3月打卡活动第31天 LeetCode第912题:排序数组(中等)

3月打卡活动第31天 LeetCode第912题:排序数组(中等)

  • 题目:给定一个整数数组 nums,将该数组升序排列。
  • 解题思路1:借着这道题复习一下排序方法吧。冒泡排序,依次从大到小确定。
class Solution {
    public int[] sortArray(int[] nums) {
        int len = nums.length;
        //冒泡排序
        for(int i=0;i<len;i++){
            for(int j=0;j<len-1-i;j++){
                if(nums[j]>nums[j+1]){
                    int temp = nums[j+1];
                    nums[j+1] = nums[j];
                    nums[j] = temp;
                }
            }
        }
        return nums;
    }
}

在这里插入图片描述

  • 解题思路2:选择排序看来还是比冒泡要好呀,从小到大确定。
class Solution {
    public int[] sortArray(int[] nums) {
        int len = nums.length;
        //选择排序
        for(int i=0;i<len;i++){
            int index = i;
            for(int j=i+1;j<len;j++){
                if(nums[j]<nums[index]){
                    index = j;
                }
            }
            int temp = nums[index];
            nums[index] = nums[i];
            nums[i] = temp;
        }
        return nums;
    }
}

在这里插入图片描述

  • 解题思路3:插入排序,保持当前元素左侧始终是排序后的数组,依次确定当前数的位置。
class Solution {
    public int[] sortArray(int[] nums) {
        int len = nums.length;
        //插入排序法
        for(int i=1;i<len;i++){   
            for(int j=i;j>0;j--){   
                if (nums[j]<nums[j-1]){   
                    int temp=nums[j-1];  
                    nums[j-1]=nums[j];  
                    nums[j]=temp;          
                }else break;   
            }  
        }  
        return nums;
    }
}

在这里插入图片描述

  • 题解做法1:非比较排序,思路真是很新颖
class Solution {
    public int[] sortArray(int[] nums) {
        int max = -50001, min = 50001;
        for (int num: nums) {
            max = Math.max(num, max);
            min = Math.min(num, min);
        }


        int[] counter = new int[max - min + 1];
        for (int num: nums) {
            counter[num - min]++;
        }

        int idx = 0;
        for (int num = min; num <= max; num++) {
            int cnt = counter[num - min];
            while (cnt-- > 0) {
                nums[idx++] = num;
            }
        }
        return nums;
    }
}

作者:sweetiee
链接:https://leetcode-cn.com/problems/sort-an-array/solution/dang-wo-tan-pai-xu-shi-wo-zai-tan-xie-shi-yao-by-s/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

在这里插入图片描述

  • 题解做法2:归并排序。归并排序是典型的使用分治思想(divide-and-conquer)解决问题的案例。在排序的过程中,把原来的数组变成左右两个数组,然后分别进行排序,当左右的子数组排序完毕之后,再合并这两个子数组形成一个新的排序数组。整个过程递归进行,当只剩下一个元素或者没有元素的时候就直接返回。
private void mergeSort(int[] nums, int left, int right) {  // 需要左右边界确定排序范围
    if (left >= right) return;
    int mid = (left+right) / 2;

    mergeSort(nums, left, mid);                           // 先对左右子数组进行排序
    mergeSort(nums, mid+1, right);

    int[] temp = new int[right-left+1];                   // 临时数组存放合并结果
    int i=left,j=mid+1;
    int cur = 0;
    while (i<=mid&&j<=right) {                            // 开始合并数组
        if (nums[i]<=nums[j]) temp[cur] = nums[i++];
        else temp[cur] = nums[j++];
        cur++;
    }
    while (i<=mid) temp[cur++] = nums[i++];
    while (j<=right) temp[cur++] = nums[j++];

    for (int k = 0; k < temp.length; k++) {             // 合并数组完成,拷贝到原来的数组中
        nums[left+k] = temp[k];
    }
}

作者:bryansun2020
链接:https://leetcode-cn.com/problems/sort-an-array/solution/shi-er-chong-pai-xu-suan-fa-bao-ni-man-yi-dai-gift/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 题解做法3:快速排序,其核心的思路是取第一个元素(或者最后一个元素)作为分界点,把整个数组分成左右两侧,左边的元素小于或者等于分界点元素,而右边的元素大于分界点元素,然后把分界点移到中间位置,对左右子数组分别进行递归,最后就能得到一个排序完成的数组。当子数组只有一个或者没有元素的时候就结束这个递归过程。
private void quickSort(int[] nums, int left, int right) {
    if (left >= right) return;
    int lo = left+1;               // 小于分界点元素的最右侧的指针
    int hi = right;                // 大于分界点元素的最左侧的指针
    while (lo<=hi) {
        if (nums[lo]>nums[left]) { // 交换元素确保左侧指针指向元素小于分界点元素
            swap(nums, lo, hi);
            hi--;
        } else {
            lo++;
        }
    }
    lo--;                          // 回到小于分界点元素数组的最右侧
    swap(nums, left, lo);          // 将分界点元素移到左侧数组最右侧
    quickSort2(nums, left, lo-1);
    quickSort2(nums, lo+1, right);
}

作者:bryansun2020
链接:https://leetcode-cn.com/problems/sort-an-array/solution/shi-er-chong-pai-xu-suan-fa-bao-ni-man-yi-dai-gift/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 题解做法4:堆排序
private void heapSort(int[] nums) {
    heapify(nums);                                 // 新建一个最大堆
    for (int i = nums.length - 1; i >= 1; i--) {
        swap(nums, 0, i);                       // 弹出最大堆的堆顶放在最后
        rebuildHeap(nums, 0,i-1);          // 重建最大堆
    }
}

private void heapify(int[] nums) {
    for (int i = 1; i < nums.length; i++) {
        int par = (i-1)>>1;                       // 找到父节点
        int child = i;                            // 定义子节点
        while (child>0&&nums[par]<nums[child]) {  // 从子节点到根节点构建最大堆
            swap(nums, par, child);
            child = par;
            par = (par-1) >> 1;
        }
    }
}

private void rebuildHeap(int[] nums, int par, int last) {
    int left = 2*par+1;                           // 左子节点
    int right = 2*par+2;                          // 右子节点
    int maxIndex = left;

    if (right<=last && nums[right]>nums[left]) {  // 找到最大子节点
        maxIndex = right;
    }

    if (left<=last && nums[par] < nums[maxIndex]) {// 和最大子节点比较
        swap(nums, par, maxIndex);                 // 互换到最大子节点
        rebuildHeap(nums, maxIndex, last);         // 重建最大子节点代表的子树
    }
}

作者:bryansun2020
链接:https://leetcode-cn.com/problems/sort-an-array/solution/shi-er-chong-pai-xu-suan-fa-bao-ni-man-yi-dai-gift/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 题解做法5:二叉搜索树排序
private int[] bstSort(int[] nums) {
    TreeNode root = new TreeNode(nums[0]);   // 构建根节点
    for (int i = 1; i < nums.length; i++) {  // 将所有的元素插入到二叉搜索树中
        buildTree(root, nums[i]);
    }
    inorderTraversal(root, nums, new int[1]);// 中序遍历获取二叉树中的所有节点
    return nums;
}

private void inorderTraversal(TreeNode node, int[] nums, int[] pos) {
    if (node == null) return;
    inorderTraversal(node.left, nums, pos);
    nums[pos[0]++] = node.val;
    inorderTraversal(node.right, nums, pos);
}

private void buildTree(TreeNode node, int num) {
    if (node == null) return;
    if (num >= node.val) {                   // 插入到右子树中
        if (node.right == null) {
            node.right = new TreeNode(num);
        } else {
            buildTree(node.right, num);
        }
    } else {                                 // 插入到左子树中
        if (node.left == null) {
            node.left = new TreeNode(num);
        } else {
            buildTree(node.left, num);
        }
    }
}

static class TreeNode {   // 树节点的数据结构
    int val;
    TreeNode left;
    TreeNode right;

    public TreeNode(int val) {
        this.val = val;
    }
}

作者:bryansun2020
链接:https://leetcode-cn.com/problems/sort-an-array/solution/shi-er-chong-pai-xu-suan-fa-bao-ni-man-yi-dai-gift/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值