1,問題描述
數組中有一個數字出現的次數超過數組長度的一半,請找出這個數字。例如輸入一個長度爲9的數組{1,2,3,2,2,2,5,4,2}。由於數字2在數組中出現了5次,超過數組長度的一半,因此輸出2。如果不存在則輸出0。
2,解題思路
(1)思路一:
遍歷數組,統計每個元素出現的次數。思路簡單,但是時間複雜度是O(n^2).
(2)思路二:陣地攻守。
- 陣地攻守思想:先找出可能的目標元素,再統計該元素出現的次數。時間複雜度是O(n).
- 第一個數字作爲第一個士兵,守陣地;count = 1;
- 遇到相同元素,count++;
- 遇到不相同元素,即爲敵人,同歸於盡,count--;
- 當遇到count爲0的情況,又以新的i值作爲守陣地的士兵.
- 繼續下去,到最後還留在陣地上的士兵,有可能是目標元素。
- 驗證該元素出現的次數是否滿足要求(出現[1,1,2,2]或者[1,2,3,4]的情況不滿足要求,所以需要驗證一下).
3,源碼
/**
* @author Manduner_TJU
* @version 創建時間:2019年4月8日下午3:24:13
*/
public class MoreThanHalfNum {
public static void main(String[] args) {
int[] a = {1,2,3,2,2,2,5,4,2};
//int result = MoreThanHalfNum_Solution(a);
int result = MoreThanHalfNum_Solution2(a);
System.out.println(result);
}
//1,遍歷數組,統計每個元素出現的次數。思路簡單,但是時間複雜度是O(n^2).
public static int MoreThanHalfNum_Solution(int [] array) {
int len = array.length;
if(len == 0) return 0;
int result=0;
count=0;
for(int i=0;i<len;i++) {
if(count(array[i],array)*2 > len) {
result = array[i];
break;
}
}
return result;
}
public static int count(int x, int[] array) {
int num=0;
for(int i=0;i<array.length;i++) {
if(x==array[i]) {
num++;
}
}
return num;
}
/**2,陣地攻守思想:先找出可能的目標元素,再統計該元素出現的次數。時間複雜度是O(n).
* 第一個數字作爲第一個士兵,守陣地;count = 1;
* 遇到相同元素,count++;
* 遇到不相同元素,即爲敵人,同歸於盡,count--;
* 當遇到count爲0的情況,又以新的i值作爲守陣地的士兵.
* 繼續下去,到最後還留在陣地上的士兵,有可能是目標元素。
* 驗證該元素出現的次數是否滿足要求(出現[1,1,2,2]或者[1,2,3,4]的情況不滿足要求).
* @param a
* @return
*/
public static int MoreThanHalfNum_Solution2(int[] a) {
int num = a[0];
int count = 1;
for(int i=1;i<a.length;i++) {
if(a[i]==num) count++;
else count--;
if(count==0) {
num = a[i];
count = 1;
}
}
int result=0;
count=0;
for(int i=0;i<a.length;i++) {
if(a[i]==num) count++;
}
if(count*2>a.length) result = num;
return result;
}
}