136.只出现一次的数字
位运算
异或运算
0^a = a
0 ^ a ^ a = 0
异或运算具有交换性
0 ^ a ^ b ^ a = 0 ^ a ^ a ^ b = 0 ^ b = b
换言之,起始用0去顺序异或所有元素,出现两次的值都会被异或为0,最终得到的值,即为只出现一次的值
public int singleNumber(int[] nums) {
int flag = 0;
for(int i : nums) {
flag ^= i;
}
return flag;
}
HashSet
public int singleNumber(int[] nums) {
Set<Integer> set = new HashSet<>();
for(int i : nums) {
if(!set.add(i)) {//添加失败,说明这是出现两次的元素
set.remove(i);//将之前添加的该值也删掉
}
}
//最终set中只剩下目标元素
//HashSet没有提供直接访问元素的方法
//set.toArray(new Integer[set.size()])将HashSet中的元素复制到一个新的Integer数组中
return set.toArray(new Integer[set.size()])[0];
}
75.颜色分类
傻方法
我有一个很吊诡的想法,只有三个元素0,1,2,我可以建立一个数组存储三个元素的个数,然后遍历数组记录个数,接着直接按顺序填入。
public void sortColors(int[] nums) {
int[] count = new int[3];
for(int i : nums) {
count[i]++;
}
int index = 0;
for(int i = 0; i < 3; i++) {
for(int j = 0; j < count[i]; j++) {
nums[index++] = i;
}
}
}
冒泡排序
这题本质是一个排序问题,0,1,2的排序问题,大概就是一个冒泡
但是这里的时间复杂度要高于上面的代码
public void sortColors(int[] nums) {
int slow = 0, fast = 0;
while(slow < nums.length) {
fast++;
//从fast开始寻找比nums[slow]更小的元素
//slow之前就应该是已经排序好的数组
while(fast < nums.length) {
if(nums[fast] < nums[slow]) {//如果查到的元素比nums[slow]小,则交换
int temp = nums[fast];
nums[fast] = nums[slow];
nums[slow] = temp;
}
fast++;
}
slow++;
fast = slow;
}
}
后面有三指针的方法,可以只遍历一次数组