【剑指offer】-28-数组中出现次数超过一半的数字
数组中出现次数超过一半的数字
https://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163?tpId=13&&tqId=11181&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
方法一:Map法。时间复杂度:O(n),空间复杂度:O(n)。
import java.util.*;
public class Solution{
public int MoreThanHalfNum_Solution(int[] array) {
if (array.length == 0 || array == null) return 0;
Map<Integer, Integer> map = new HashMap<>();
int maxCount = 0;
int val = 0;
for (int i = 0; i < array.length; i++) {
int currentKey = array[i];
Integer value = map.get(currentKey);
if (value != null) {
map.put(currentKey, value + 1);
if (value + 1 > maxCount) {
maxCount = value + 1;
val = currentKey;
}
} else {
map.put(currentKey, 1);
if (maxCount < 1) {
maxCount = 1;
val = currentKey;
}
}
}
return (maxCount > array.length / 2) ? val : 0;
}
}方法二:同归于尽,相互抵消法。时间复杂度:O(n),空间复杂度:1。
- 阵地攻守的思路:第一个数字作为士兵,count=1,遇到一个相等的数字即友军则count++,遇到不同的数字即敌军则count--,此时当count==0的时候,选用下一个数字作为友军且count=1。直到最后若count >1,那么只有这个数字才有可能是超过一半的数字,因为若一个数字他超过数组一半,那么它必定能活到最后。
- 上一步是找出出现最多的数字,再遍历数组判断这个数字出现的次数是否大于一半。
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
if(array == null || array.length == 0)return 0;
int preValue = array[0];//用来记录上一次的记录
int count = 1;//preValue出现的次数(相减之后)
for(int i = 1; i < array.length; i++){
if(array[i] == preValue)
count++;
else{
count--;
if(count == 0){
preValue = array[i];
count = 1;
}
}
}
int num = 0;//需要判断是否真的是大于1半数,这一步骤是非常有必要的,因为我们的上一次遍历只是保证如果存在超过一半的数就是preValue,但不代表preValue一定会超过一半
for(int i=0; i < array.length; i++)
if(array[i] == preValue)
num++;
return (num > array.length/2)?preValue:0;
}
}
