文章目录
前言
心情难过,练习一道题
一、只出现一次的数字
题目:给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
摘要:非空、整数数组、某数字只出现一次、其余元素均出现两次、找出现一次的元素;
原思想:先将数组进行排序,然后前后比较,如果前后元素不相等,则返回前元素
原代码:
class Solution {
public int singleNumber(int[] nums) {
Arrays.sort(nums);
int n = nums.length;
int temp=0;
for (int i = 0; i < n - 1; i++) {
if (nums[i] != nums[i + 1]) {
temp=nums[i];
}
}
return temp;
}
}
问题:如果遇到的是最后一个元素才不重复,如11223,那么返回的是2不是3
新思想:
1.异或思想
-使用异或运算,将所有值进行异或
-异或运算,相异为真,相同为假,所以 a^ a= 0 ; 0^a = a
-因为异或运算 满足交换律 a ^ b ^ a = a b ^ a ^ b = b 所以数组经过异或运算,单独的值就剩下了
2.使用集合Set解决
我们遍历数组中的元素,然后在一个个添加到集合Set中,如果添加失败,说明以前添加过,就把他给移除掉。当我们把数组中的所有元素都遍历完的时候,集合Set中只会有一个元素,这个就是我们要求的值。
3.先排序再查找
遍历排序后的数组,遇到前后相同就直接跳过,进行下一次比较, 如果不相同,则当前元素就是只出现了一次的元素
对于思想1的新代码:
class Solution {
public int singleNumber(int[] nums) {
int reduce = 0;
for (int num : nums) {
reduce = reduce ^ num;
}
return reduce;
}
}
对于思想2的新代码:
public int singleNumber(int[] nums) {
Set<Integer> set = new HashSet<>();
for (int num : nums) {
if (!set.add(num)) {
//如果添加失败,说明这个值
//在集合Set中存在,我们要
//把他给移除掉
set.remove(num);
}
}
//最终集合Set中只有一个元素,我们直接返回
return (int) set.toArray()[0];
}
对于思想3的新代码:
class Solution {
public int singleNumber(int[] nums) {
Arrays.sort(nums);
for (int i = 0 ; i < nums.length ; i++) {
if ((i < nums.length - 1) && (nums[i] == nums[i + 1])) {
i++;
} else return nums[i];
}
return nums[nums.length - 1];
}
}
总结
1.数学思想要好好应用
2.问题考虑的不全面,数组有特殊性,比如比较时最后一个元素和第一个元素的处理