刷题日记03补充

书接上回,上次做了一道求数组中多数的问体,我用了两种方法,一个是自己想出来的比较麻烦的,一个是看了题解用Map做的。根据评论区一个高手建议,我补充一种摩尔投票的解题方法,很好用。

public static int majorityElement(int[] nums){
        int ans = 0;
        int count = 0;
        //摩尔投票
        for (int i = 0; i < nums.length; i++) {
            if(count == 0){
                ans = nums[i];
            }
            if(ans == nums[i]){
                count++;
            }else{
                count--;
            }
        }
        return ans;
}

摩尔算法可以理解为对数组进行抵消、抵消、抵消,直到不能够抵消。那什么时候可以抵消呢?摩尔投票算法是基于这个事实:每次从序列中选取两个数据进行比较,如果不相同就把两个数据删除,最后剩一个或多个相同元素,那么该数字就是我们要找的多数。

比如我们查询一个数组为[2,2,1,1,1,2,2],遍历该数组,同时我们创建两个数组分别为arr和result,arr用来存储当前不能被抵消的数字,result用来表示抵消后剩余数组。

  • 第一个数字为2,前面没有数字可以抵消,arr = {2},result = {2,2,1,1,1,2,2}。
  • 第二个数字为2,和前面的2不能抵消,arr = {2,2},result = {2,2,1,1,1,2,2}。
  • 第三个数字为1,和前面的2抵消,arr = {2},result = {2,1,1,2,2}。
  • 第四个数字为1,和前面的1抵消,arr = {},result = {1,2,2}。
  • 第五个数字为1,前面没有数字了,arr = {1},result = {1,2,2}。
  • 第六个数字为2,和前面的1不能抵消,arr = {},result = {2}。
  • 第七个数字为2,前面没数字了。arr = {2},result = {2}。

所以最后剩个2就是多数。简单来说这就相当于多派战斗,就是比人数,打的时候都是极限一换一,最后剩的就是人多的一派。

除去冗余关系:实际代码中没有array,也没有result,因为我们不需要。由于前面提到array里只可能同时存储一种数字,所以我们用major来表示当前array里存储的数,count表示array的长度,即目前暂时无法删除的元素个数,最后扫描完所有的数字,array和result变成一样了,都表示“最后还是无法删除的数字”。

  • 第一个数字为2,前面没有数字可以抵消,major = 2,count = 1。
  • 第二个数字为2,和前面的2不能抵消,major = 2,count = 2。
  • 第三个数字为1,和前面的2抵消,major= 2。这时候major不用变,因为查到1的时候这个1和前面的2抵消了,还剩一个2,所以arr中还是2,因此major = 2,count = 1。
  • 第四个数字为1,和前面的1抵消,major = 2,count =0。此时count = 0,其实可以理解为扫到的元素都抵消完了,这里可以暂时不改变major的值。
  • 第五个数字为1,前面没有数字了,major = 1,count = 1。
  • 第六个数字为2,和前面的1不能抵消,major暂时不变,major = 1,count= 0。
  • 第七个数字为2,前面没数字了。major= 2,count = 1。

经过上述遍历,我们可以发现,当count = 0的时候,major才会变化,变成当前遍历值。如果count不为0的时候,遍历的值和major相等则count++,遍历的值和major不相等则count--。

通过此题又掌握了一种新算法,耶耶耶

#如何看待2023届秋招##你的秋招进展怎么样了##我的求职思考##0offer是寒冬太冷还是我太菜#
全部评论
楼主,酱紫刷题会不会太认真了。。
1 回复 分享
发布于 2023-01-12 22:52 香港

相关推荐

2024-12-09 17:26
重庆大学 硬件开发
安全劝退第二人:给我发个
点赞 评论 收藏
分享
头发暂时很多的KFC总裁:找廉价劳动力罢了
点赞 评论 收藏
分享
评论
34
2
分享
牛客网
牛客企业服务