912. 排序数组

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sort-an-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
排序问题,分治思想:核心是回溯;快速排序:核心是DFS
分治思想:
public int[] sortArray(int[] nums) {
divide(nums,0,nums.length-1);
return nums;
}
public void divide(int[] nums, int l,int r) {
if(l==r) {
return;
}
int mid = l+(r-l)/2;
divide(nums,l,mid);
divide(nums,mid+1,r);
// 先给拆分到一个数据,之后再合并,合并之后的是有顺序的。
merge(nums,l,mid,r);
}
private void merge(int[] nums, int l, int mid, int r) {
int[] ret = new int[r-l+1];
int n=0;
int i=l;
int j=mid+1;
// 判断,小的添加。
while(i<=mid && j<=r) {
if(nums[i] < nums[j]) {
ret[n++] = nums[i];
i++;
} else {
ret[n++] = nums[j];
j++;
}
}
while(i<=mid) {
ret[n++] = nums[i];
i++;
}
while(j<=r) {
ret[n++] = nums[j];
j++;
}
// ret排序好后,覆盖nums数组中的值
for(i=l;i<=r;i++) {
nums[i] = ret[i-l];
}
}
快速排序:注意的问题:为什么返回j位置。
public int[] sortArray(int[] nums) {
// divide(nums,0,nums.length-1);
// return nums;
dfs(nums,0,nums.length-1);
return nums;
}
public void dfs(int[] nums, int l, int r) {
if(l >= r) {
return;
}
// 通过返回来的位置,区分两个
int j = search(nums,l,r);
dfs(nums,l,j-1);
dfs(nums,j+1,r);
}
public int search(int[] nums, int l, int r) {
int cur = nums[l];
// 这里使用的是开区间(l,r+1)
int i = l;
int j = r+1;
while(i<j) {
while(++i < r && nums[i] < cur){}
while(--j > l && nums[j] > cur){}
// 由于和第一个值比较,所以j最小就是l
if(j<=i) {
break;
}
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
int tmp = nums[l];
nums[l] = nums[j];
nums[j] = tmp;
// 为什么返回的值是j,因为在交汇后,j的位置是最后一个小于当前值的。自然就是放当前值的位置。
return j;
}
为什么分治的判断条件是l==r 而快排是l>=r?原因在于传参:
分治是(l,mid),(mid+1,r)是连续的,而快排是:(l,j-1),(j+1,r);就会出现l>=r;举个例子:[1,2]排序,返回的j=0;进入到下一层就是(0,-1),(1,1);
浙公网安备 33010602011771号