From 5620e2b49adfd88ef06df9d82a80a4b9219fe31e Mon Sep 17 00:00:00 2001 From: ShusenTang Date: Tue, 29 Oct 2019 14:29:29 +0800 Subject: [PATCH] Create 260. Single Number III.md --- solutions/260. Single Number III.md | 30 +++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 solutions/260. Single Number III.md diff --git a/solutions/260. Single Number III.md b/solutions/260. Single Number III.md new file mode 100644 index 0000000..df5f437 --- /dev/null +++ b/solutions/260. Single Number III.md @@ -0,0 +1,30 @@ +# 思路 +这道题是之前 [136 Single Number](https://github.com/ShusenTang/LeetCode/blob/master/solutions/136.%20Single%20Number.md) 和 +[137 Single Number II](https://github.com/ShusenTang/LeetCode/blob/master/solutions/137.%20Single%20Number%20II.md)的再次拓展, +依然是用位操作解决. + +这题和136唯一不同就是此题有两个出现了一次的数, 所以我们按照136题类似的遍历一遍数组然后得到所有数字异或结果是 +待求两个数(设为res1和res2)的异或结果`res1^res2`, 所以我们不能直接这样做. 既然同时存在两个只出现过一次的数, 那么如果我们将数组分成两部分且 +这两部分数组分别包含了res1和res2, 然后再采用136完全一样的思路不就解决了吗. + +所以问题转换成如何将数组分成两个部分且这两部分分别包含res1和res2. 还是利用位操作, 我们可以根据res1和res2不同的某一位来划分数组, +例如若二者第3位分别为0和1, 那么我们就根据"第三位为0还是为1"来划分数组. 我们不妨取二者不同位的最低(即最右)的那位, 即二者异或结果`res1^res2` +最低位的1. 设`res=res1^res2`, 那么`res&(-res)`即res最低位的1. + +# C++ +``` C++ +class Solution { +public: + vector singleNumber(vector& nums) { + int res = 0, res1 = 0, res2 = 0; + for(auto num: nums) res ^= num; + int mask = res & (-res); + for(auto num: nums){ + if(num & mask) res1 ^= num; + else res2 ^= num; + } + return vector{res1, res2}; + // return vector{res1, res1 ^ res}; + } +}; +```