题目:一个数组中有一种数出现K次,其它数都出现了M次,M>1且K<M,找到出现了K次的数,并要求额外空间复杂度为O(1),时间复杂度为O(N)
package com.harrison.class01;
import java.util.HashMap;
import java.util.HashSet;
public class Code12_KM {
public static int onlyKTimes(int[] arr,int k,int m){
int[] t=new int[32];
for(int num:arr){
for(int i=0; i<=31; i++){
t[i]+=(num>>i)&1;
}
}
int ans=0;
for(int i=0; i<32; i++){
if((t[i]%m)!=0){
ans |= (1<<i);
}
}
return ans;
}
public static int test(int[] arr,int k,int m){
HashMap<Integer,Integer> map=new HashMap<>();
for(int num:arr){
if(map.containsKey(num)){
map.put(num,map.get(num)+1);
}else{
map.put(num,1);
}
}
for(int num:map.keySet()){
if(map.get(num)==k){
return num;
}
}
return -1;
}
public static int[] generateRandomArray(int maxKinds,int range,int k,int m){
int kTimesNum=randomNumber(range);
int numKinds=(int)(Math.random()*maxKinds)+2;
int[] arr=new int[k+(numKinds-1)*m];
int index=0;
for( ; index<k; index++){
arr[index]=kTimesNum;
}
numKinds--;
HashSet<Integer> set=new HashSet<>();
set.add(kTimesNum);
while(numKinds!=0){
int curNum=0;
do{
curNum=randomNumber(range);
}while(set.contains(curNum));
set.add(curNum);
numKinds--;
for(int i=0; i<m; i++){
arr[index++]=curNum;
}
}
for(int i=0; i<arr.length; i++){
int j=(int)(Math.random()*arr.length);
int tmp=arr[i];
arr[i]=arr[j];
arr[j]=tmp;
}
return arr;
}
public static int randomNumber(int range){
return (int)(Math.random()*(range)+1)-(int)(Math.random()*(range)+1);
}
public static void main(String[] args) {
int maxKinds=10;
int range=200;
int testTimes=100000;
int max=9;
System.out.println("test begin");
for(int i=0; i<testTimes; i++){
int a=(int)(Math.random()*max)+1;
int b=(int)(Math.random()*max)+1;
int k=Math.min(a,b);
int m=Math.max(a,b);
if(a==b){
m++;
}
int[] arr=generateRandomArray(maxKinds,range,k,m);
int ans1=onlyKTimes(arr,k,m);
int ans2=test(arr,k,m);
if(ans1!=ans2){
System.out.println("oops");
}
}
System.out.println("test finish");
}
}