添加 problem 7、136、137、169、187、190、201、229、260

This commit is contained in:
YDZ
2019-07-07 10:39:35 +08:00
parent 7d0c085035
commit 777215785f
27 changed files with 990 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
package leetcode
func reverse_7(x int) int {
tmp := 0
for x != 0 {
tmp = tmp*10 + x%10
x = x / 10
}
if tmp > 1<<31-1 || tmp < -(1<<31) {
return 0
}
return tmp
}

View File

@@ -0,0 +1,57 @@
package leetcode
import (
"fmt"
"testing"
)
type question7 struct {
para7
ans7
}
// para 是参数
// one 代表第一个参数
type para7 struct {
one int
}
// ans 是答案
// one 代表第一个答案
type ans7 struct {
one int
}
func Test_Problem7(t *testing.T) {
qs := []question7{
question7{
para7{321},
ans7{123},
},
question7{
para7{-123},
ans7{-321},
},
question7{
para7{120},
ans7{21},
},
question7{
para7{1534236469},
ans7{0},
},
}
fmt.Printf("------------------------Leetcode Problem 7------------------------\n")
for _, q := range qs {
_, p := q.ans7, q.para7
fmt.Printf("【input】:%v 【output】:%v\n", p.one, reverse_7(p.one))
}
fmt.Printf("\n\n\n")
}

View File

@@ -0,0 +1,35 @@
# [7. Reverse Integer](https://leetcode.com/problems/reverse-integer/)
## 题目:
Given a 32-bit signed integer, reverse digits of an integer.
**Example 1:**
Input: 123
Output: 321
**Example 2:**
Input: -123
Output: -321
**Example 3:**
Input: 120
Output: 21
**Note:**Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [2^31, 2^31  1]. For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows.
## 题目大意
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。注意:假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [2^31,  2^31  1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
## 解题思路
- 这一题是简单题,要求反转 10 进制数。类似的题目有第 190 题。
- 这一题只需要注意一点,反转以后的数字要求在 [2^31, 2^31  1]范围内,超过这个范围的数字都要输出 0 。

View File

@@ -0,0 +1,9 @@
package leetcode
func singleNumber(nums []int) int {
result := 0
for i := 0; i < len(nums); i++ {
result ^= nums[i]
}
return result
}

View File

@@ -0,0 +1,47 @@
package leetcode
import (
"fmt"
"testing"
)
type question136 struct {
para136
ans136
}
// para 是参数
// one 代表第一个参数
type para136 struct {
s []int
}
// ans 是答案
// one 代表第一个答案
type ans136 struct {
one int
}
func Test_Problem136(t *testing.T) {
qs := []question136{
question136{
para136{[]int{2, 2, 1}},
ans136{1},
},
question136{
para136{[]int{4, 1, 2, 1, 2}},
ans136{4},
},
}
fmt.Printf("------------------------Leetcode Problem 136------------------------\n")
for _, q := range qs {
_, p := q.ans136, q.para136
fmt.Printf("【input】:%v 【output】:%v\n", p, singleNumber(p.s))
}
fmt.Printf("\n\n\n")
}

View File

@@ -0,0 +1,29 @@
# [136. Single Number](https://leetcode.com/problems/single-number/)
## 题目:
Given a **non-empty** array of integers, every element appears *twice* except for one. Find that single one.
**Note:**
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
**Example 1:**
Input: [2,2,1]
Output: 1
**Example 2:**
Input: [4,1,2,1,2]
Output: 4
## 题目大意
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。要求算法时间复杂度是线性的,并且不使用额外的辅助空间。
## 解题思路
- 题目要求不能使用辅助空间,并且时间复杂度只能是线性的。
- 题目为什么要强调有一个数字出现一次其他的出现两次我们想到了异或运算的性质任何一个数字异或它自己都等于0。也就是说如果我们从头到尾依次异或数组中的每一个数字那么最终的结果刚好是那个只出现依次的数字因为那些出现两次的数字全部在异或中抵消掉了。于是最终做法是从头到尾依次异或数组中的每一个数字那么最终得到的结果就是两个只出现一次的数字的异或结果。因为其他数字都出现了两次在异或中全部抵消掉了。**利用的性质是 x^x = 0**。

View File

@@ -0,0 +1,35 @@
package leetcode
func singleNumberII(nums []int) int {
ones, twos := 0, 0
for i := 0; i < len(nums); i++ {
ones = (ones ^ nums[i]) & ^twos
twos = (twos ^ nums[i]) & ^ones
}
return ones
}
// 以下是拓展题
// 在数组中每个元素都出现 5 次,找出只出现 1 次的数。
// 解法一
func singleNumberIIIII(nums []int) int {
na, nb, nc := 0, 0, 0
for i := 0; i < len(nums); i++ {
nb = nb ^ (nums[i] & na)
na = (na ^ nums[i]) & ^nc
nc = nc ^ (nums[i] & ^na & ^nb)
}
return na & ^nb & ^nc
}
// 解法二
func singleNumberIIIII_(nums []int) int {
twos, threes, ones := 0xffffffff, 0xffffffff, 0
for i := 0; i < len(nums); i++ {
threes = threes ^ (nums[i] & twos)
twos = (twos ^ nums[i]) & ^ones
ones = ones ^ (nums[i] & ^twos & ^threes)
}
return ones
}

View File

@@ -0,0 +1,47 @@
package leetcode
import (
"fmt"
"testing"
)
type question137 struct {
para137
ans137
}
// para 是参数
// one 代表第一个参数
type para137 struct {
s []int
}
// ans 是答案
// one 代表第一个答案
type ans137 struct {
one int
}
func Test_Problem137(t *testing.T) {
qs := []question137{
question137{
para137{[]int{2, 2, 3, 2}},
ans137{3},
},
question137{
para137{[]int{0, 1, 0, 1, 0, 1, 99}},
ans137{99},
},
}
fmt.Printf("------------------------Leetcode Problem 137------------------------\n")
for _, q := range qs {
_, p := q.ans137, q.para137
fmt.Printf("【input】:%v 【output】:%v\n", p, singleNumberII(p.s))
}
fmt.Printf("\n\n\n")
}

View File

@@ -0,0 +1,66 @@
# [137. Single Number II](https://leetcode.com/problems/single-number-ii/)
## 题目:
Given a **non-empty** array of integers, every element appears *three* times except for one, which appears exactly once. Find that single one.
**Note:**
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
**Example 1:**
Input: [2,2,3,2]
Output: 3
**Example 2:**
Input: [0,1,0,1,0,1,99]
Output: 99
## 题目大意
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。要求算法时间复杂度是线性的,并且不使用额外的辅助空间。
## 解题思路
- 这一题是第 136 题的加强版。这类题也可以扩展,在数组中每个元素都出现 5 次,找出只出现 1 次的数。
- 本题中要求找出只出现 1 次的数,出现 3 次的数都要被消除。第 136 题是消除出现 2 次的数。这一题也会相当相同的解法,出现 3 次的数也要被消除。定义状态00、10、01这 3 个状态。当一个数出现 3 次,那么它每个位置上的 1 出现的次数肯定是 3 的倍数,所以当 1 出现 3 次以后,就归零清除。如何能做到这点呢?仿造`三进制(001001)` 就可以做到。
- 变量 ones 中记录遍历中每个位上出现 1 的个数。将它与 A[i] 进行异或,目的是:
- 每位上两者都是 1 的,表示历史统计结果 ones 出现1次、A[i]中又出现1次则是出现 2 次,需要进位到 twos 变量中。
- 每位上两者分别为 0、1 的,加入到 ones 统计结果中。
- 最后还要 & ^twos ,是为了能做到三进制,出现 3 次就清零。例如 ones = x那么 twos = 0当 twos = x那么 ones = 0
- 变量 twos 中记录遍历中每个位上出现 1 2次 的个数。与 A[i] 进行异或的目的和上述描述相同,不再赘述。
> 在 golang 中,&^ 表示 AND NOT 的意思。这里的 ^ 作为一元操作符,表示按位取反 (^0001 0100 = 1110 1011)X &^ Y 的意思是将 X 中与 Y 相异的位保留,相同的位清零。
> 在 golang 中没有 Java 中的 ~ 位操作运算符Java 中的 ~ 运算符代表按位取反。这个操作就想当于 golang 中的 ^ 运算符当做一元运算符使用的效果。
这一题还可以继续扩展,在数组中每个元素都出现 5 次,找出只出现 1 次的数。那该怎么做呢思路还是一样的模拟一个五进制5 次就会消除。代码如下:
// 解法一
func singleNumberIII(nums []int) int {
na, nb, nc := 0, 0, 0
for i := 0; i < len(nums); i++ {
nb = nb ^ (nums[i] & na)
na = (na ^ nums[i]) & ^nc
nc = nc ^ (nums[i] & ^na & ^nb)
}
return na & ^nb & ^nc
}
// 解法二
func singleNumberIIII(nums []int) int {
twos, threes, ones := 0xffffffff, 0xffffffff, 0
for i := 0; i < len(nums); i++ {
threes = threes ^ (nums[i] & twos)
twos = (twos ^ nums[i]) & ^ones
ones = ones ^ (nums[i] & ^twos & ^threes)
}
return ones
}

View File

@@ -0,0 +1,30 @@
package leetcode
// 解法一 时间复杂度 O(n) 空间复杂度 O(1)
func majorityElement(nums []int) int {
res, count := nums[0], 0
for i := 0; i < len(nums); i++ {
if count == 0 {
res, count = nums[i], 1
} else {
if nums[i] == res {
count++
} else {
count--
}
}
}
return res
}
// 解法二 时间复杂度 O(n) 空间复杂度 O(n)
func majorityElement_(nums []int) int {
m := make(map[int]int)
for _, v := range nums {
m[v]++
if m[v] > len(nums)/2 {
return v
}
}
return 0
}

View File

@@ -0,0 +1,57 @@
package leetcode
import (
"fmt"
"testing"
)
type question169 struct {
para169
ans169
}
// para 是参数
// one 代表第一个参数
type para169 struct {
s []int
}
// ans 是答案
// one 代表第一个答案
type ans169 struct {
one int
}
func Test_Problem169(t *testing.T) {
qs := []question169{
question169{
para169{[]int{2, 2, 1}},
ans169{2},
},
question169{
para169{[]int{3, 2, 3}},
ans169{3},
},
question169{
para169{[]int{2, 2, 1, 1, 1, 2, 2}},
ans169{2},
},
question169{
para169{[]int{-2147483648}},
ans169{-2147483648},
},
}
fmt.Printf("------------------------Leetcode Problem 169------------------------\n")
for _, q := range qs {
_, p := q.ans169, q.para169
fmt.Printf("【input】:%v 【output】:%v\n", p, majorityElement(p.s))
}
fmt.Printf("\n\n\n")
}

View File

@@ -0,0 +1,28 @@
# [169. Majority Element](https://leetcode.com/problems/majority-element/)
## 题目:
Given an array of size n, find the majority element. The majority element is the element that appears **more than** `⌊ n/2 ⌋` times.
You may assume that the array is non-empty and the majority element always exist in the array.
**Example 1:**
Input: [3,2,3]
Output: 3
**Example 2:**
Input: [2,2,1,1,1,2,2]
Output: 2
## 题目大意
给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。你可以假设数组是非空的,并且给定的数组总是存在众数。
## 解题思路
- 题目要求找出数组中出现次数大于 `⌊ n/2 ⌋` 次的数。要求空间复杂度为 O(1)。简单题

View File

@@ -0,0 +1,39 @@
package leetcode
// 解法一
func findRepeatedDnaSequences(s string) []string {
if len(s) < 10 {
return nil
}
charMap, mp, result := map[uint8]uint32{'A': 0, 'C': 1, 'G': 2, 'T': 3}, make(map[uint32]int, 0), []string{}
var cur uint32
for i := 0; i < 9; i++ { // 前9位忽略
cur = cur<<2 | charMap[s[i]]
}
for i := 9; i < len(s); i++ {
cur = ((cur << 2) & 0xFFFFF) | charMap[s[i]]
if mp[cur] == 0 {
mp[cur] = 1
} else if mp[cur] == 1 { // >2重复
mp[cur] = 2
result = append(result, s[i-9:i+1])
}
}
return result
}
// 解法二
func findRepeatedDnaSequences_(s string) []string {
if len(s) < 10 {
return []string{}
}
ans, cache := make([]string, 0), make(map[string]int)
for i := 0; i <= len(s)-10; i++ {
curr := string(s[i : i+10])
if cache[curr] == 1 {
ans = append(ans, curr)
}
cache[curr] += 1
}
return ans
}

View File

@@ -0,0 +1,42 @@
package leetcode
import (
"fmt"
"testing"
)
type question187 struct {
para187
ans187
}
// para 是参数
// one 代表第一个参数
type para187 struct {
one string
}
// ans 是答案
// one 代表第一个答案
type ans187 struct {
one []string
}
func Test_Problem187(t *testing.T) {
qs := []question187{
question187{
para187{"AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"},
ans187{[]string{"AAAAACCCCC", "CCCCCAAAAA"}},
},
}
fmt.Printf("------------------------Leetcode Problem 187------------------------\n")
for _, q := range qs {
_, p := q.ans187, q.para187
fmt.Printf("【input】:%v 【output】:%v\n", p, findRepeatedDnaSequences(p.one))
}
fmt.Printf("\n\n\n")
}

View File

@@ -0,0 +1,24 @@
# [187. Repeated DNA Sequences](https://leetcode.com/problems/repeated-dna-sequences/)
## 题目:
All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACGAATTCCG". When studying DNA, it is sometimes useful to identify repeated sequences within the DNA.
Write a function to find all the 10-letter-long sequences (substrings) that occur more than once in a DNA molecule.
**Example:**
Input: s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"
Output: ["AAAAACCCCC", "CCCCCAAAAA"]
## 题目大意
所有 DNA 由一系列缩写为 ACG 和 T 的核苷酸组成例如“ACGAATTCCG”。在研究 DNA 时,识别 DNA 中的重复序列有时会对研究非常有帮助。编写一个函数来查找 DNA 分子中所有出现超多一次的10个字母长的序列子串
## 解题思路
- 这一题不用位运算比较好做,维护一个长度为 10 的字符串,在 map 中出现次数 > 1 就输出。
- 用位运算想做这一题,需要动态的维护长度为 10 的 hashkey先计算开头长度为 9 的 hash在往后面扫描的过程中如果长度超过了 10 ,就移除 hash 开头的一个字符,加入后面一个字符。具体做法是先将 ATCG 变成 00011011 的编码,那么长度为 10 hashkey 就需要维护在 20 位。mask = 0xFFFFF 就是 20 位的。维护了 hashkey 以后,根据这个 hashkey 进行去重和统计频次。

View File

@@ -0,0 +1,10 @@
package leetcode
func reverseBits(num uint32) uint32 {
var res uint32 = 0
for i := 0; i < 32; i++ {
res = res<<1 | num&1
num >>= 1
}
return res
}

View File

@@ -0,0 +1,47 @@
package leetcode
import (
"fmt"
"testing"
)
type question190 struct {
para190
ans190
}
// para 是参数
// one 代表第一个参数
type para190 struct {
one uint32
}
// ans 是答案
// one 代表第一个答案
type ans190 struct {
one uint32
}
func Test_Problem190(t *testing.T) {
qs := []question190{
question190{
para190{43261596},
ans190{964176192},
},
question190{
para190{4294967293},
ans190{3221225471},
},
}
fmt.Printf("------------------------Leetcode Problem 190------------------------\n")
for _, q := range qs {
_, p := q.ans190, q.para190
fmt.Printf("【input】:%v 【output】:%v\n", p, reverseBits(p.one))
}
fmt.Printf("\n\n\n")
}

View File

@@ -0,0 +1,35 @@
# [190. Reverse Bits](https://leetcode.com/problems/reverse-bits/)
## 题目:
Reverse bits of a given 32 bits unsigned integer.
**Example 1:**
Input: 00000010100101000001111010011100
Output: 00111001011110000010100101000000
Explanation: The input binary string 00000010100101000001111010011100 represents the unsigned integer 43261596, so return 964176192 which its binary representation is 00111001011110000010100101000000.
**Example 2:**
Input: 11111111111111111111111111111101
Output: 10111111111111111111111111111111
Explanation: The input binary string 11111111111111111111111111111101 represents the unsigned integer 4294967293, so return 3221225471 which its binary representation is 10101111110010110010011101101001.
**Note:**
- Note that in some languages such as Java, there is no unsigned integer type. In this case, both input and output will be given as signed integer type and should not affect your implementation, as the internal binary representation of the integer is the same whether it is signed or unsigned.
- In Java, the compiler represents the signed integers using [2's complement notation](https://en.wikipedia.org/wiki/Two%27s_complement). Therefore, in **Example 2** above the input represents the signed integer `-3` and the output represents the signed integer `-1073741825`.
## 题目大意
颠倒给定的 32 位无符号整数的二进制位。提示:
- 请注意,在某些语言(如 Java没有无符号整数类型。在这种情况下输入和输出都将被指定为有符号整数类型并且不应影响您的实现因为无论整数是有符号的还是无符号的其内部的二进制表示形式都是相同的。
- 在 Java 中,编译器使用二进制补码记法来表示有符号整数。因此,在上面的 示例 2 输入表示有符号整数 -3输出表示有符号整数 -1073741825。
## 解题思路
- 简单题,要求反转 32 位的二进制位。
- 把 num 往右移动,不断的消灭右边最低位的 1将这个 1 给 resres 不断的左移即可实现反转二进制位的目的。

View File

@@ -0,0 +1,23 @@
package leetcode
// 解法一
func rangeBitwiseAnd_(m int, n int) int {
if m == 0 {
return 0
}
moved := 0
for m != n {
m >>= 1
n >>= 1
moved++
}
return m << uint32(moved)
}
// 解法二 Brian Kernighan's algorithm
func rangeBitwiseAnd(m int, n int) int {
for n > m {
n &= (n - 1) // 清除最低位的 1
}
return n
}

View File

@@ -0,0 +1,48 @@
package leetcode
import (
"fmt"
"testing"
)
type question201 struct {
para201
ans201
}
// para 是参数
// one 代表第一个参数
type para201 struct {
m int
n int
}
// ans 是答案
// one 代表第一个答案
type ans201 struct {
one int
}
func Test_Problem201(t *testing.T) {
qs := []question201{
question201{
para201{5, 7},
ans201{4},
},
question201{
para201{0, 1},
ans201{0},
},
}
fmt.Printf("------------------------Leetcode Problem 201------------------------\n")
for _, q := range qs {
_, p := q.ans201, q.para201
fmt.Printf("【input】:%v 【output】:%v\n", p, rangeBitwiseAnd(p.m, p.n))
}
fmt.Printf("\n\n\n")
}

View File

@@ -0,0 +1,35 @@
# [201. Bitwise AND of Numbers Range](https://leetcode.com/problems/bitwise-and-of-numbers-range/)
## 题目:
Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers in this range, inclusive.
**Example 1:**
Input: [5,7]
Output: 4
**Example 2:**
Input: [0,1]
Output: 0
## 题目大意
给定范围 [m, n],其中 0 <= m <= n <= 2147483647返回此范围内所有数字的按位与包含 m, n 两端点)。
## 解题思路
- 这一题要求输出 [m,n] 区间内所有数的 AND 与操作之后的结果。
- 举个例子,假设区间是 [26,30],那么这个区间内的数用二进制表示出来为:
11010
11011
11100
11101
11110
- 可以观察到,把这些数都 AND 起来,只要有 0 的位,最终结果都是 0所以需要从右往前找到某一位上不为 0 的。不断的右移左边界和右边界,把右边的 0 都移走,直到它们俩相等,就找到了某一位上开始都不为 0 的了。在右移的过程中记录下右移了多少位,最后把 m 或者 n 的右边添上 0 即可。按照上面这个例子来看11000 是最终的结果。
- 这一题还有解法二,还是以 [26,30] 这个区间为例。这个区间内的数末尾 3 位不断的 01 变化着。那么如果把末尾的 1 都打掉,就是最终要求的结果了。当 n == m 或者 n < m 的时候就退出循环说明后面不同的位数已经都被抹平了1 都被打掉为 0 了。所以关键的操作为 `n &= (n - 1)` ,清除最低位的 1 。这个算法名叫 `Brian Kernighan` 算法。

View File

@@ -0,0 +1,64 @@
package leetcode
// 解法一 时间复杂度 O(n) 空间复杂度 O(1)
func majorityElement_229(nums []int) []int {
// since we are checking if a num appears more than 1/3 of the time
// it is only possible to have at most 2 nums (>1/3 + >1/3 = >2/3)
count1, count2, candidate1, candidate2 := 0, 0, 0, 1
// Select Candidates
for _, num := range nums {
if num == candidate1 {
count1++
} else if num == candidate2 {
count2++
} else if count1 <= 0 {
// We have a bad first candidate, replace!
candidate1, count1 = num, 1
} else if count2 <= 0 {
// We have a bad second candidate, replace!
candidate2, count2 = num, 1
} else {
// Both candidates suck, boo!
count1--
count2--
}
}
// Recount!
count1, count2 = 0, 0
for _, num := range nums {
if num == candidate1 {
count1++
} else if num == candidate2 {
count2++
}
}
length := len(nums)
if count1 > length/3 && count2 > length/3 {
return []int{candidate1, candidate2}
}
if count1 > length/3 {
return []int{candidate1}
}
if count2 > length/3 {
return []int{candidate2}
}
return []int{}
}
// 解法二 时间复杂度 O(n) 空间复杂度 O(n)
func majorityElement_229_(nums []int) []int {
result, m := make([]int, 0), make(map[int]int)
for _, val := range nums {
if v, ok := m[val]; ok {
m[val] = v + 1
} else {
m[val] = 1
}
}
for k, v := range m {
if v > len(nums)/3 {
result = append(result, k)
}
}
return result
}

View File

@@ -0,0 +1,47 @@
package leetcode
import (
"fmt"
"testing"
)
type question229 struct {
para229
ans229
}
// para 是参数
// one 代表第一个参数
type para229 struct {
s []int
}
// ans 是答案
// one 代表第一个答案
type ans229 struct {
one []int
}
func Test_Problem229(t *testing.T) {
qs := []question229{
question229{
para229{[]int{3, 2, 3}},
ans229{[]int{3}},
},
question229{
para229{[]int{1, 1, 1, 3, 3, 2, 2, 2}},
ans229{[]int{1, 2}},
},
}
fmt.Printf("------------------------Leetcode Problem 229------------------------\n")
for _, q := range qs {
_, p := q.ans229, q.para229
fmt.Printf("【input】:%v 【output】:%v\n", p, majorityElement_229(p.s))
}
fmt.Printf("\n\n\n")
}

View File

@@ -0,0 +1,28 @@
# [229. Majority Element II](https://leetcode.com/problems/majority-element-ii/)
## 题目:
Given an integer array of size n, find all elements that appear more than `⌊ n/3 ⌋` times.
**Note:** The algorithm should run in linear time and in O(1) space.
**Example 1:**
Input: [3,2,3]
Output: [3]
**Example 2:**
Input: [1,1,1,3,3,2,2,2]
Output: [1,2]
## 题目大意
给定一个大小为 n 的数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1)。
## 解题思路
- 这一题是第 169 题的加强版。
- 题目要求找出数组中出现次数大于 `⌊ n/3 ⌋` 次的数。要求空间复杂度为 O(1)。简单题。

View File

@@ -0,0 +1,19 @@
package leetcode
func singleNumberIII(nums []int) []int {
diff := 0
for _, num := range nums {
diff ^= num
}
// Get its last set bit (lsb)
diff &= -diff
res := []int{0, 0} // this array stores the two numbers we will return
for _, num := range nums {
if (num & diff) == 0 { // the bit is not set
res[0] ^= num
} else { // the bit is set
res[1] ^= num
}
}
return res
}

View File

@@ -0,0 +1,42 @@
package leetcode
import (
"fmt"
"testing"
)
type question260 struct {
para260
ans260
}
// para 是参数
// one 代表第一个参数
type para260 struct {
s []int
}
// ans 是答案
// one 代表第一个答案
type ans260 struct {
one []int
}
func Test_Problem260(t *testing.T) {
qs := []question260{
question260{
para260{[]int{1, 2, 1, 3, 2, 5}},
ans260{[]int{3, 5}},
},
}
fmt.Printf("------------------------Leetcode Problem 260------------------------\n")
for _, q := range qs {
_, p := q.ans260, q.para260
fmt.Printf("【input】:%v 【output】:%v\n", p, singleNumberIII(p.s))
}
fmt.Printf("\n\n\n")
}

View File

@@ -0,0 +1,34 @@
# [260. Single Number III](https://leetcode.com/problems/single-number-iii/)
## 题目:
Given an array of numbers `nums`, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.
**Example:**
Input: [1,2,1,3,2,5]
Output: [3,5]
**Note**:
1. The order of the result is not important. So in the above example, `[5, 3]` is also correct.
2. Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?
## 题目大意
给定一个整数数组 nums其中恰好有两个元素只出现一次其余所有元素均出现两次。 找出只出现一次的那两个元素。
注意:
- 结果输出的顺序并不重要,对于上面的例子,[5, 3] 也是正确答案。
- 要求算法时间复杂度是线性的,并且不使用额外的辅助空间。
## 解题思路
- 这一题是第 136 题的加强版。第 136 题里面只有一个数出现一次,其他数都出现 2 次。而这一次有 2 个数字出现一次,其他数出现 2 次。
- 解题思路还是利用异或,把出现 2 次的数先消除。最后我们要找的 2 个数肯定也是不同的,所以最后 2 个数对一个数进行异或,答案肯定是不同的。那么我们找哪个数为参照物呢?可以随便取,不如就取 lsb 最低位为 1 的数吧
- 于是整个数组会被分为 2 部分,异或 lsb 为 0 的和异或 lsb 为 1 的,在这 2 部分中,用异或操作把出现 2 次的数都消除,那么剩下的 2 个数分别就在这 2 部分中。