给定条件,找到数组中只出现一次的数字

给定条件,找到数组中只出现一次的数字

要求:
1.非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
2.算法具有线性时间复杂度。
3.不使用额外的空间。

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

- 方法一

要求中除了一个数出现了一次,其他数字都出现了2次。便可以考虑使用异或运算的特点来解决。

异或运算(^)是以二进制数据为基础进行运算的。
当代码中使用到异或运算时,都会先将两个数据进行转换,转换成二进制数据后,再进行运算。
异或中同位如果值相同(都是0或者都是1)则为0,不同(一个是0,一个是1)1。

其运算规律是:两个操作数的位中,相同则结果为0,不同则结果为1
a^a=0;自己和自己异或等于0
	
a^0=a;任何数字和0异或还等于他自己
	
a^b^c=a^c^b;异或运算具有交换律

另外,注意到一点,0与x异或都为x。我们便可以写出代码。

#Java
public int singleNumber(int nums[]) {
    int result = 0;
    for (int i = 0; i < nums.length; i++)
        result ^= nums[i];
    return result;
}

- 方法二(使用额外空间)

1.使用集合解决。
遍历数组中的元素,一个个添加到HashSet中,如果添加失败,说明以前添加过,就移除掉该元素。当我们把数组中的所有元素都遍历完的时候,HashSet中只会有一个元素,这个就是我们要求的值。

#Java
public int singleNumber(int[] nums) {
    Set<Integer> set = new HashSet<>();
    for (int num : nums) {
        if (!set.add(num)) {
            //添加失败,说明这个值在集合Set中存在,则移除
            set.remove(num);
        }
    }
    return (int) set.toArray()[0];
}

2.使用哈希表存储每个数字和该数字出现的次数。遍历数组即可得到每个数字出现的次数,并更新哈希表,最后遍历哈希表,得到只出现一次的数字。

#Java
 public int singleNumber(int[] nums) {
       Map<Integer, Integer> countMap = new HashMap<>();
       for(int num:nums){
           int count = countMap.getOrDefault(num, 0) + 1;
           countMap.put(num,count);
       }
       for(int num:nums){
           if(countMap.get(num)==1){
               return num;
           }
       }
       return 0;
    }

3.使用集合存储数组中出现的所有数字,并计算数组中的元素之和。由于集合保证元素无重复,因此计算集合中的所有元素之和的两倍,即为每个元素出现两次的情况下的元素之和。由于数组中只有一个元素出现一次,其余元素都出现两次,因此用集合中的元素之和的两倍减去数组中的元素之和,剩下的数就是数组中只出现一次的数字。

#python
  def singleNumber(self, nums: List[int]) -> int:
        result1 = 0
        for num in nums:
            result1+=num
        result2 = 0
        x = set(nums)
        for num in x:
            result2+=num
        return result2*2-result1

LeetCode 136

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

山风wind

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

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

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

打赏作者

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

抵扣说明:

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

余额充值