两道题有点像,就直接放在一起写了。第一题找出数组中超过一半的数字,可以用map存储,key是数字,value是次数,记录后遍历value即可,时间复杂度o(n),但是需要o(n)的的空间复杂度。记录数组出现次数times,一次遍历,如果相同则times++,如果不同则--,因为数字次数超过一半,所以最后times>1的数字肯定是要找的数字。时间复杂度为o(n),空间复杂度o(1)
public static int moreThanHalf(int[] array) {
if (array == null || array.length <= 0) {
return 0;
}
int len = array.length;
int result = array[0];
int times = 1;
for (int i = 1; i < len; i++) {
if (times == 0) {
result = array[i];
times++;
} else if (result == array[i]) {
// 如果相同++
times++;
} else {
// 如果不同--
times--;
}
}
return result;
}
第二题,数组中重复的数字,长度为n数组中所有数字都在0到n-1范围内,找出某个重复数字,在范围内这个条件很重要,这样的话所有的数字和数组对应下标应该是相同的,即i=array[i],若没有重复出现,所以如果有重复出现的话则不满足这个条件,找出了重复的数字;如果不满足条件的时候,交换对应数字,有两个循环,但是里面的while是两两交换,时间复杂度还是o(n)
public static int repeatNumber(int[] array) {
if (array == null || array.length <= 0) {
return 0;
}
int len = array.length;
for (int i = 0; i < len; i++) {
while (array[i] != i) {
// 如果有之前的相同,则说明重复了
if (array[i] == array[array[i]]) {
return array[i];
}
// 交换两个数字
int tem = array[i];
array[i] = array[tem];
array[tem] = tem;
}
}
return 0;
}