【数组4】数组中出现次数超过一半的数字
2016-07-26 19:13
295 查看
【题目】数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
更好的方法:
当数据量很大时,上面两个方法都不适合,这时候 应该考虑到使用快排。
数组中出现次数超过一半的数一定是在中间。所以使用快排,每次获取中枢轴值。若中枢轴值恰好在中间,即返回对应值,再进行判断是否其次数超过一半。
public class Solution {
public int MoreThanHalfNum_Solution(int [] arr) {
if(arr == null || arr.length <= 0)
return 0;
int middle = arr.length >> 1;
int low = 0;
int high = arr.length - 1;
int pivot = Partition(arr, low, high);
while(pivot != middle){
if(pivot > middle){
pivot = Partition(arr, low, pivot - 1);
} else{
pivot = Partition(arr, pivot + 1, high);
}
}
int num = arr[middle];
int count = 0;
for(int i = 0; i < arr.length; i++){
if(arr[i] == num)
count++;
}
if(count * 2 > arr.length)
return num;
return 0;
}
public int Partition(int[] arr, int low, int high){
int pivotKey = arr[low];
while(low < high){
while(low < high && arr[high] >= pivotKey){
high--;
}
Swap(arr, low, high);
while(low < high && arr[low] <= pivotKey){
low++;
}
Swap(arr, low, high);
}
return low;
}
private void Swap(int[] arr, int low, int high) {
int temp = arr[low];
arr[low] = arr[high];
arr[high] = temp;
}
}
更好的方法:
import java.util.*; public class Solution { public int MoreThanHalfNum_Solution(int [] arrs) { if(arrs==null ||arrs.length<=0) return 0; Map<Integer,Integer> map = new HashMap<>();//数+对应的出现次数 Set<Integer> set=new HashSet<>(); for(int i=0;i<arrs.length;i++){ if(!set.add(arrs[i])){ map.put(arrs[i],map.get(arrs[i])+1);//有相同值次数+1 }else{ map.put(arrs[i],1);//第一次添加 } } for(Map.Entry<Integer,Integer> entry:map.entrySet()){ Integer key=entry.getKey(); Integer value=entry.getValue(); if(value>(arrs.length/2))//遍历map集合,找到出现次数超过一半的,返回对应的数字 return key; } return 0; } }
/**思路 *遍历数组,相同的数,count+1,不同,-1. * */ public class Solution { boolean flag=false; public int MoreThanHalfNum_Solution(int [] arrs) { if(arrs==null ||arrs.length<=0){ flag=true; return 0; } int result=arrs[0]; int count=1; for(int i=1;i<arrs.length;i++){ if(count==0){ result=arrs[i]; count=1; } if(result==arrs[i]){ count++; }else{ count--; } } if(!CheckMoreThanHalfNum(arrs,result)){ flag=true; return 0; } return result; } private boolean CheckMoreThanHalfNum(int[] arrs,int result){ int len=arrs.length; int count=0; for(int i=0;i<len;i++){ if(result==arrs[i]) count++; } if(2*count<=len){ return false; } return true; } }
当数据量很大时,上面两个方法都不适合,这时候 应该考虑到使用快排。
数组中出现次数超过一半的数一定是在中间。所以使用快排,每次获取中枢轴值。若中枢轴值恰好在中间,即返回对应值,再进行判断是否其次数超过一半。
public class Solution {
public int MoreThanHalfNum_Solution(int [] arr) {
if(arr == null || arr.length <= 0)
return 0;
int middle = arr.length >> 1;
int low = 0;
int high = arr.length - 1;
int pivot = Partition(arr, low, high);
while(pivot != middle){
if(pivot > middle){
pivot = Partition(arr, low, pivot - 1);
} else{
pivot = Partition(arr, pivot + 1, high);
}
}
int num = arr[middle];
int count = 0;
for(int i = 0; i < arr.length; i++){
if(arr[i] == num)
count++;
}
if(count * 2 > arr.length)
return num;
return 0;
}
public int Partition(int[] arr, int low, int high){
int pivotKey = arr[low];
while(low < high){
while(low < high && arr[high] >= pivotKey){
high--;
}
Swap(arr, low, high);
while(low < high && arr[low] <= pivotKey){
low++;
}
Swap(arr, low, high);
}
return low;
}
private void Swap(int[] arr, int low, int high) {
int temp = arr[low];
arr[low] = arr[high];
arr[high] = temp;
}
}
相关文章推荐
- 阅读笔记(五)
- 2016 Multi-University Training Contest 3
- POJ3368 Frequent Values [RMQ] [线段树]
- 2015 Multi-University Training Contest 1
- HDU 5762Teacher Bo
- 有序顺序表归并
- tyvj1228 有道搜索框
- 用 Python 写了个简单的股票量化交易框架
- java之文件夹
- 【字符串2】-字符串排列
- PHPMailer发匿名邮件及Extension missing: openssl的解决
- Opencv图像识别从零到精通(16)------膨胀腐蚀
- 顺序表元素移位
- spring 静态AOP切第三方jar包
- HDU 3361 ASCII (水题)
- 生成四位随机数的PHP代码
- phoenix初步
- 顺序表建表法清除重复元素
- Java IO流(一)_day20
- 【数组3】-调整数组顺序使奇数位于偶数前面