Day1 LeetCode-169-多数元素-简单


169. 多数元素

一、题目描述

  给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。你可以假设数组是非空的,并且给定的数组总是存在多数元素。

  进阶:
  尝试设计时间复杂度为 O(n)、空间复杂度为 O(1) 的算法解决此问题。


二、基础题解

首先,既然标注为简单题了,说明肯定可以在短时间内得出解法,并且可以通过所有测试数据,只不过性能不会很好。
因为刷题用c++比较多一些,STL自然就是是标配了。所以本题第一时间想到的解法就是:

使用map
1、首先遍历一遍数组,使用map统计数组中每个元素及其出现的次数;
2、遍历map,找到出现次数最多的那个元素,即多数元素。

性能分析

时间复杂度:O(nlgn)
说明:因为每次修改元素的出现次数时,都需要修改map,而map是用红黑树实现的,根据红黑树的特性,修改树节点的时间复杂度是O(lgn)。总共有n个元素,所以中的时间复杂度是O(nlgn)。

空间复杂度:O(n)
说明:因为多数元素大于总数的一半,所以map大小的上限就是总数的一半(准确来说是总数一半取上整),即n/2。

三、进阶题解

上述题解其实并未用到“ 出现次数大于⌊ n/2 ⌋ ”性质,相当于就是求众数了。而接下来的解法会让人欣喜若狂!(可能像我这样的菜鸡才会这样吧233)

维护一个候选多数元素more及其出现次数 count。
1、初始化:more = 任意值,count = 0;
2、遍历数组 nums:
  2.1 如果count 的值为 0,more = x ;
  2.2 否则将x和more作比较:
    2.2.1 如果 x == more,则count 加 1;
    2.2.1 如果 x ! = more,则count 减 1;

3、遍历完成后,more就是数组中的多数元素。

解析

我的理解是,因为已知多数元素出现的次数是一定大于⌊ n/2 ⌋的,所以对count执行+1操作其实就是记录多数元素的个数;而执行-1操作就是记录其他无关元素的个数。如果两者数量相等,那么count值最后一定等于0,但是因为多数元素数量更多,所以最后的count一定大于0,而对应的当前记录的数字more,就是这个多数元素!

性能分析

时间复杂度:O(n)
说明:只需遍历一次数组即可。

空间复杂度:O(1)
说明:只需维护两个整型变量,所以是常数空间。

四、总结

进阶解法利用了出现次数大于⌊ n/2 ⌋的性质,其性能就实现了质的飞跃,真是太美妙了!
不禁让我联想起电视剧上相似的场景:某个镜头中,某个人物的眼神特写,最后一定会暗示着什么~~~

五、代码

最后的最后,附上解题代码(c++),相信正在看的你们,一定能自己写出来的。

#include <bits/stdc++.h>
using namespace std;
int majorityElement(vector<int>& nums) {
    
    
    int count = 0;
    int more = 0;
    for (int num : nums) {
    
    
        if(count == 0){
    
    
            more = num;
            count++;
        }else if(more == num){
    
    
            count++;
        }else{
    
    
            count--;
        }
    }
    return more;
}
int main() {
    
    
    vector<int> test = {
    
    1,2,2,1,3,3,1,1,1};
    cout<<majorityElement(test)<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40466537/article/details/116667595