1-
21## 题目地址
2+
33https://leetcode.com/problems/single-number/description/
44
55## 题目描述
@@ -11,22 +11,24 @@ Note:
1111
1212Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
1313```
14+
1415## 思路
1516
16- 根据题目描述,由于加上了时间复杂度必须是O (n),并且空间复杂度为O (1)的条件,因此不能用排序方法,也不能使用map数据结构 。
17+ 根据题目描述,由于加上了时间复杂度必须是 O (n),并且空间复杂度为 O (1)的条件,因此不能用排序方法,也不能使用 map 数据结构 。
1718
1819我们可以利用二进制异或的性质来完成,将所有数字异或即得到唯一出现的数字。
1920
2021## 关键点
22+
21231 . 异或的性质
22- 两个数字异或的结果` a^b ` 是将a和b的二进制每一位进行运算 ,得出的数字。 运算的逻辑是
23- 如果同一位的数字相同则为0,不同则为1
24+ 两个数字异或的结果` a^b ` 是将 a 和 b 的二进制每一位进行运算 ,得出的数字。 运算的逻辑是
25+ 如果同一位的数字相同则为 0,不同则为 1
2426
25272 . 异或的规律
2628
2729- 任何数和本身异或则为` 0 `
2830
29- - 任何数和0异或是 ` 本身 `
31+ - 任何数和 0 异或是 ` 本身 `
3032
31333 . 很多人只是记得异或的性质和规律,但是缺乏对其本质的理解,导致很难想到这种解法(我本人也没想到)
3234
@@ -48,52 +50,49 @@ Your algorithm should have a linear runtime complexity. Could you implement it w
4850 *
4951 * Given a non-empty array of integers, every element appears twice except for
5052 * one. Find that single one.
51- *
53+ *
5254 * Note:
53- *
55+ *
5456 * Your algorithm should have a linear runtime complexity. Could you implement
5557 * it without using extra memory?
56- *
58+ *
5759 * Example 1:
58- *
59- *
60+ *
61+ *
6062 * Input: [2,2,1]
6163 * Output: 1
62- *
63- *
64+ *
65+ *
6466 * Example 2:
65- *
66- *
67+ *
68+ *
6769 * Input: [4,1,2,1,2]
6870 * Output: 4
69- *
70- *
71+ *
72+ *
7173 */
7274/**
7375 * @param {number[]} nums
7476 * @return {number}
7577 */
7678var singleNumber = function (nums ) {
77- let ret = 0 ;
78- for (let index = 0 ; index < nums .length ; index++ ) {
79- const element = nums[index];
80- ret = ret ^ element;
81-
82- }
83- return ret;
79+ let ret = 0 ;
80+ for (let index = 0 ; index < nums .length ; index++ ) {
81+ const element = nums[index];
82+ ret = ret ^ element;
83+ }
84+ return ret;
8485};
85-
8686```
8787
8888## 延伸
8989
9090有一个 n 个元素的数组,除了两个数只出现一次外,其余元素都出现两次,让你找出这两个只出现一次的数分别是几,要求时间复杂度为 O(n) 且再开辟的内存空间固定(与 n 无关)。
9191
92-
9392和上面一样,只是这次不是一个数字,而是两个数字。还是按照上面的思路,我们进行一次全员异或操作,
9493得到的结果就是那两个只出现一次的不同的数字的异或结果。
9594
96- 我们刚才讲了异或的规律中有一个` 任何数和本身异或则为0 ` , 因此我们的思路是能不能将这两个不同的数字分成两组A和B 。
95+ 我们刚才讲了异或的规律中有一个` 任何数和本身异或则为0 ` , 因此我们的思路是能不能将这两个不同的数字分成两组 A 和 B 。
9796分组需要满足两个条件.
9897
99981 . 两个独特的的数字分成不同组
@@ -104,12 +103,10 @@ var singleNumber = function(nums) {
104103
105104问题的关键点是我们怎么进行分组呢?
106105
107- 由于异或的性质是,同一位相同则为0,不同则为1. 我们将所有数字异或的结果一定不是0,也就是说至少有一位是1 .
106+ 由于异或的性质是,同一位相同则为 0,不同则为 1. 我们将所有数字异或的结果一定不是 0,也就是说至少有一位是 1 .
108107
109- 我们随便取一个, 分组的依据就来了, 就是你取的那一位是0分成1组,那一位是1的分成一组 。
110- 这样肯定能保证` 2. 相同的数字分成相同组 ` , 不同的数字会被分成不同组么。 很明显当然可以, 因此我们选择是1 ,也就是
108+ 我们随便取一个, 分组的依据就来了, 就是你取的那一位是 0 分成 1 组,那一位是 1 的分成一组 。
109+ 这样肯定能保证` 2. 相同的数字分成相同组 ` , 不同的数字会被分成不同组么。 很明显当然可以, 因此我们选择是 1 ,也就是
111110说` 两个独特的的数字 ` 在那一位一定是不同的,因此两个独特元素一定会被分成不同组。
112111
113112Done!
114-
115-
0 commit comments