题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
解题思路
解法一:
import java.util.Arrays;
public class Solution {
//如果存在,那么把数组排序之后,那个数一定是中间元素
public int MoreThanHalfNum_Solution(int [] array) {
Arrays.sort(array);
int len = array.length;
int midValue = array[len/2];
int count = 0 ;
for (int i = 0;i < len;i++){
if (midValue == array[i]){
count ++;
}
}
if (count > len/2){
return midValue;
}
return 0;
}
}
解法二:
数组中有一个数字出现的次数超过数组长度的一半,也就是说它出现的次数比其他所有数字出现次数的和还要多。因此我们可以考虑在遍历数组的时候保存两个值:一个是数组的一个数字,一个是次数。当我们遍历到下一个数字的时候,如果下一个数字和我们之前保存的数字相同,则次数加 1;如果下一个数字和我们之前保存的数字不同,如果次数大于0,则次数减1 ;如果次数为零,我们需要保存下一个数字,并把次数设为1 。由于我们要找的数字出现的次数比其他所有数字出现的次数之和还要多,如果存在,那么最后保存着的数字一定是所求。
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
int len = array.length;
if (len == 0){
return 0;
}
int curNumber = array[0];
int curCount = 1;
for (int i = 1;i < len;i++){
if (array[i] == curNumber){
curCount++;
}else{
if (curCount > 0){
curCount--;
}else{
curNumber = array[i];
curCount = 1;
}
}
}
int count = 0;
for (int i = 0;i < len;i++){
if (curNumber == array[i]){
count++;
}
}
if (count > len/2){
return curNumber;
}else{
return 0;
}
}
}
解法三:
利用map记录数组值和出现的次数 -- 空间换时间
import java.util.HashMap;
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
HashMap<Integer,Integer> map = new HashMap<>();
int len = array.length;
for (int i = 0;i < len;i++){
int cur = array[i];
if (map.containsKey(cur)){
map.put(cur,map.get(cur) + 1);
}else{
map.put(cur,1);
}
if (map.get(cur) > len/2){
return cur;
}
}
return 0;
}
}