Leetcode刷题-190812-异或的性质

题目描述

题目地址: https://leetcode-cn.com/problems/single-number

原题说的是给一个数组,它具有其中只有一个元素是只出现1次,其他元素都出现2次的特点。我们需要找到那个只出现1次的元素。

思路与实现

常规HashMap

第一想法能想到我们用Map统计每个元素出现的次数,直接贴实现没什么需要说的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Solution {
public int singleNumber(int[] nums) {
Map<Integer, Integer> map = new HashMap<>();

for (int i : nums) {

if (map.containsKey(i)) {
int count = map.get(i);
count++;
map.put(i, count);
}
else {
map.put(i, 1);
}

}

for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
if (entry.getValue() == 1) {
return entry.getKey();
}
}

return 0;
}
}

但其实这并不是这道题真正要考察的点,翻了评论才知道这道题考位运算,于是赶紧博客记录下来学习一波。

利用异或的性质

异或运算 ^ 具有一下3个性质:

  • 交换律:$b$ ^ $a$ = $a$ ^ $b$
  • $n$ ^ $0$ = $n$
  • $n$ ^ $n$ = $0$

利用给的数组的特点,将每两个相同的元素利用交换律放在一起优先计算,再由于“相同元素异或为0“,成对的元素都变成了0,最后只剩下单个的那个元素即是我们需要的(本身异或0还是本身)。

实现也很简洁:

1
2
3
4
5
6
7
8
9
10
11
12
13

class Solution {

func singleNumber(_ nums: [Int]) -> Int {

var result:[Int] = 0

nums.map { res ^= $0 }

return result
}

}

小结

位运算一看就蒙…遇到就记录一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值