* 面试题39:数组中出现次数超过一半的数字
* 题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
* 例如:输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.
* 由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2
*
* 思路:Partition方法
* 将数组进行排序,若是某个数字在数组中超过一半,
*那么排序后的中间位置的数字就是要找的那个重复的数字
*使用快速排序的方法,将其进行排序 找到中间的,
*并且使用一个函数再对该数字进行检验,查看重复量是否超过了一半
package Test;
public class No39MoreThanHalfNum {
/*
* 面试题39:数组中出现次数超过一半的数字
* 题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
* 例如:输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.
* 由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2
*
*
* 思路:Partition方法
* 将数组进行排序,若是某个数字在数组中超过一半,
*那么排序后的中间位置的数字就是要找的那个重复的数字
*使用快速排序的方法,将其进行排序 找到中间的,
*并且使用一个函数再对该数字进行检验,查看重复量是否超过了一半
*
* */
//int flag = 0;
//标志位(当number=0时) :若flag为0 表示数组不为空 若flag为1 表示数组为空
public static void main(String[] args) {
// TODO Auto-generated method stub
No39MoreThanHalfNum m = new No39MoreThanHalfNum();
int[] array = {1,2,3,2,2,2,5,4,2};
System.out.println("数组中超过一半的数字是:"+m.MoreThanHalfNum_Solution(array));
}
//查找数组中超过一半的数字
public int MoreThanHalfNum_Solution(int[] array) {
// TODO Auto-generated method stub
if(array == null || array.length == 0) {
// flag = 1;
return 0;
}
int midIndex = array.length/2;
int low = 0;
int high = array.length - 1;
int p = partition(array,low,high);
//若是p !中间值,则继续找中间值
while(p != midIndex) {
if(p > midIndex)
high = p - 1;
else if(p < midIndex)
low = p + 1;
p = partition(array,low,high);
}
if(checkMoreThanHalf(array,array[p]))
return array[p];
return 0;
}
//判断是否中间值array[p] 在数组中出现的次数超过了一半
public boolean checkMoreThanHalf(int[] array, int val) {
// TODO Auto-generated method stub
System.out.println(val);
int count = 0;
for(int i = 0;i < array.length;i++) {
//for(int i : array)
//if(i == val)
if(array[i] == val)
count++;
}
//若count大于数组长度一半,则返回true;否则返回false
return count > array.length/2;
}
//快速排序算法 然后索引号
public int partition(int[] array,int low,int high) {
int val = array[low];
int i = low + 1;
int j = high;
//走一遍 从左到右 右边小 左边大
while(i <= j) {
while(i <= high && array[i] < val)
i++;
while(j >= low && array[j] > val)
j--;
if(i > j)
break;
//找到左边大的 和 右边小的
//首先进行交换
//然后i自加,j自加向下继续比较
swap(array,i++,j--);
}
//将选定的节点,与j进行交换 形成 左边小 右边大的数组
swap(array,low,j);
return j;
}
public void swap(int[] array,int indexA,int indexB) {
int temp = array[indexA];
array[indexA] = array[indexB];
array[indexB] = temp;
}
}
* 面试题39:数组中出现次数超过一半的数字
* 题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
* 例如:输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.
* 由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2
*
*
* 思路:根据数组特点找出时间复杂度为O(n)的算法
* 定义两个变量:一个用于记录数字 一个用于记录数字出现的次数
* 首次访问该数字时,次数设置为1,访问之后的元素,相等,则加1;不等,则减1;
* 若次数等于零,则开始记录下一个数字
* 其中因为重复超过数组的一半,所以该数字应该是最后一个次数被设置为1的值
package Test;
public class No39MoreThanHalfNum_ArrayFeature {
/*
* 面试题39:数组中出现次数超过一半的数字
* 题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
* 例如:输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.
* 由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2
*
*
* 思路:根据数组特点找出时间复杂度为O(n)的算法
* 定义两个变量:一个用于记录数字 一个用于记录数字出现的次数
* 首次访问该数字时,次数设置为1,访问之后的元素,相等,则加1;不等,则减1;
* 若次数等于零,则开始记录下一个数字
* 其中因为重复超过数组的一半,所以该数字应该是最后一个次数被设置为1的值
*
*
*
* */
//int flag = 0;
//标志位(当number=0时) :若flag为0 表示数组不为空 若flag为1 表示数组为空
public static void main(String[] args) {
// TODO Auto-generated method stub
No39MoreThanHalfNum_ArrayFeature m = new No39MoreThanHalfNum_ArrayFeature();
int[] array = {1,2,3,2,2,2,5,4,2};
System.out.println("数组中超过一半的数字是:"+m.MoreThanHalfNum_Solution(array));
}
//查找数组中超过一半的数字
public int MoreThanHalfNum_Solution(int[] array) {
// TODO Auto-generated method stub
if(array == null || array.length == 0) {
// flag = 1;
return 0;
}
//从数组的第一个数字开始遍历
//记录数值
int result = array[0];
//记录次数
int times = 1;
for(int i = 1;i < array.length;i++) {
//若次数为0 需要保存下一个数字 并且设置times为1
if(times == 0) {
result = array[i];
times = 1;
}
//若当前值和记录的值相等 则 times加1
else if(array[i] == result) {
times ++;
}
//若当前值和记录的值不相等 则 times减1
else {
times --;
}
}
if(checkMoreThanHalf(array,result))
return result;
return 0;
}
//判断是否中间值array[p] 在数组中出现的次数超过了一半
public boolean checkMoreThanHalf(int[] array, int val) {
// TODO Auto-generated method stub
System.out.println(val);
int count = 0;
for(int i = 0;i < array.length;i++) {
//for(int i : array)
//if(i == val)
if(array[i] == val)
count++;
}
//若count大于数组长度一半,则返回true;否则返回false
return count > array.length/2;
}
}