数组中出现次数超过一半的数字
使用hashMap
记录每个数字出现次数,寻找出现次数超过一半的数字。
public static int moreThanHalfNum(int[] nums){
if (nums == null){
return 0;
}
Map<Integer,Integer> map= new HashMap<>();
int len = nums.length;
for (int i = 0; i< len;i++){
map.put(nums[i],map.getOrDefault(nums[i],0)+1);
if (map.get(nums[i])>len/2){
return nums[i];
}
}
return 0;
}
拓展方法
令result = nums[0],times = 1;
如果nums[1]!=nums[0],times-1;
如果nums[1]==nums[0],times+1;
当times==0时,改变result,再令times=1;
重复以上步骤,若最后times>1,则result为出现次数超过一半的数字。
[1,2,1,1,3,1,4,1]
result=1,times=1;
1!=2;times-=1;times==0;result=2;times=1;
2!=1;times-=1;times==0;result=1;times=1;
1==1;times+=1;times==2;
3!=1times-=1;times==1;
1==1;times+=1;times==2;
4!=1;times-=1;times==1;
1==1;times+=1;times==2;
public static int moreThanHalf(int[] nums){
int count = 0;
Integer candidate = null;
for (int num:nums){
if (count==0){
candidate = num;
}
System.out.println("candidate"+candidate);
if (num!=candidate){
count--;
}else {
count++;
}
if (count == 0){
candidate = num;
count = 1;
}
System.out.println("count"+count);
}
return count==1?0:candidate;
}
数组中只出现一次的数字
除了某个元素只出现一次外,其余每个元素均出现两次,找出只出现一次的元素。
使用set集合
将元素加入set集合中,因重复加入时而失败时,删除要加入元素的对应元素,最后剩下的元素为出现了一次的元素。
public static Integer findOneNum(int[] arr){
Set<Integer> set = new HashSet<>();
for (int i:arr){
if (!set.add(i)){
set.remove(i);
}
}
if (set.size()==0){
return null;
}
return set.toArray(new Integer[set.size()])[0];
}
使用位运算
二进制位运算,异或结合律,相同为0,相异为1,两个相同的数异或后得0,0异或其它数仍为其它数。
public static Integer findOneNum02(int[] arr){
int flag = 0;
for (int i:arr){
flag^=i;
}
return flag;
}
找出数组中的重复数字
public static Set findDuplicates(int[] arr){
Set<Integer> set = new HashSet<>();
Set<Integer> res = new HashSet<>();
for (int i : arr){
if (!set.add(i)){
res.add(i);
}
}
return res;
}
//可以改变map.get(i)>?来找到出现相应次数的元素
public static Set findDuplicates02(int[] arr){
Map<Integer,Integer> map = new HashMap<>();
Set set = new HashSet();
for (int i:arr){
map.put(i,map.getOrDefault(i,0)+1);
if (map.get(i)>1){
set.add(i);
}
}
return set;
}
leetcode137
public static int singleNumber(int[] arr){
int a = 0,b=0;
for (int i = 0;i < arr.length;i++){
b = (b^arr[i])&~a;
a = (a^arr[i])&~b;
}
return b;
}
颜色分类问题
leetcode75
0、1、2代表红、白、蓝三色,进行原地排序,按照红白蓝顺序排,相同颜色相邻。
双指针
找到nums[right]==0,与nums[left]进行交换,left++;
找到nums[right]==1,与nums[left]进行交换,left++.
//2次遍历,O(2n)
public static void colorClassify(int[] arr){
int n = arr.length;
int left = 0;
int right = 0;
for (;right<n;right++){
if (arr[right]==0){
int temp = arr[right];
arr[right] = arr[left];
arr[left] = temp;
left++;
}
}
for (right = left;right<n;right++){
if(arr[right]==1){
int temp = arr[right];
arr[right]=arr[left];
arr[left]=temp;
left++;
}
}
}
三指针
left左侧全为0
right右侧全为2
index进行遍历,将0和2与left和right进行交换。
//一次遍历,O(n)
public static void colorClassify02(int[] arr){
int n = arr.length;
int left = 0;
int right = n - 1;
int index = 0;
for (;index<n;index++){
if (index==right){
break;
}
if (arr[index]==0){
int temp = arr[index];
arr[index]=arr[left];
arr[left]=temp;
left++;
}else if (arr[index] == 2){
int temp = arr[right];
arr[right]=arr[index];
arr[index]=temp;
right--;
}
}
}