水王问题 历史和由来可自行百度
抽象问题为:
奉上代码 即详细注释:
* 思想 :如果在一个数组中存在一个出现次数大于一半的数
* 每次删除两个不同的数 到最后剩下的肯定是这个数 不可能是其他是数
*/
public class superId {
public static void main(String[] args) {
int [] arr = {2,5,2,7,2,1,2};
printHalfMajor(arr);
}
public static void printHalfMajor(int [] arr) {
int cand = 0;//候选元素 相当于老怪 不断有新的英雄出现 只要跟他不一样就同归于尽 即同时删去了两个不同的数
int times = 0;//剩余节点数 相当于老怪的生命条数 每次出现相同的数 生命条数就加1 然后出现不同的数就同归于尽 就减少一条生命
//同时删除两个不同的数
for (int i = 0; i != arr.length; i++) {
//1.还没有候选数(就是从第一个数开始)连续出现两个不同的数 则直接删去
if (times == 0) { //如果剩余的数为0 即 没有相同的数
cand = arr[i]; //则当前的数作为候选数
times = 1; //候选数的剩余节点加1
//2.有候选数了 出现了一个和候选数相同的数 则不删除 增加
//候选数的剩余点数
} else if (arr[i] == cand) { //当节点数不为0 且出现相同的候选数时
times++; //候选数的节点数加1 即出现相同的数了
//当存在候选数 然后出现的数与候选数不同 则删除当前数 并带走候选数的一条命
//即候选点数减1
} else { //当节点数不为0 且当前出现的数和候选数不同时
times--; //候选数的节点数减1
}
}
//因为上一个for循环中 如果数组都是不同的数 也会返回一个值 就是最后那个数
//所以需要下面的判断
// times = 0;
for (int i = 0; i != arr.length; i++) {
if (arr[i] == cand) { //到这一步cand已经知道 只是判断是否是多余一半的数
times++;
}
}
if (times > arr.length / 2) {
System.out.println(cand);
} else {
System.out.println("no such number.");
}
}
}
测试结果为:2;
注:通过左神的讲解 深刻理解的 膜拜左神!