题目:数组中有一个数字出现的次数超过了数组长度的一半(大于一半),找出这个数字。
解法一:排序后返回arr[N/2],N为数组的长度。O(nlg(n))
代码:排序直接调用Arrays.sort(arr);
解法二:hash统计
解法三:等价于找第N/2小的元素。O(n)注意:这种方法会改变数组里面的元素顺序
代码:可以参考:第k个元素-快排思想_羡云不羡君的博客-CSDN博客
解法四:不同的数进行消除
public class 超过一半的数字 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = {1,5,2,1,1,1};
fun(arr);
}
//解法四
public static void fun(int[] arr) {
//定义一个候选数:把第一个元素定义为候选数
int candidate = arr[0];
//出现的次数
int nTimes = 1;
//扫描数组
for(int i =1;i<arr.length;i++) {
if(nTimes==0) {//出现的次数为0了,需要重新定义一个候选数
candidate = arr[i];
nTimes = 1;
continue;//重新选了候选数后需要跳过后面语句,找到下一个数,与候选数比较
}
if(arr[i]==candidate) {
nTimes++;//与候选数相同,次数加1
}
else {
nTimes--;//与候选数不同,次数减一
}
}
//扫描一遍过后,只有出现次数大于了一半的才能成为候选数
System.out.println(candidate);
}
}
解法五:双层for循环统计出现次数,暴力破解。 O(n^2)
public class 超过一半的数字 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = {1,5,2,1,1};
fun1(arr);
}
//解法五
public static void fun1(int[] arr) {
int[] count = new int[arr.length];
int maxcount = 0;
int maxValue = 0;
for(int i = 0;i<arr.length;i++) {
count[i] = 0;
for(int j = 0;j<arr.length;j++) {
if(arr[i] == arr[j]) {
count[i]++;
}
}
if(count[i]>maxcount) {
maxcount = count[i];
maxValue = arr[i];
}
}
if(maxcount>arr.length /2)
System.out.println(maxValue);
else
System.out.println("不存在这样的数");
}
}