首页 > 其他分享 >二叉树-快排-leetcode912

二叉树-快排-leetcode912

时间:2023-06-25 16:14:13浏览次数:163  
标签:nums int lo leetcode912 快排 hi 二叉树 pivot swap

给你一个整数数组 nums,请你将该数组升序排列。

示例 1:

输入:nums = [5,2,3,1]
输出:[1,2,3,5]
示例 2:

输入:nums = [5,1,1,2,0,0]
输出:[0,0,1,1,2,5]
提示:

1 <= nums.length <= 5 * 104
-5 * 104 <= nums[i] <= 5 * 104

思路:快排,或者叫前序二叉树,排序后端结果是一个二叉搜索树


//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
    public int[] sortArray(int[] nums) {
        sort(nums);
        return nums;
    }

    public static void sort(int[] nums) {
        // 为了避免出现耗时的极端情况,先随机打乱
        //shuffle(nums);
        // 排序整个数组(原地修改)
        sort(nums, 0, nums.length - 1);
    }

    private static void sort(int[] nums, int lo, int hi) {
        if (lo >= hi) {
            return;
        }
        // 对 nums[lo..hi] 进行切分
        // 使得 nums[lo..p-1] <= nums[p] < nums[p+1..hi]
        int p = partition(nums, lo, hi);

        sort(nums, lo, p - 1);
        sort(nums, p + 1, hi);
    }

    // 对 nums[lo..hi] 进行切分
    private static int partition(int[] nums, int lo, int hi) {
        int pivot = nums[lo];
        // 关于区间的边界控制需格外小心,稍有不慎就会出错
        // 我这里把 i, j 定义为开区间,同时定义:
        // [lo, i) <= pivot;(j, hi] > pivot
        // 之后都要正确维护这个边界区间的定义
        int i = lo + 1, j = hi;
        // 当 i > j 时结束循环,以保证区间 [lo, hi] 都被覆盖
        while (i <= j) {
            while (i < hi && nums[i] <= pivot) {
                i++;
                // 此 while 结束时恰好 nums[i] > pivot
            }
            while (j > lo && nums[j] > pivot) {
                j--;
                // 此 while 结束时恰好 nums[j] <= pivot
            }
            // 此时 [lo, i) <= pivot && (j, hi] > pivot

            if (i >= j) {
                break;
            }
            swap(nums, i, j);
        }
        // 将 pivot 放到合适的位置,即 pivot 左边元素较小,右边元素较大
        System.out.println("lo"+lo);
        System.out.println("j"+j);
        swap(nums, lo, j);
        return j;
    }

    // 洗牌算法,将输入的数组随机打乱
    private static void shuffle(int[] nums) {
        Random rand = new Random();
        int n = nums.length;
        for (int i = 0 ; i < n; i++) {
            // 生成 [i, n - 1] 的随机数
            int r = i + rand.nextInt(n - i);
            swap(nums, i, r);
        }
    }

    // 原地交换数组中的两个元素
    private static void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}
//leetcode submit region end(Prohibit modification and deletion)


标签:nums,int,lo,leetcode912,快排,hi,二叉树,pivot,swap
From: https://www.cnblogs.com/xiaoshahai/p/17503149.html

相关文章

  • 树和二叉树详细讲解
    前言在上篇文章中,向大家介绍了线性数据结构中的栈、队列和串三种数据结构,相对来说比较简单,栈的特点是先进后出(FILO),队列的特点是先进先出(FIFO)。栈包含入栈和出栈两个操作,两个操作操作的都是栈顶元素;队列包含入队和出队两个操作,元素从队尾进入队列,需要时从队头取出元素。全......
  • 二叉树
    #include<stdio.h>#include<stdlib.h>#include<malloc.h>typedefstructBTNode{ chardata; structBTNode*lchild; structBTNode*rchild;}*BiTree;voidcreateBiTree(BiTree*t){//此处补充代码,输入二叉树的先序遍历序列建立二叉树 chars;......
  • [leetcode]114. 二叉树展开为链表
    总结:怎样写递归函数?关键是把递归函数的功能定义清楚,并在递归函数体中使用自身来做事,此时不要关注递归函数执行的细节。也就是写高层级代码的时候不要关注低层级的事情,这就叫抽象。关注也没有用,想不清楚的。 1classSolution{2publicvoidflatten(TreeNoderoot){......
  • 代码随想录算法训练营第十六天| 找树左下角的值 路径总和 从中序与后序遍历序列
    找树左下角的值1,层序遍历,较为简单:1intfindBottomLeftValue_simple(TreeNode*root){2intresult=0;3if(!root)returnresult;4queue<TreeNode*>selected;5selected.push(root);67while(!selected.empty())8{9......
  • 代码随想录算法训练营第十五天| 110.平衡二叉树 (优先掌握递归) 257. 二叉树的所有路径
     110.平衡二叉树(优先掌握递归)难点:要求每个节点的左右字数的高度相减<=1,因此,需要对每个节点都进行检查,难就难在怎么获得任意节点的高度其中递归是最简单的: 1intisB_cursor(TreeNode*node,bool&isBalance)2{3if(isBalance==false)return0;4if......
  • 代码随想录算法训练营第十四天| 104.二叉树的最大深度 (优先掌握递归) 111.二叉树的最小
    104.二叉树的最大深度(优先掌握递归)迭代法,上一篇已经讲过,只需要对每一层+1,这里重要些递归法递归法注意:如果当前节点为NULL,返回0,不是NULL,那么就是1+max(right,left)代码:1voidmaxD_cursor(TreeNode*node,int&result)2{3if(!node)return;45result......
  • 交换二叉树
    #include<stdio.h>#include<stdlib.h>#include<malloc.h>typedefstructBTNode{ chardata; structBTNode*lchild; structBTNode*rchild;}*BiTree;voidcreateBiTree(BiTree*t){//此处补充代码,输入二叉树的先序遍历序列建立二叉树 chars;......
  • 20230314 3.2. 二叉树
    二叉树的定义二叉树T:一个有穷的结点集合。这个集合可以为空若不为空,则它是由根结点和称为其左子树TL和右子树TR的两个不相交的二叉树组成。二叉树具体五种基本形态:空二叉树;只有根结点的二叉树;只有根结点和左子树TL的二叉树;只有根结点和右子树TR的二叉树;具有根结点、左......
  • 代码随想录算法训练营第十三天| 层序遍历 226.翻转二叉树 (优先掌握递归) 101. 对
    层序遍历注意:1,使用队列的形式,依次入队,同时对队列进行计数2,知道数目消失,才进行下一个队列代码:1vector<vector<int>>levelOrder(TreeNode*root)2{3vector<vector<int>>result;4if(root==NULL)returnresult;5queue<TreeNode*>selected;6......
  • 快排
    代码#include<iostream>usingnamespacestd;constintN=1e5+10;ints[N];voidquickSort(intl,intr){if(l>=r)return;intmid=s[(l+r)>>1];inti=l-1,j=r+1;while(i<j){do++i;whil......