题目描述:
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
思路:
方法一:
借助hashmap存储数组中每个数出现的次数,最后看是否有数字出现次数超过数组长度的一半;
代码:
package offer;
import org.omg.PortableInterceptor.INACTIVE;
import java.util.HashMap;
import java.util.Map;
public class TestNo28_1 {
public static void main(String[] args) {
int[] a = {1,2,3,2,2,2,5,4,2};
System.out.println(new TestNo28().MoreThanHalfNum_Solution(a));
}
public int MoreThanHalfNum_Solution(int [] array) {
HashMap<Integer,Integer> map = new HashMap<Integer, Integer>();
int len = array.length;
for(int i = 0;i<len;i++){ //开始进行遍历 Entry<键,值> 数作为键,出现的次数作为值
if(!map.containsKey(array[i])){ //如果当前遍历的数不在哈希表中,则将该数加进去<键,1> ‘1’说明该值在哈希表中只有一个
map.put(array[i],1);
}else{
map.put(array[i],map.get(array[i])+1);//如果当前的值已经在哈希表中了,就将该键的值取出来+1
}
for(Map.Entry<Integer,Integer> entry :map.entrySet()){ //遍历每一个Entry,进行验证
if(entry.getValue()>len/2){
return entry.getKey();
}
}
}
return 0;
}
}
方法二:
对数组先进行排序,如果数组中存在一个长度超过数组一半的数字,那么数组中间的那个数一定是这个数。我们取数组中间的那个数做一下统计,验证一下是否大于数组长度的一半。
代码:
package offer;
import java.util.Arrays;
public class TestNo28_2 {
public static void main(String[] args) {
int[] a = {1,2,3,2,2,2,5,4,2};
System.out.println(new TestNo28().MoreThanHalfNum_Solution(a));
}
public int MoreThanHalfNum_Solution(int [] array) {
Arrays.sort(array); //先对数组进行排序
int half = array.length/2;
int count = 0;
for(int i = 0;i<array.length;i++){ //进行遍历
if(array[i] == array[half]){ //如果等于中间的那个数,则计数加1
count++;
}
}
if(count > half) //如果中间那个数的计数大于数组长度的一半,则返回数组中间的值
return array[half];
else
return 0;
}
}
方法三:
如果数组中存在大于数组长度一半的数字,那么该数的长度肯定大于数组中其它数字长度的综合。比如数组arr{1,2,3,2,2,2,5,4,2}中,2的长度是5,数组中其它数字的长度是4,因此,我们可以这样进行遍历,申请两个变量,一个用于记录当前遍历的数字num,一个用于记录次数count,比如,初始化num=arr[0],count=1,开始进行遍历,当与上一个数字相同的时候进行count++操作,当与上一个数字不相同的时候进行count--操作,当count=0的时候,更新num=arr[i],(i指的是使得count为0的数字)。遍历一遍之后,使得count不等于0的数字应该就是大于数组长度一半的数,之后进行验证即可。
代码:
package offer;
public class TestNo28 {
public static void main(String[] args) {
int[] a = {1,2,3,2,2,2,5,4,2};
System.out.println(new TestNo28().MoreThanHalfNum_Solution(a));
}
public int MoreThanHalfNum_Solution(int [] array) {
int num = array[0],count = 1; //num用于记录当前遍历的数,初始化为第一个数。count用于记录次数
for(int i = 1;i<array.length;i++){//开始进行遍历,从当前遍历的下一个数开始
if(array[i] == num){ //如果遍历的数等于 num
count++;
}else{
count--;
}
if(count== 0){ //如果count==0 则更新num为 使count为0的那个数,并且更新count为1
num = array[i];
count = 1;
}
}
count = 0; //进行验证,看看找到的那个数的个数是不是大于数组的一半
for(int i = 0;i<array.length;i++){
if(array[i] == num){
count++;
}
}
return count > array.length/2 ? num:0;
}
}