[leetCode]136.只出现一次的数字
暴力法
数组中依次取出每一个元素,将该元素和数组中所有元素进行比对,使用一个计数器进行计数,如果比对一遍后计数器为1则返回这个数字,否则清空计数器。
class Solution {
public int singleNumber(int[] nums) {
int count = 0;
for(int i = 0; i < nums.length; i++){
int curDigit = nums[i];
for(int j = 0; j < nums.length; j++){
if(nums[j] == curDigit){
++count;
}
}
if(count == 1) return curDigit;
else count = 0;
}
return 0;
}
}
双指针
先将数组排序然后两两比对
class Solution {
public int singleNumber(int[] nums) {
Arrays.sort(nums);
int i = 0;
while(i < nums.length - 1) {
for(int j = i+1; j < nums.length; j++){
if(nums[j] == nums[i]){
++j;
i = j;
}else{
return nums[i];
}
}
}
return nums[i];
}
}
下面看了别人的写法是将相同的数字交换到数组最前面,如果是单个数字则无法交换,则i指针指向的位置就是只出现一次的数字。由于要进行多次比较交换所以还是上面先排序再两两比对快。
class Solution {
public int singleNumber(int[] nums) {
int i = 0;
for (int j = 1; j < nums.length; j++) {
if (nums[i] == nums[j]) {
int temp = nums[j];
nums[j] = nums[i + 1];
nums[i + 1] = temp;
i = i + 2;
j = i;
}
}
return nums[i];
}
}
记录数字
遍历一次哈希表将数字与其对应出现的次数填入,再遍历一次找到次数为1的数字。
class Solution {
public int singleNumber(int[] nums) {
Map<Integer, Integer> map = new HashMap<>();
for(Integer num : nums){
Integer count = map.get(num);
count = count==null ? 1 : ++count;
map.put(num,count);
}
for(Integer num : nums){
if(map.get(num) == 1) return num;
}
return -1;
}
}
下面是对上述方法的改进,遍历数组如果集合中没有数字则加入集合,如果集合中已经存在这个数字则将该数字从集合删除,最后集合剩下的数字就是唯一出现过的数字。
class Solution {
public int singleNumber(int[] nums) {
HashSet set = new HashSet();
for(Integer num : nums){
if(!set.contains(num)) set.add(num);
else set.remove(num);
}
Iterator<Integer> it = set.iterator();
return it.next();
}
}
异或
用到了异或的性质,相同的数字异或为0,0和任何数字异或为该数字本身。妙啊🤙
class Solution {
public int singleNumber(int[] nums) {
for(int i = 1; i < nums.length; i++){
nums[0] ^= nums[i];
}
return nums[0];
}
}