leecode更新
This commit is contained in:
parent
03bc9f9c6b
commit
e9ab1f5244
|
|
@ -0,0 +1,51 @@
|
|||
package com.markilue.leecode.hot100.second;
|
||||
|
||||
import com.markilue.leecode.listnode.ListNode;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.hot100.second
|
||||
*@Author: markilue
|
||||
*@CreateTime: 2023-04-25 10:12
|
||||
*@Description:
|
||||
* TODO 力扣23 合并K个升序链表:
|
||||
* 给你一个链表数组,每个链表都已经按升序排列。
|
||||
* 请你将所有链表合并到一个升序链表中,返回合并后的链表。
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class T17_23_MergeKLists {
|
||||
|
||||
|
||||
public ListNode mergeKLists(ListNode[] lists) {
|
||||
if (lists.length == 0) return null;
|
||||
return merge(lists, 0, lists.length - 1);
|
||||
}
|
||||
|
||||
public ListNode merge(ListNode[] lists, int start, int end) {
|
||||
if (start >= end) return lists[start];
|
||||
|
||||
int mid = start + ((end - start) >> 1);
|
||||
ListNode list1 = merge(lists, start, mid);
|
||||
ListNode list2 = merge(lists, mid + 1, end);
|
||||
return mergeTwoList(list1, list2);
|
||||
}
|
||||
|
||||
private ListNode mergeTwoList(ListNode list1, ListNode list2) {
|
||||
if (list1 == null) {
|
||||
return list2;
|
||||
} else if (list2 == null) {
|
||||
return list1;
|
||||
}
|
||||
ListNode root = new ListNode(0);
|
||||
if (list1.val < list2.val) {
|
||||
root.val = list1.val;
|
||||
root.next = mergeTwoList(list1.next, list2);
|
||||
} else {
|
||||
root.val = list2.val;
|
||||
root.next = mergeTwoList(list1, list2.next);
|
||||
}
|
||||
|
||||
return root;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package com.markilue.leecode.hot100.second;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.hot100.second
|
||||
*@Author: markilue
|
||||
*@CreateTime: 2023-04-25 10:25
|
||||
*@Description:
|
||||
* TODO 力扣31 下一个排列:
|
||||
* 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。
|
||||
* 例如,arr = [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。
|
||||
* 整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组的 下一个排列 就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)。
|
||||
* 例如,arr = [1,2,3] 的下一个排列是 [1,3,2] 。
|
||||
* 类似地,arr = [2,3,1] 的下一个排列是 [3,1,2] 。
|
||||
* 而 arr = [3,2,1] 的下一个排列是 [1,2,3] ,因为 [3,2,1] 不存在一个字典序更大的排列。
|
||||
* 给你一个整数数组 nums ,找出 nums 的下一个排列。
|
||||
* 必须 原地 修改,只允许使用额外常数空间。
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class T18_31_NextPermutation {
|
||||
|
||||
/**
|
||||
* 下一个排列:从后往前找第一个不是递增的,然后交换,然后将后面的全部反转
|
||||
* @param nums
|
||||
*/
|
||||
public void nextPermutation(int[] nums) {
|
||||
|
||||
int index = nums.length - 2;
|
||||
|
||||
while (index >= 0 && nums[index] >= nums[index + 1]) {
|
||||
index--;
|
||||
}
|
||||
|
||||
if (index >= 0) {
|
||||
//交换,第一个比他大的数
|
||||
int j = nums.length - 1;
|
||||
while (j >= 0 && nums[index] >= nums[j]) {//注意这些地方都是要等于
|
||||
j--;
|
||||
}
|
||||
swap(nums, index, j);
|
||||
}
|
||||
|
||||
reverse(nums, index + 1, nums.length-1);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void swap(int[] nums, int left, int right) {
|
||||
int temp = nums[left];
|
||||
nums[left] = nums[right];
|
||||
nums[right] = temp;
|
||||
}
|
||||
|
||||
public void reverse(int[] nums, int start, int end) {
|
||||
|
||||
while (start < end) {
|
||||
swap(nums, start, end);
|
||||
start++;
|
||||
end--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@ package com.markilue.leecode.hot100.second;
|
|||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
|
|
@ -17,7 +19,7 @@ import java.util.LinkedList;
|
|||
public class T19_32_LongestValidParentheses {
|
||||
|
||||
@Test
|
||||
public void test(){
|
||||
public void test() {
|
||||
String s = ")()())";
|
||||
System.out.println(longestValidParentheses(s));
|
||||
}
|
||||
|
|
@ -43,8 +45,8 @@ public class T19_32_LongestValidParentheses {
|
|||
stack.pop();
|
||||
if (stack.isEmpty()) {
|
||||
stack.push(i);
|
||||
}else {
|
||||
length = Math.max(i-stack.peek() , length);
|
||||
} else {
|
||||
length = Math.max(i - stack.peek(), length);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -53,4 +55,31 @@ public class T19_32_LongestValidParentheses {
|
|||
return length;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public int longestValidParentheses1(String s) {
|
||||
|
||||
Deque<Integer> stack = new ArrayDeque<>();//入栈的时候对应的index
|
||||
stack.push(-1);
|
||||
int result = 0;
|
||||
|
||||
char[] chars = s.toCharArray();
|
||||
for (int i = 0; i < chars.length; i++) {
|
||||
if (chars[i] == '(') {
|
||||
stack.push(i);
|
||||
} else {
|
||||
stack.pop();
|
||||
if (stack.isEmpty()) {
|
||||
stack.push(i);
|
||||
}else {
|
||||
result = Math.max(result, i - stack.peek());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,111 @@
|
|||
package com.markilue.leecode.hot100.second;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.hot100.second
|
||||
*@Author: markilue
|
||||
*@CreateTime: 2023-04-25 10:49
|
||||
*@Description:
|
||||
* TODO 力扣33 搜索旋转排序数组:
|
||||
* 整数数组 nums 按升序排列,数组中的值 互不相同 。
|
||||
* 在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。
|
||||
* 给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。
|
||||
* 你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class T20_33_Search {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
int[] nums = {1, 3};
|
||||
System.out.println(search(nums, 3));
|
||||
}
|
||||
|
||||
|
||||
//递归法
|
||||
public int search(int[] nums, int target) {
|
||||
|
||||
return searchTwo(nums, 0, nums.length - 1, target);
|
||||
}
|
||||
|
||||
public int searchTwo(int[] nums, int start, int end, int target) {
|
||||
if (start >= end) {
|
||||
if (nums[start] == target) {
|
||||
return start;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int mid = start + ((end - start) >> 1);
|
||||
|
||||
if (nums[mid] >= nums[0]) {
|
||||
if (nums[mid] < target) {
|
||||
return searchTwo(nums, mid + 1, end, target);
|
||||
} else if (nums[mid] > target) {
|
||||
if (target >= nums[0]) {
|
||||
return searchTwo(nums, start, mid - 1, target);
|
||||
} else {
|
||||
return searchTwo(nums, mid + 1, end, target);
|
||||
}
|
||||
} else {
|
||||
return mid;
|
||||
}
|
||||
} else {
|
||||
if (nums[mid] < target) {
|
||||
if (nums[0] > target) {
|
||||
return searchTwo(nums, mid + 1, end, target);
|
||||
} else {
|
||||
return searchTwo(nums, start, mid - 1, target);
|
||||
}
|
||||
} else if (nums[mid] > target) {
|
||||
return searchTwo(nums, start, mid - 1, target);
|
||||
} else {
|
||||
return mid;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
//优雅while的search
|
||||
public int search1(int[] nums, int target) {
|
||||
int n = nums.length;
|
||||
if (n == 0) {
|
||||
return -1;
|
||||
}
|
||||
if (n == 1) {
|
||||
return nums[0] == target ? 0 : -1;
|
||||
}
|
||||
|
||||
int left = 0;
|
||||
int right = n - 1;
|
||||
while (left <= right) {
|
||||
int mid = left + ((right - left) >> 1);
|
||||
if (nums[mid] == target) {
|
||||
return mid;
|
||||
}
|
||||
|
||||
if (nums[0] <= nums[mid]) {//TODO 主要这里要等于,就是将不翻转的情况也包含进行
|
||||
if (nums[0] <= target && nums[mid] > target) {
|
||||
right = mid - 1;
|
||||
} else {
|
||||
left = mid + 1;
|
||||
}
|
||||
} else {
|
||||
if (nums[mid] < target && target <= nums[n - 1]) {
|
||||
left = mid + 1;
|
||||
} else {
|
||||
right = mid - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package com.markilue.leecode.hot100.second;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.hot100.second
|
||||
*@Author: markilue
|
||||
*@CreateTime: 2023-04-25 11:24
|
||||
*@Description:
|
||||
* TODO 力扣34 在排序数组中查找元素的第一个和最后一个位置:
|
||||
* 给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。
|
||||
* 如果数组中不存在目标值 target,返回 [-1, -1]。
|
||||
* 你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class T21_34_SearchRange {
|
||||
|
||||
public int[] searchRange(int[] nums, int target) {
|
||||
int n = nums.length;
|
||||
if (n == 0) {
|
||||
return new int[]{-1, -1};
|
||||
}
|
||||
if (n == 1) {
|
||||
return nums[0] == target ? new int[]{0, 0} : new int[]{-1, -1};
|
||||
}
|
||||
|
||||
int left = 0;
|
||||
int right = n - 1;
|
||||
|
||||
while (left <= right) {
|
||||
int mid = left + ((right - left) >> 1);
|
||||
if (nums[mid] < target) {
|
||||
left = mid + 1;
|
||||
} else if (nums[mid] > target) {
|
||||
right = mid - 1;
|
||||
} else {
|
||||
int left1 = mid;
|
||||
int right1 = mid;
|
||||
while (left1 > 0 && nums[left1-1] == nums[mid]) {
|
||||
left1--;
|
||||
}
|
||||
while (right1 < nums.length-1 && nums[right1+1] == nums[mid]) {
|
||||
right1++;
|
||||
}
|
||||
return new int[]{left1, right1};
|
||||
}
|
||||
}
|
||||
|
||||
return new int[]{-1, -1};
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package com.markilue.leecode.hot100.second;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.hot100.second
|
||||
*@Author: markilue
|
||||
*@CreateTime: 2023-04-25 11:55
|
||||
*@Description:
|
||||
* TODO 力扣39 组和总和:
|
||||
* 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
|
||||
* candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
|
||||
* 对于给定的输入,保证和为 target 的不同组合数少于 150 个。
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class T22_39_CombinationSum {
|
||||
@Test
|
||||
public void test() {
|
||||
int[] nums = {2, 3, 6, 7};
|
||||
System.out.println(combinationSum(nums, 7));
|
||||
}
|
||||
|
||||
List<Integer> cur = new ArrayList<>();
|
||||
List<List<Integer>> result = new ArrayList<>();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param candidates
|
||||
* @param target
|
||||
* @return
|
||||
*/
|
||||
public List<List<Integer>> combinationSum(int[] candidates, int target) {
|
||||
Arrays.sort(candidates);
|
||||
backtracking(candidates, target, 0);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
public void backtracking(int[] candidates, int target, int startIndex) {
|
||||
|
||||
if (target == 0) {
|
||||
result.add(new ArrayList<>(cur));
|
||||
return;
|
||||
}
|
||||
if (startIndex >= candidates.length) return;
|
||||
|
||||
for (int i = 0; target - candidates[startIndex] * i >= 0; i++) {
|
||||
for (int j = 0; j < i; j++) {
|
||||
cur.add(candidates[startIndex]);
|
||||
}
|
||||
backtracking(candidates, target - i * candidates[startIndex], startIndex + 1);
|
||||
for (int j = 0; j < i; j++) {
|
||||
cur.remove(cur.size()-1);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
package com.markilue.leecode.interview.meituan;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.interview.meituan
|
||||
*@Author: markilue
|
||||
*@CreateTime: 2023-04-22 14:55
|
||||
*@Description: TODO
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class test1 {
|
||||
|
||||
|
||||
public int maxScore(int[] price, int k) {
|
||||
int n = price.length;
|
||||
Arrays.sort(price); // 将宝石按价格从小到大排序
|
||||
|
||||
// 计算最小分数
|
||||
int minScore = 0;
|
||||
for (int i = 0; i < k; i++) {
|
||||
minScore += price[i];
|
||||
}
|
||||
|
||||
// 计算最大分数
|
||||
int maxScore = minScore + price[n - 1] * k; // 最大分数的范围在[minScore, maxScore]之间
|
||||
while (minScore < maxScore) {
|
||||
int midScore = minScore + (maxScore - minScore) / 2;
|
||||
if (check(price, k, midScore)) { // 如果当前最大分数可行,则继续往上调整
|
||||
minScore = midScore + 1;
|
||||
} else { // 否则往下调整
|
||||
maxScore = midScore;
|
||||
}
|
||||
}
|
||||
return maxScore - minScore;
|
||||
}
|
||||
|
||||
// 判断当前最大分数是否可行
|
||||
private boolean check(int[] price, int k, int maxScore) {
|
||||
int n = price.length;
|
||||
int[] bag = new int[n]; // bag[i]表示第i个宝石所在的行囊编号,初始值为-1表示没有被放入行囊中
|
||||
int[] capacity = new int[k]; // capacity[i]表示第i个行囊还能容纳多少宝石,初始值为k
|
||||
Arrays.fill(bag, -1); // 初始化bag数组
|
||||
Arrays.fill(capacity, k); // 初始化capacity数组
|
||||
|
||||
int i = n - 1; // 从价格最高的宝石开始往下放
|
||||
while (i >= 0) {
|
||||
int j = findNext(bag, price[i]); // 找到下一个可以放入宝石的行囊编号
|
||||
if (j == -1) { // 如果没有可用的行囊,则当前最大分数不可行
|
||||
return false;
|
||||
}
|
||||
int l = findLeft(bag, j, price[i]); // 找到行囊j中宝石的最左边位置
|
||||
int r = findRight(bag, j, price[i]); // 找到行囊j中宝石的最右边位置
|
||||
if (r - l + 1 <= capacity[j]) { // 如果行囊j可以容纳当前宝石
|
||||
for (int p = l; p <= r; p++) { // 将[l,r]之间的宝石全部放入行囊j中
|
||||
bag[p] = j;
|
||||
}
|
||||
capacity[j] -= r - l + 1; // 更新行囊j的容量
|
||||
i--; // 处理下一个宝石
|
||||
} else { // 如果行囊j不能容纳当前宝石,则需要找下一个行囊
|
||||
i++; // 回溯到上一个宝石
|
||||
j = findPrev(bag, j); // 找到上一个可用的行囊编号
|
||||
if (j == -1) { // 如果没有可用的行囊,则当前最大分数不可行
|
||||
return false;
|
||||
}
|
||||
l = findLeft(bag, j, price[i]); // 找到行囊j中宝石的最左边位置
|
||||
r = findRight(bag, j, price[i]); // 找到行囊j中宝石的最右边位置
|
||||
for (int p = l; p <= r; p++) { // 将[l,r]之间的宝石全部放入行囊j中
|
||||
bag[p] = j;
|
||||
}
|
||||
capacity[j] -= r - l + 1; // 更新行囊j的容量
|
||||
i--; // 处理下一个宝石
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 找到下一个可以放入宝石的行囊编号
|
||||
private int findNext(int[] bag, int p) {
|
||||
int n = bag.length;
|
||||
int i = 0;
|
||||
while (i < n && (bag[i] != -1 || (i > 0 && bag[i - 1] == -1 && p - i < i - 1))) {
|
||||
i++;
|
||||
}
|
||||
return (i == n ? -1 : i);
|
||||
}
|
||||
|
||||
// 找到上一个可用的行囊编号
|
||||
private int findPrev(int[] bag, int j) {
|
||||
int i = j - 1;
|
||||
while (i >= 0 && bag[i] == -1) {
|
||||
i--;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
// 找到行囊j中宝石的最左边位置
|
||||
private int findLeft(int[] bag, int j, int p) {
|
||||
int i = j;
|
||||
while (i >= 0 && bag[i] == j && p - i <= j - i) {
|
||||
i--;
|
||||
}
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
// 找到行囊j中宝石的最右边位置
|
||||
private int findRight(int[] bag, int j, int p) {
|
||||
int n = bag.length;
|
||||
int i = j;
|
||||
while (i < n && bag[i] == j && i - p <= j - i) {
|
||||
i++;
|
||||
}
|
||||
return i - 1;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
int[] nums = {2, 3,5,4};
|
||||
int n = 3;
|
||||
System.out.println(maxScore1(nums, n));
|
||||
}
|
||||
|
||||
|
||||
int max = Integer.MIN_VALUE;
|
||||
int min = Integer.MAX_VALUE;
|
||||
|
||||
public int maxScore1(int[] price, int k) {
|
||||
|
||||
backtracking(price, 0, k-1, 0);
|
||||
return max - min;
|
||||
|
||||
}
|
||||
|
||||
public void backtracking(int[] price, int startIndex, int k, int cur) {
|
||||
if (k == 0) {
|
||||
cur += price[price.length - 1] + price[startIndex];
|
||||
if (max < cur) max = cur;
|
||||
if (min > cur) min = cur;
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = startIndex; i < price.length-k; i++) {
|
||||
cur += price[startIndex] + price[i];
|
||||
backtracking(price, i + 1, k - 1, cur);
|
||||
cur -= price[startIndex] + price[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static int shortestPath(int[][] maze, int startRow, int startCol, int endRow, int endCol) {
|
||||
int[][] directions = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
|
||||
Queue<int[]> queue = new LinkedList<>();
|
||||
Set<String> visited = new HashSet<>();
|
||||
|
||||
queue.offer(new int[]{startRow, startCol, 0});
|
||||
visited.add(startRow + "," + startCol);
|
||||
|
||||
while (!queue.isEmpty()) {
|
||||
int[] pos = queue.poll();
|
||||
int row = pos[0], col = pos[1], steps = pos[2];
|
||||
|
||||
if (row == endRow && col == endCol) {
|
||||
return steps;
|
||||
}
|
||||
|
||||
for (int[] d : directions) {
|
||||
int newRow = row + d[0], newCol = col + d[1];
|
||||
|
||||
if (newRow >= 0 && newRow < maze.length && newCol >= 0 && newCol < maze[0].length
|
||||
&& !visited.contains(newRow + "," + newCol) && maze[newRow][newCol] == 1) {
|
||||
queue.offer(new int[]{newRow, newCol, steps + 1});
|
||||
visited.add(newRow + "," + newCol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[][] maze = {{1, 1, 1, 0, 1},
|
||||
{1, 0, 1, 1, 1},
|
||||
{1, 1, 1, 0, 1},
|
||||
{0, 0, 1, 1, 1},
|
||||
{1, 0, 0, 0, 1}};
|
||||
int startRow = 0, startCol = 0, endRow = 4, endCol = 4;
|
||||
System.out.println(shortestPath(maze, startRow, startCol, endRow, endCol)); // 输出4
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
package com.markilue.leecode.test;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.test
|
||||
*@Author: markilue
|
||||
*@CreateTime: 2023-04-23 13:39
|
||||
*@Description: TODO
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class HeapSort {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
int[] nums = {8, 6, 9, 1, 4, 7, 2, 3, 5};
|
||||
heapSort(nums);
|
||||
System.out.println(Arrays.toString(nums));
|
||||
}
|
||||
|
||||
|
||||
public void heapSort(int[] nums) {
|
||||
int n = nums.length;
|
||||
//从最后一个非叶子节点开始堆化
|
||||
for (int i = n / 2 - 1; i >= 0; i--) {
|
||||
adjustHeap(nums, i, n);
|
||||
}
|
||||
int temp;
|
||||
//挨个取出重新堆化
|
||||
for (int i = n - 1; i > 0; i--) {
|
||||
temp = nums[i];
|
||||
nums[i] = nums[0];
|
||||
nums[0] = temp;
|
||||
adjustHeap(nums, 0, i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param nums
|
||||
* @param i 开始调整的位置
|
||||
* @param length 长度
|
||||
*/
|
||||
public void adjustHeap(int[] nums, int i, int length) {
|
||||
|
||||
int root = nums[i];
|
||||
|
||||
for (int j = 2 * i + 1; j < length; j = 2 * j + 1) {
|
||||
if (j + 1 < length && nums[j] < nums[j + 1]) {
|
||||
j++;
|
||||
}
|
||||
|
||||
if (root < nums[j]) {
|
||||
nums[i] = nums[j];
|
||||
i = j;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nums[i] = root;//放到合适位置
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue