❓ 剑指 Offer 39. 数组中出现次数超过一半的数字
难度:简单
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2
限制:
- 1 <= 数组长度 <= 50000
注意:本题 169. 多数元素 相同。
💡思路:投票问题
多数投票问题,可以利用 Boyer-Moore Majority Vote Algorithm 来解决这个问题,使得时间复杂度为 O ( n ) O(n) O(n)。
使用 cnt
来统计一个元素出现的次数:
- 当遍历到的元素和统计元素相等时,令
cnt++
,否则令cnt--
。 - 如果前面查找了
i
个元素,且cnt == 0
,说明前i
个元素没有ans
,或者有ans
,但是出现的次数少于i / 2
,因为如果多于i / 2
的话cnt
就一定不会为 0 。此时剩下的n - i
个元素中,ans
的数目依然多于(n - i) / 2
,因此继续查找就能找出ans
。
🍁代码:(C++、Java)
C++
class Solution {
public:int majorityElement(vector<int>& nums) {int ans = nums[0], cnt = 0;for(int num : nums) {ans = cnt == 0 ? num : ans;cnt = ans == num ? ++cnt : --cnt;}return ans;}
};
Java
class Solution {public int majorityElement(int[] nums) {int ans = nums[0], cnt = 0;for(int num : nums) {ans = cnt == 0 ? num : ans;cnt = ans == num ? ++cnt : --cnt;}return ans;}
}
🚀 运行结果:
🕔 复杂度分析:
- 时间复杂度: O ( n ) O(n) O(n),其中
n
为数组的长度,Boyer-Moore 算法只对数组进行了一次遍历。。 - 空间复杂度: O ( 1 ) O(1) O(1),只需要常数级别的额外空间。
题目来源:力扣。
放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我LeetCode主页 / CSDN—力扣专栏,每日更新!