• LeetCode高频题75. 颜色分类:荷兰国旗问题


    LeetCode高频题75. 颜色分类:荷兰国旗问题

    提示:本题是系列LeetCode的150道高频题,你未来遇到的互联网大厂的笔试和面试考题,基本都是从这上面改编而来的题目
    互联网大厂们在公司养了一大批ACM竞赛的大佬们,吃完饭就是设计考题,然后去考应聘人员,你要做的就是学基础树结构与算法,然后打通任督二脉,以应对波云诡谲的大厂笔试面试题!
    你要是不扎实学习数据结构与算法,好好动手手撕代码,锻炼解题能力,你可能会在笔试面试过程中,连题目都看不懂!比如华为,字节啥的,足够让你读不懂题
    在这里插入图片描述
    基础知识:
    【2】Topk问题:bfprt算法: 无序数组arr,找出如果arr有序的话,第k小那个数是多少
    【1】10大排序算法之五:快排算法,快速排序【不稳定】,复杂度中,系统常用快速排序


    题目

    给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,
    原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

    我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

    必须在不使用库的sort函数的情况下解决这个问题。

    来源:力扣(LeetCode)
    链接:https://leetcode.cn/problems/sort-colors
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


    一、审题

    示例 1:

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

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

    提示:

    n == nums.length
    1 <= n <= 300
    nums[i] 为 0、1 或 2


    这就是荷兰国旗问题,我说过多次了

    【1】10大排序算法之五:快排算法,快速排序【不稳定】,复杂度中,系统常用快速排序
    上文就是我讲荷兰国旗问题,讲得非常透彻的地方了

    荷兰国旗问题,正常情况下,要返回等于pivot区的左边界和右边界的

    用在哪里呢?topK问题
    这个topK问题经常推荐系统要用的,所以面试的时候互联网大厂经常考
    【2】Topk问题:bfprt算法: 无序数组arr,找出如果arr有序的话,第k小那个数是多少

    今天我再整一遍,简单说

    本质就是整一个pivot=1,
    然后将小于pivot的,统统挪到左边小于pivot的小于区
    将所有等于pivot的放在中间等于区
    然后将大于pivot的放在右边大于区

    完成0000 1111 2222的工作

    代码中设定2个区的边界less和more
    初始化less=-1,more=N,代表小于区没有纳入任何元素,大于区也没有纳入任何元素

    在这里插入图片描述
    然后i=0开始从左往右遍历,对比arri=pivot=1,相等i++
    如果arri 如果arri>pivot,则将–more位置和i位置交换,然后i不动

    循环轮番操作,知道i=more,相撞停止,说明此时已经排好了

    比如:
    在这里插入图片描述
    显然arri=2>pivot=1,所以则将–more=5位置和i=0位置交换,然后i=0不动
    为毛i不能动呢???
    谁知道你刚刚交换过来的数,是大,等,还是小于pivot呢??
    还需比较i和pivot的,故,i不动
    在这里插入图片描述
    继续对比
    arri=0 然后i++=1
    在这里插入图片描述
    继续对比
    arri=0 然后i++=2
    在这里插入图片描述
    继续对比
    arri=2>pivot=1,则将–more=4位置和i=2位置交换,然后i不动
    在这里插入图片描述
    继续对比
    对比arri=pivot=1,相等i++=3
    在这里插入图片描述
    继续对比
    对比arri=pivot=1,相等i++=4
    在这里插入图片描述
    经过刚刚的循环轮番操作,直到i=more=4,相撞停止,说明此时已经排好了
    你瞅瞅是不是arr已经变成001122了
    已经就是题目要的结果了

    懂??

    荷兰国旗的颜色就是红色0,白色1、蓝色2
    这时,可不就是一张完美的荷兰国旗了吗

    在这里插入图片描述

    okay,手撕代码,非常简单

    把arr的L–R排好

    中途遇到的交换函数,巨简单了

            public static void swap(int[] arr, int i,  int j){
                int tmp = arr[i];
                arr[i] = arr[j];
                arr[j] = tmp;
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    荷兰国旗问题的分函数——这个函数,正常情况下,要返回等于pivot区的左边界和右边界的

    用在哪里呢?topK问题
    这个topK问题经常推荐系统要用的,所以面试的时候互联网大厂经常考

    所以你可要熟透了

            public static void partition(int[] arr, int L, int R, int pivot){
                //然后i=0开始从左往右遍历,对比arri=pivot=1,相等i++
                //如果arri
                //如果arri>pivot,则将--more位置和i位置交换,然后i不动
                int less = L - 1;
                int more = R + 1;
                int i = 0;
                while (i != more){//i到了大区边界停止
                    if (arr[i] == pivot) i++;
                    else if (arr[i] < pivot) swap(arr, ++less, i++);
                    else swap(arr, --more, i);//i不动哦
                }
                //本题就结束了,正常情况下,我们求topK问题的话,还需要这个返回等于区的左边界和右边界
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    本题的解题代码

            //复习荷兰国旗问题,不用交换R位置了,直接干
    
            public void sortColorsReview(int[] nums) {
                if (nums == null || nums.length == 0) return;
    
                int N = nums.length;
                partition(nums, 0, N - 1, 1);
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    测试:

        public static void test(){
            int[] arr = {2,0,1,1,0,2,1};
            int[] arr2 = {2,0,1,1,0,2,1};
            Solution solution = new Solution();
            solution.sortColors(arr);
            for(Integer i:arr) System.out.print(i +" ");
    
            System.out.println();
            solution.sortColorsReview(arr2);
            for(Integer i:arr2) System.out.print(i +" ");
        }
    
    
        public static void main(String[] args) {
            test();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    结果:

    0 0 1 1 1 2 2 
    0 0 1 1 1 2 2 
    
    • 1
    • 2

    LeetCode测试
    在这里插入图片描述
    在这里插入图片描述

    这个题啥也别说,一定会在真的互联网大厂面试中用到的,就是topK问题
    pivot今天是1,
    未来面试中考你,一定pivot是一个随机的
    乃至bfprt算法整中位数数组的中位数
    【2】Topk问题:bfprt算法: 无序数组arr,找出如果arr有序的话,第k小那个数是多少


    总结

    提示:重要经验:

    1)荷兰国旗问题
    3)笔试求AC,可以不考虑空间复杂度,但是面试既要考虑时间复杂度最优,也要考虑空间复杂度最优。

  • 相关阅读:
    问道管理:申购额度如何计算?
    php代码比对工具优化版
    2022 11月24 Ridge/LASSO Regression学习笔记
    [LeetCode解题报告] 241. 为运算表达式设计优先级
    【场景化解决方案】构建门店通讯录,“门店通”实现零售门店标准化运营
    哈尔滨商业大学计算机考研资料汇总
    Python爬虫
    主流的深度学习推理架构有哪些(NCNNN)
    0基础2小时搭建自己的网站
    Linux之基础文件类指令(二)
  • 原文地址:https://blog.csdn.net/weixin_46838716/article/details/126185239