第一种:用Hash,我们先创建一个HashMap的key是元素的值,value是已经出现的次数,然后遍历数组来统计所有元素的出现次数,同时遍历哈希判断value是否超过一半的数字,
第二种:可以在遍历数组的时候设置两个初始值:一个是数组中的数result,另一个是出现的次数times,和第一种的思想有一点点联系,result初始值设为null,times设为0;
遍历数组,初始的时候,result=第一个元素,times=1,
当出现与result元素相同的元素,times+1;否认则times-1;
当times=0的时候,result等于下个位置元素,
例子:[1,2,1,3,1,4,1]和[2,1,2,3,1,4,1]两个序列
第一个:
1. result = 1, times = 1,
2.result !=2,times = 0,下一轮改变result = 1
3. result =1 times = 1,
4,result != 3 ,times= 0;下一轮改变result=1
5.result = 1 times = 1,
6.result !=4 times = 0, 下一轮,
7.result = 1,times = 1
返回最后result的值,第二种最后result仍然是1,大家可以自己尝试,
如过result在数组中出现超过一半,则随后times >=1 ,正好一半的时候,times=0,例如[1,2,1,3,1,4]最后结果是0,所以最后还是要检查一下,
代码:
public static int majorityRlement(int[] nums){
//count表示出现次数,result初始设置为null遍历到第一个元素,赋值
int count = 0;
Integer result = null;
for (int a:nums
) {
if (count == 0){
result = a;
}
count += (result == a)?1:-1;
}
return result;
}
题目:LeetCode136,
位运算也就是异或运算
0和其他数字异或还是那个数字,0和0异或还是0,因为只有一个元素出现一次所以异或最合适
public static int find(int[] arr){
int flag = 0;
for (int a:arr
) {
flag ^=a;
}
return flag;
}
第一种方法:我们使用两次遍历,第一次遍历将数字0交换到左边,第二次遍历将数字1交换到数字2的前面
第二种方法:
left指针表示所有左侧元素都是0;
right表示右侧元素都是2
index,从头到尾遍历数组,根据nums[index]是0还是2决定与左还是右交换
当index位置是1的时候,我们不需要交换,直接index++,后面出现0的话会被交互到左边,
index=right时候停止,index=2的时候right-- index不变,因为被交换到右边的是2,被交换到左边的不能确定,需要重新判断是0还是1再做交换,而index=0的时候被交换到左边的一定是0,left++无疑问,而index++如果index左边存在2会被交换到右边,
代码实现
public void colorswap(int[] nums){
int left = 0;int right = nums.length-1;
int index = 0;
while (index <=right){
if (index == 0){
swap(nums,index++,left++);
}else if (index == 2){
swap(nums,index,right--);
}else {
index++;
}
}
}
public void swap(int[] nums,int i,int j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}