数组中出现次数超过一半的数字
题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
输入
[1,2,3,2,2,2,5,4,2]
返回值
2
看到代码直觉就是用map做,遍历存放数值和出现次数。没多大困难可以做出来,但是占用内存也很高啊。想点办法优化。
方法一(easy,easy。不会吧不会吧,你不会做不出来吧)
import java.util.HashMap;
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
HashMap h = new HashMap<Integer,Integer>();
if(array.length == 1)
return array[0];
for(int i = 0;i<array.length;i++){
int cur = array[i]; // 当前数值
if(h.get(cur) == null){
//如果为空表示第一次出现
h.put(cur,1);
}else{
//不为空在基础上加一
int num = (Integer)h.get(cur) + 1;
h.put(cur,num);
if(num == array.length/2 + 1){
//如果有出现次数大于一半退出循环
return cur;
}
}
}
return 0;
}
}
好吧,我自己没想明白。就去看了题解,解题思路真的是惊为天人。。这就是算法吗?爱了爱了
假设不同的数字代表不同阵营,每个士兵都容不得敌人,宁愿与敌人同归于尽。可以想象,如果某个阵营的士兵数量超过所有阵营士兵总数的一半,该阵营士兵一换一带走一个其他阵营的,最终剩下的就是该阵营的士兵了,该阵营就获胜了。
打仗了,士兵依次进入战场,首先是1和2同归于尽,然后3来到战场,现在3是胜者,接着2进入与它同归于尽,2又进入…重复这个过程。最终战场上剩下的只会是同一阵营的,而该阵营就是人数过半的那个。
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
int count = 0; //用来记录当前胜方人数
int win = 0; //用来记录当前胜方
for(int n : array){
if(count == 0){
win = n;
count = 1;
}else{
if(win == n){
//同一阵营
count++;
}else{
//不同阵营
count--;
}
}
}
int sign = 0;
for(int n : array){
if(n == win){
sign = sign+1;
}
if(sign >= array.length/2 + 1){
return win;
}
}
return 0;
}
}