【leetcode】位运算-只出现一次的数字

题目:
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 1:

输入: [2,2,1]
输出: 1

示例 2:

输入: [4,1,2,1,2]
输出: 4


思路一:
使用异或位运算
1.a⊕a=0
2.a⊕0=a
3.a⊕b⊕a=b⊕a⊕a=b⊕(a⊕a)=b⊕0=b

假设数组为1,1,2,2,3,4,4,5,5
1与0分别进行异或,即0与1异或为1,1与1异或为0
2与0分别进行异或,即0与2异或为2,2与2异或为0
3与0进行异或,即0与3进行异或为3

或者是1与1,2与2等分别进行异或均为0,0与3异或为3

class Solution {
    public int singleNumber(int[] nums) {
        int temp=0;
        for(int num:nums){
            temp^=num;

        }
        return temp;
    }
}

不使用for each结构,用for循环,需要标出数组下标
使用for each的耗时为1ms,使用for循环的耗时为2ms

class Solution {
    public int singleNumber(int[] nums) {
        
        for(int i=1;i<nums.length;i++){
            nums[0]^=nums[i];
        }
        return nums[0];
    }
}

思路二:
如果使用额外的空间实现而不是线性
可以先排序在暴力遍历
此处需要从下标1开始,单独在for内部循环讨论为0的特殊情况
耗时8ms

       Arrays.sort(nums);
        for(int i=1; i<nums.length; i++) {
            if(i == 0 && nums[i] != nums[i+1] 
               || i == (nums.length-1) && nums[i] != nums[i-1] 
               || nums[i-1] != nums[i] && nums[i] != nums[i+1]) 
                return nums[i];
        }
        return nums[0];

或者使用另一种暴力遍历的条件
耗时9ms

class Solution {
    public int singleNumber(int[] nums) {
    Arrays.sort(nums);
    for(int i=0; i<nums.length-1; ) {
        if(  nums[i] != nums[i+1]) 
            return nums[i];  
        
        else i=i+2;
    }
        return nums[nums.length-1];
    }
}

思路三:
使用哈希表(=-=没想到 不太懂)

本身遍历nums的数组,其 value为nums 的值而不是下标
get(value)因为还是哈希表,还未添加,所以获取其下标元素的时候都是null
即判断是否为null,如果为null则赋值为1,如果不为null,也就是get(value)已经添加一些值上去,所以count++
最后一一添加进入map

之后通过KeySet进行遍历map的key值
最后判断key值中value是否为1就可以

class Solution {
    public int singleNumber(int[] nums) {
        Map<Integer, Integer> map = new HashMap<>();
        for (Integer value : nums) {
            Integer count = map.get(value);
            count = count == null ? 1 : ++count;
            map.put(value, count);
        }
        for (Integer key : map.keySet()) {
            Integer count = map.get(key);
            if (count == 1) {
                return key;
            }
        }
        return -1; // can't find it.
    }
}

或者是这种写法

class Solution {
    public int singleNumber(int[] nums) {
        Map<Integer, Integer> map = new HashMap<>();
        for (Integer i=0;i<nums.length;i++) {
            Integer value=map.get(nums[i]);
            if(value!=null)value++;
            else value=1;
            map.put(nums[i],value);
        }
        for (Integer key : map.keySet()) {
            if (map.get(key) == 1) {
                return key;
            }
        }
        return -1; // can't find it.
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农研究僧

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值