LeetCode琅琊榜-第一层(荷兰国旗问题)

LeetCode_75.颜色分类

难度:中等

关注博主,持续输出优质算法内容

题目


传统代码的思路与实现🐼

class Solution {
    public void sortColors(int[] nums) {
        var red = 0;
        var white = 0;
        var blue = 0;
        for (var item : nums) {
            if (item == 0) {
                red++;
            }else if (item == 1) {
                white++;
            }else {
                blue++;
            }
        }
        for (int i = 0;i < nums.length;i++) {
            if (i < red) {
                nums[i] = 0;
            }else if (i < red + white) {
                nums[i] = 1;
            }else {
                nums[i] = 2;
            }
        }
    }
}
  • 1.思路🦁

    • 由题目可知,数组里面的元素有且仅有三个元素,分别是[0,1,2]
    • 根据示例可知,无非是将这三个数字进行排序罢了
    • 我们不妨把这三个数字的个数分别统计起来,然后再将它们分别赋值给数组中对应的下标
  • 2.代码分析🦁

    • 如代码所示,第一个增强for循环用于对这三个数字分别进行统计,相应的我们要设置三个对应的变量用于统计对应的个数
    • 第二个for循环用于给数组对应的位置赋值

不足之处及提升的方法🐼 

不足:😀

  • 该算法循环遍历了该数组两次,太多了,我不满意

提升的方法:😀

  • 采用快速排序的思想来完成这道问题,即这道题对应的荷兰国旗问题算法的思想

荷兰国旗问题的思路分析🐼

  • 数组中只可能存在三个不同的元素,我们不妨把他们分为三组
    • [0,p0),这一组只可以放0
    • [p0,i),这一组只可以放1
    • [p2,nums.lengh-1]这一组只能放2
    • 要点:
      • 0和nums.length-1是闭区间的原因是这两个位置是可以肯定的,因为第一个区间一定从0开始,最后一个区间一定从nums.length-1结束
      • 同理得,第二个区间一定是从p0开始,其他都是不确定的,所以用开区间
  • 我们分别定义上面的三个变量i,p0,p1,然后得出一下的定义
    • p0表示的是第一个区间的最后一个元素的后一个元素
    • i表示的是第二区间的最后一个元素的后一个元素
    • p2表示的是第三个区间的第一个元素的前一个元素
  • 注意:我们要严格遵循变量定义不变的规则,我们不能写着写着程序这些变量的所对应的意义发生了改变,我更愿意称之为"变量定义不变性"
  • 注意:这三个区间一开始应该是空的,因为一开始我们不知道谁应该有多少,有没有,所以应该是空的

荷兰国旗问题的代码实现与分析🐼

class Solution {
    public void sortColors(int[] nums) {
        var p0 = 0;
        var p1 = nums.length - 1;
        int i = 0;
        while (i <= p1) {
            if (nums[i] == 0) {
                swap(nums,i,p0);
                p0++;
                i++;
            }else if (nums[i] == 1) {
                i++;
            }else {
                swap(nums,i,p1);
                p1--;
            }
        } 
    }

    public void swap(int[] nums,int n1,int n2) {
        var temp = nums[n1];
        nums[n1] = nums[n2];
        nums[n2] = temp;
    }
}

代码分析🐨:

  1. p0和i赋值为0,p1赋值为nums.length-1即他们三个对应的区间分别是[0,0) [0,0) (length-1,length-1]
    1. 可以清晰的得出他们三个区间一开始都是空区间
  2. 循环讲述
    1. 布尔表达式为i <= p1的原因
      1. 我们不妨看看定义,我们这三个区间最终组合起来应该是整个数组,我们不妨得到[0,p0) + [p0,i) + (p1,nums.length-1]
      2. 当我们的i = p1的时候刚好遍历到最后一个元素,即当i=p1的时候,就可以组成一个完整的数组
    2. 如果我们发现,i指向的元素是等于0的话,我们应该放在第一个区间中,由定义可知,p0是最后一个元素的后一个元素,所以i要与p0调换
      1. 调换之后,为了保持变量定义不变性,我们需要将p0++,因为p0++了,对应的i也要++,如果i不++,会导致第二个区间的i的定义发生了变化
    3. 如果我们发现i指向的元素等于1的话,由于变量定义不变性,i需要++
    4. 同理得
      1. 注意的是:如果放到第三个区间,i的定义并没有发生改变,所以不需要进行改变

结论🐼

        题目的解法是以快速排序的基础上建立起来的,然而,在我的观点看来,这可以独立成一个区间问题,以后凡是遇到区间问题都可以借鉴该算法,我来总结该算法的核心掌握内容

        1.变量定义不变性

        2.区间的划分 

  • 28
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 42
    评论
LeetCode-Editor是一种在线编码工具,它提供了一个用户友好的界面编写和运行代码。在使用LeetCode-Editor时,有时候会出现乱码的问题。 乱码的原因可能是由于编码格式不兼容或者编码错误导致的。在这种情况下,我们可以尝试以下几种解决方法: 1. 检查文件编码格式:首先,我们可以检查所编辑的文件的编码格式。通常来说,常用的编码格式有UTF-8和ASCII等。我们可以将编码格式更改为正确的格式。在LeetCode-Editor中,可以通过界面设置或编辑器设置来更改编码格式。 2. 使用正确的字符集:如果乱码是由于使用了不同的字符集导致的,我们可以尝试更改使用正确的字符集。常见的字符集如Unicode或者UTF-8等。在LeetCode-Editor中,可以在编辑器中选择正确的字符集。 3. 使用合适的编辑器:有时候,乱码问题可能与LeetCode-Editor自身相关。我们可以尝试使用其他编码工具,如Text Editor、Sublime Text或者IDE,看是否能够解决乱码问题。 4. 查找特殊字符:如果乱码问题只出现在某些特殊字符上,我们可以尝试找到并替换这些字符。通过仔细检查代码,我们可以找到导致乱码的特定字符,并进行修正或替换。 总之,解决LeetCode-Editor乱码问题的方法有很多。根据具体情况,我们可以尝试更改文件编码格式、使用正确的字符集、更换编辑器或者查找并替换特殊字符等方法来解决这个问题
评论 42
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爪哇土著、JOElib

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值