第一题用捉队厮杀的策略实现ON时间,O1空间
但是捉对厮杀其实并不是先分成两对两对然后再汇总,
思想这是么一个思想,但实现起来有些小细节。
如果那样做也可以,但是比较麻烦
所以实现的时候是相当于取一个擂台。
每个数直接和擂主相杀,相同的话擂主加一滴血count++。不同的话擂主掉一滴血count--。
擂主血掉光了,下一个数就上擂台,初始血为1。
public int majorityElement(int[] nums) {
int ans = nums[0];
int count = 0;
for (int n : nums) {
if (count == 0) { //瞄下擂台是否为空
ans = n; //成功上台
count++;
} else if (n == ans) {
count++; //加血
} else {
count--; //pk,擂主掉血,自己也炮灰了
}
}
return ans;
}
LC229的话是三个,也是同样套路,但是由于可以存在两个擂主, 这两个擂主有的可能是凭实力,有的可能是凭运气,所以最后需要再过一遍把实力派筛出来。
public List<Integer> majorityElement(int[] nums) {
int target1 = 0, target2 = 0, count1 = 0, count2 = 0;
for (int n : nums) {
if (count1 == 0 && count2 == 0) { // 是不是两擂台都空
target1 = n; //上擂台
count1++;
} else if (count1 == 0 && n != target2) { //一个擂台空
target1 = n;
count1++;
} else if (count2 == 0 && n != target1) { //另一个擂台空
target2 = n;
count2++;
} else if (count1 != 0 && n == target1) { //加血
count1++;
} else if (count2 != 0 && n == target2) {//加血
count2++;
} else { //两擂主同时掉血。因为只有 1/3多,所以需要以1敌2。
count1--;
count2--;
}
}
count1 = 0;
count2 = 0;
for (int n : nums) {
count1 += (n == target1 ? 1 : 0);
count2 += (n == target2 ? 1 : 0);
}
List<Integer> ans = new ArrayList<>();
if (count1 * 3 > nums.length) ans.add(target1);
if (target2 != target1 && count2 * 3 > nums.length) ans.add(target2);
return ans;
}