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);

posted @ 2022-02-25 15:09  一颗青菜  阅读(9)  评论(0)    收藏  举报