文章目录
超级水王
解题思路
代码
229. 多数元素 II
摩尔投票法
代码
超级水王
给定一个数组arr,如果有某个数出现次数超过了数组长度的一半,打印这个数,如果没有不打印
解题思路
一次删掉两个不同值的数,如果arr中真的有水王的话,这个水王数一定会剩下来
因为水王数是大于一半的次数的。哪怕其它所有的数字都跟水王数为敌
水王数也会活下来,更不用说其它数字之间还会有内战的情况
可能性
1:没有数字剩下来,无水王数
2:有数剩下来
x剩下来,再遍历看x真实出现的次数跟N/2对比
怎么一次删除两个不同的数?
时间复杂度O(N)
空间复杂度0(1)
两个变量
1)候选
2)血量
当血量=0,认为没有候选人
一个个数遍历,三条规则:
1)如果没有候选,当前数立为候选,血量+1
2)如果有候选
1.当前数跟候选不一样,血量–
2.当前数是候选,血量++
遍历完成后,如果血量=0,表示什么数也没有剩下来,如果血量不等于零,候选就是剩下来的数
代码
public static void printHalfMajor(int[] arr) {
int cand = 0;
int HP = 0;
for (int i = 0; i < arr.length; i++) {
if (HP == 0) {
cand = arr[i];
HP = 1;
} else if (arr[i] == cand) {
HP++;
} else {
HP--;
}
}
if(HP == 0) {
System.out.println("no such number.");
return;
}
HP = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == cand) {
HP++;
}
}
if (HP > arr.length / 2) {
System.out.println(cand);
} else {
System.out.println("no such number.");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Interlaken Protocol白皮书(中文)
0星
超过10%的资源
851KB
下载
229. 多数元素 II
给定一个大小为 n 的整数数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。
示例 1:
输入:nums = [3,2,3]
输出:[3]
示例 2:
输入:nums = [1]
输出:[1]
示例 3:
输入:nums = [1,2]
输出:[1,2]
摩尔投票法
与水王问题相似,思路是消耗血量,因为是找出出现超过 ⌊ n/3 ⌋ 次的元素
我们可以推出最后最多剩下2个数字
因为如果有3个数字都超过n/3,那么数组长度至少是n+3,不符合题目
因此最多只有2个数字超过n/3
我们需要设置两个hp来记录两个数的血量
设置两个cand来记录哪两个数活到最后
最后只需再遍历数组两个数是否符合超过n/3
代码
class Solution {
public List<Integer> majorityElement(int[] nums) {
int hp1=0;
int cand1=0;
int hp2=0;
int cand2=0;
int n=nums.length;
for(int i=0;i<n;i++){
if(hp1>0&&nums[i]==cand1){
hp1++;
}else if(hp2>0&&nums[i]==cand2){
hp2++;
}
else if(hp1==0){
hp1=1;
cand