mirror of
https://github.com/halfrost/LeetCode-Go.git
synced 2025-07-05 16:36:41 +08:00
更改包路径
This commit is contained in:
13
leetcode/0001. Two Sum/1. Two Sum.go
Normal file
13
leetcode/0001. Two Sum/1. Two Sum.go
Normal file
@ -0,0 +1,13 @@
|
||||
package leetcode
|
||||
|
||||
func twoSum(nums []int, target int) []int {
|
||||
m := make(map[int]int)
|
||||
for i := 0; i < len(nums); i++ {
|
||||
another := target - nums[i]
|
||||
if _, ok := m[another]; ok {
|
||||
return []int{m[another], i}
|
||||
}
|
||||
m[nums[i]] = i
|
||||
}
|
||||
return nil
|
||||
}
|
34
leetcode/0001. Two Sum/1. Two Sum_test.go
Normal file
34
leetcode/0001. Two Sum/1. Two Sum_test.go
Normal file
@ -0,0 +1,34 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestTwoSum(t *testing.T) {
|
||||
tests := [][]int{
|
||||
[]int{3, 2, 4},
|
||||
[]int{3, 2, 4},
|
||||
[]int{0, 8, 7, 3, 3, 4, 2},
|
||||
[]int{0, 1},
|
||||
}
|
||||
targets := []int{
|
||||
6,
|
||||
5,
|
||||
11,
|
||||
1,
|
||||
}
|
||||
results := [][]int{
|
||||
[]int{1, 2},
|
||||
[]int{0, 1},
|
||||
[]int{1, 3},
|
||||
[]int{0, 1},
|
||||
}
|
||||
fmt.Printf("------------------------Leetcode Problem 1------------------------\n")
|
||||
for i := 0; i < len(targets); i++ {
|
||||
fmt.Printf("nums = %v target = %v result = %v\n", tests[i], targets[i], twoSum(tests[i], targets[i]))
|
||||
if ret := twoSum(tests[i], targets[i]); ret[0] != results[i][0] && ret[1] != results[i][1] {
|
||||
t.Fatalf("case %d fails: %v\n", i, ret)
|
||||
}
|
||||
}
|
||||
}
|
28
leetcode/0001. Two Sum/README.md
Normal file
28
leetcode/0001. Two Sum/README.md
Normal file
@ -0,0 +1,28 @@
|
||||
# [1. Two Sum](https://leetcode.com/problems/two-sum/)
|
||||
|
||||
## 题目
|
||||
|
||||
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
|
||||
|
||||
You may assume that each input would have exactly one solution, and you may not use the same element twice.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
Given nums = [2, 7, 11, 15], target = 9,
|
||||
|
||||
Because nums[0] + nums[1] = 2 + 7 = 9,
|
||||
return [0, 1].
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 题目大意
|
||||
|
||||
在数组中找到 2 个数之和等于给定值的数字,结果返回 2 个数字在数组中的下标。
|
||||
|
||||
## 解题思路
|
||||
|
||||
这道题最优的做法时间复杂度是 O(n)。
|
||||
|
||||
顺序扫描数组,对每一个元素,在 map 中找能组合给定值的另一半数字,如果找到了,直接返回 2 个数字的下标即可。如果找不到,就把这个数字存入 map 中,等待扫到“另一半”数字的时候,再取出来返回结果。
|
43
leetcode/0002. Add Two Numbers/2. Add Two Numbers.go
Normal file
43
leetcode/0002. Add Two Numbers/2. Add Two Numbers.go
Normal file
@ -0,0 +1,43 @@
|
||||
package leetcode
|
||||
|
||||
/**
|
||||
* Definition for singly-linked list.
|
||||
* type ListNode struct {
|
||||
* Val int
|
||||
* Next *ListNode
|
||||
* }
|
||||
*/
|
||||
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
|
||||
if l1 == nil || l2 == nil {
|
||||
return nil
|
||||
}
|
||||
head := &ListNode{Val: 0, Next: nil}
|
||||
current := head
|
||||
carry := 0
|
||||
for l1 != nil || l2 != nil {
|
||||
var x, y int
|
||||
if l1 == nil {
|
||||
x = 0
|
||||
} else {
|
||||
x = l1.Val
|
||||
}
|
||||
if l2 == nil {
|
||||
y = 0
|
||||
} else {
|
||||
y = l2.Val
|
||||
}
|
||||
current.Next = &ListNode{Val: (x + y + carry) % 10, Next: nil}
|
||||
current = current.Next
|
||||
carry = (x + y + carry) / 10
|
||||
if l1 != nil {
|
||||
l1 = l1.Next
|
||||
}
|
||||
if l2 != nil {
|
||||
l2 = l2.Next
|
||||
}
|
||||
}
|
||||
if carry > 0 {
|
||||
current.Next = &ListNode{Val: carry % 10, Next: nil}
|
||||
}
|
||||
return head.Next
|
||||
}
|
79
leetcode/0002. Add Two Numbers/2. Add Two Numbers_test.go
Normal file
79
leetcode/0002. Add Two Numbers/2. Add Two Numbers_test.go
Normal file
@ -0,0 +1,79 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question2 struct {
|
||||
para2
|
||||
ans2
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para2 struct {
|
||||
one []int
|
||||
another []int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans2 struct {
|
||||
one []int
|
||||
}
|
||||
|
||||
func Test_Problem2(t *testing.T) {
|
||||
|
||||
qs := []question2{
|
||||
|
||||
question2{
|
||||
para2{[]int{}, []int{}},
|
||||
ans2{[]int{}},
|
||||
},
|
||||
|
||||
question2{
|
||||
para2{[]int{1}, []int{1}},
|
||||
ans2{[]int{2}},
|
||||
},
|
||||
|
||||
question2{
|
||||
para2{[]int{1, 2, 3, 4}, []int{1, 2, 3, 4}},
|
||||
ans2{[]int{2, 4, 6, 8}},
|
||||
},
|
||||
|
||||
question2{
|
||||
para2{[]int{1, 2, 3, 4, 5}, []int{1, 2, 3, 4, 5}},
|
||||
ans2{[]int{2, 4, 6, 8, 0, 1}},
|
||||
},
|
||||
|
||||
question2{
|
||||
para2{[]int{1}, []int{9, 9, 9, 9, 9}},
|
||||
ans2{[]int{0, 0, 0, 0, 0, 1}},
|
||||
},
|
||||
|
||||
question2{
|
||||
para2{[]int{9, 9, 9, 9, 9}, []int{1}},
|
||||
ans2{[]int{0, 0, 0, 0, 0, 1}},
|
||||
},
|
||||
|
||||
question2{
|
||||
para2{[]int{2, 4, 3}, []int{5, 6, 4}},
|
||||
ans2{[]int{7, 0, 8}},
|
||||
},
|
||||
|
||||
question2{
|
||||
para2{[]int{1, 8, 3}, []int{7, 1}},
|
||||
ans2{[]int{8, 9, 3}},
|
||||
},
|
||||
// 如需多个测试,可以复制上方元素。
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 2------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans2, q.para2
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, L2s(addTwoNumbers(S2l(p.one), S2l(p.another))))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
32
leetcode/0002. Add Two Numbers/README.md
Normal file
32
leetcode/0002. Add Two Numbers/README.md
Normal file
@ -0,0 +1,32 @@
|
||||
# [2. Add Two Numbers](https://leetcode.com/problems/add-two-numbers/)
|
||||
|
||||
## 题目
|
||||
|
||||
You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
|
||||
|
||||
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
|
||||
Output: 7 -> 0 -> 8
|
||||
```
|
||||
Explanation: 342 + 465 = 807.
|
||||
|
||||
|
||||
## 题目大意
|
||||
|
||||
2 个逆序的链表,要求从低位开始相加,得出结果也逆序输出,返回值是逆序结果链表的头结点。
|
||||
|
||||
## 解题思路
|
||||
|
||||
需要注意的是各种进位问题。
|
||||
|
||||
极端情况,例如
|
||||
```
|
||||
Input: (9 -> 9 -> 9 -> 9 -> 9) + (1 -> )
|
||||
Output: 0 -> 0 -> 0 -> 0 -> 0 -> 1
|
||||
```
|
||||
|
||||
为了处理方法统一,可以先建立一个虚拟头结点,这个虚拟头结点的 Next 指向真正的 head,这样 head 不需要单独处理,直接 while 循环即可。另外判断循环终止的条件不用是 p.Next != nil,这样最后一位还需要额外计算,循环终止条件应该是 p != nil。
|
@ -0,0 +1,22 @@
|
||||
package leetcode
|
||||
|
||||
func lengthOfLongestSubstring(s string) int {
|
||||
if len(s) == 0 {
|
||||
return 0
|
||||
}
|
||||
var freq [256]int
|
||||
result := 0
|
||||
left, right := 0, -1
|
||||
|
||||
for left < len(s) {
|
||||
if right+1 < len(s) && freq[s[right+1]-'a'] == 0 {
|
||||
freq[s[right+1]-'a']++
|
||||
right++
|
||||
} else {
|
||||
freq[s[left]-'a']--
|
||||
left++
|
||||
}
|
||||
result = max(result, right-left+1)
|
||||
}
|
||||
return result
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question3 struct {
|
||||
para3
|
||||
ans3
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para3 struct {
|
||||
s string
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans3 struct {
|
||||
one int
|
||||
}
|
||||
|
||||
func Test_Problem3(t *testing.T) {
|
||||
|
||||
qs := []question3{
|
||||
|
||||
question3{
|
||||
para3{"abcabcbb"},
|
||||
ans3{3},
|
||||
},
|
||||
|
||||
question3{
|
||||
para3{"bbbbb"},
|
||||
ans3{1},
|
||||
},
|
||||
|
||||
question3{
|
||||
para3{"pwwkew"},
|
||||
ans3{3},
|
||||
},
|
||||
|
||||
question3{
|
||||
para3{""},
|
||||
ans3{0},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 3------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans3, q.para3
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, lengthOfLongestSubstring(p.s))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
# [3. Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/)
|
||||
|
||||
## 题目
|
||||
|
||||
Given a string, find the length of the longest substring without repeating characters.
|
||||
|
||||
|
||||
|
||||
Example 1:
|
||||
|
||||
```c
|
||||
Input: "abcabcbb"
|
||||
Output: 3
|
||||
Explanation: The answer is "abc", with the length of 3.
|
||||
```
|
||||
|
||||
Example 2:
|
||||
|
||||
```c
|
||||
Input: "bbbbb"
|
||||
Output: 1
|
||||
Explanation: The answer is "b", with the length of 1.
|
||||
```
|
||||
|
||||
Example 3:
|
||||
|
||||
```c
|
||||
Input: "pwwkew"
|
||||
Output: 3
|
||||
Explanation: The answer is "wke", with the length of 3.
|
||||
Note that the answer must be a substring, "pwke" is a subsequence and not a substring.
|
||||
```
|
||||
|
||||
## 题目大意
|
||||
|
||||
|
||||
在一个字符串重寻找没有重复字母的最长子串。
|
||||
|
||||
## 解题思路
|
||||
|
||||
这一题和第 438 题,第 3 题,第 76 题,第 567 题类似,用的思想都是"滑动窗口"。
|
||||
|
||||
滑动窗口的右边界不断的右移,只要没有重复的字符,就不用的向右扩大窗口边界。一旦出现了重复字符,此时先计算一下滑动窗口的大小,记录下来。再需要缩小左边界。直到重复的字符移出了左边界。接着又可以开始移动滑动窗口的右边界。以此类推,不断的刷新记录的窗口大小。最终最大的值就是题目中的所求。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
13
leetcode/0007. Reverse Integer/7. Reverse Integer.go
Normal file
13
leetcode/0007. Reverse Integer/7. Reverse Integer.go
Normal file
@ -0,0 +1,13 @@
|
||||
package leetcode
|
||||
|
||||
func reverse7(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
|
||||
}
|
57
leetcode/0007. Reverse Integer/7. Reverse Integer_test.go
Normal file
57
leetcode/0007. Reverse Integer/7. Reverse Integer_test.go
Normal 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, reverse7(p.one))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
35
leetcode/0007. Reverse Integer/README.md
Executable file
35
leetcode/0007. Reverse Integer/README.md
Executable 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 。
|
@ -0,0 +1,22 @@
|
||||
package leetcode
|
||||
|
||||
func maxArea(height []int) int {
|
||||
max, start, end := 0, 0, len(height)-1
|
||||
for start < end {
|
||||
width := end - start
|
||||
high := 0
|
||||
if height[start] < height[end] {
|
||||
high = height[start]
|
||||
start++
|
||||
} else {
|
||||
high = height[end]
|
||||
end--
|
||||
}
|
||||
|
||||
temp := width * high
|
||||
if temp > max {
|
||||
max = temp
|
||||
}
|
||||
}
|
||||
return max
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question11 struct {
|
||||
para11
|
||||
ans11
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para11 struct {
|
||||
one []int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans11 struct {
|
||||
one int
|
||||
}
|
||||
|
||||
func Test_Problem11(t *testing.T) {
|
||||
|
||||
qs := []question11{
|
||||
|
||||
question11{
|
||||
para11{[]int{1, 8, 6, 2, 5, 4, 8, 3, 7}},
|
||||
ans11{49},
|
||||
},
|
||||
|
||||
question11{
|
||||
para11{[]int{1, 1}},
|
||||
ans11{1},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 11------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans11, q.para11
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p.one, maxArea(p.one))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
29
leetcode/0011. Container With Most Water/README.md
Normal file
29
leetcode/0011. Container With Most Water/README.md
Normal file
@ -0,0 +1,29 @@
|
||||
# [11. Container With Most Water](https://leetcode.com/problems/container-with-most-water/)
|
||||
|
||||
## 题目
|
||||
|
||||
Given n non-negative integers a1, a2, ..., an , where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
|
||||
|
||||
Note: You may not slant the container and n is at least 2.
|
||||
|
||||

|
||||
|
||||
The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49.
|
||||
|
||||
Example 1:
|
||||
|
||||
```c
|
||||
Input: [1,8,6,2,5,4,8,3,7]
|
||||
Output: 49
|
||||
```
|
||||
|
||||
|
||||
## 题目大意
|
||||
|
||||
给出一个非负整数数组 a1,a2,a3,…… an,每个整数标识一个竖立在坐标轴 x 位置的一堵高度为 ai 的墙,选择两堵墙,和 x 轴构成的容器可以容纳最多的水。
|
||||
|
||||
## 解题思路
|
||||
|
||||
|
||||
这一题也是对撞指针的思路。首尾分别 2 个指针,每次移动以后都分别判断长宽的乘积是否最大。
|
||||
|
38
leetcode/0015. 3Sum/15. 3Sum.go
Normal file
38
leetcode/0015. 3Sum/15. 3Sum.go
Normal file
@ -0,0 +1,38 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
func threeSum(nums []int) [][]int {
|
||||
res := [][]int{}
|
||||
counter := map[int]int{}
|
||||
for _, value := range nums {
|
||||
counter[value]++
|
||||
}
|
||||
|
||||
uniqNums := []int{}
|
||||
for key := range counter {
|
||||
uniqNums = append(uniqNums, key)
|
||||
}
|
||||
sort.Ints(uniqNums)
|
||||
|
||||
for i := 0; i < len(uniqNums); i++ {
|
||||
if (uniqNums[i]*3 == 0) && counter[uniqNums[i]] >= 3 {
|
||||
res = append(res, []int{uniqNums[i], uniqNums[i], uniqNums[i]})
|
||||
}
|
||||
for j := i + 1; j < len(uniqNums); j++ {
|
||||
if (uniqNums[i]*2+uniqNums[j] == 0) && counter[uniqNums[i]] > 1 {
|
||||
res = append(res, []int{uniqNums[i], uniqNums[i], uniqNums[j]})
|
||||
}
|
||||
if (uniqNums[j]*2+uniqNums[i] == 0) && counter[uniqNums[j]] > 1 {
|
||||
res = append(res, []int{uniqNums[i], uniqNums[j], uniqNums[j]})
|
||||
}
|
||||
c := 0 - uniqNums[i] - uniqNums[j]
|
||||
if c > uniqNums[j] && counter[c] > 0 {
|
||||
res = append(res, []int{uniqNums[i], uniqNums[j], c})
|
||||
}
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
59
leetcode/0015. 3Sum/15. 3Sum_test.go
Normal file
59
leetcode/0015. 3Sum/15. 3Sum_test.go
Normal file
@ -0,0 +1,59 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question15 struct {
|
||||
para15
|
||||
ans15
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para15 struct {
|
||||
a []int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans15 struct {
|
||||
one [][]int
|
||||
}
|
||||
|
||||
func Test_Problem15(t *testing.T) {
|
||||
|
||||
qs := []question15{
|
||||
|
||||
question15{
|
||||
para15{[]int{0, 0, 0}},
|
||||
ans15{[][]int{[]int{0, 0, 0}}},
|
||||
},
|
||||
|
||||
question15{
|
||||
para15{[]int{-1, 0, 1, 2, -1, -4}},
|
||||
ans15{[][]int{[]int{-1, 0, 1}, []int{-1, -1, 2}}},
|
||||
},
|
||||
|
||||
question15{
|
||||
para15{[]int{-4, -2, -2, -2, 0, 1, 2, 2, 2, 3, 3, 4, 4, 6, 6}},
|
||||
ans15{[][]int{[]int{-4, -2, 6}, []int{-4, 0, 4}, []int{-4, 1, 3}, []int{-4, 2, 2}, []int{-2, -2, 4}, []int{-2, 0, 2}}},
|
||||
},
|
||||
|
||||
question15{
|
||||
para15{[]int{5, -7, 3, -3, 5, -10, 4, 8, -3, -8, -3, -3, -1, -8, 6, 4, -4, 7, 2, -5, -2, -7, -3, 7, 2, 4, -6, 5}},
|
||||
ans15{[][]int{[]int{-10, 2, 8}, []int{-10, 3, 7}, []int{-10, 4, 6}, []int{-10, 5, 5}, []int{-8, 2, 6}, []int{-8, 3, 5}, []int{-8, 4, 4}, []int{-7, -1, 8},
|
||||
[]int{-7, 2, 5}, []int{-7, 3, 4}, []int{-6, -2, 8}, []int{-6, -1, 7}, []int{-6, 2, 4}, []int{-5, -3, 8}, []int{-5, -2, 7}, []int{-5, -1, 6}, []int{-5, 2, 3},
|
||||
[]int{-4, -3, 7}, []int{-4, -2, 6}, []int{-4, -1, 5}, []int{-4, 2, 2}, []int{-3, -3, 6}, []int{-3, -2, 5}, []int{-3, -1, 4}, []int{-2, -1, 3}}},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 15------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans15, q.para15
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, threeSum(p.a))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
36
leetcode/0015. 3Sum/README.md
Normal file
36
leetcode/0015. 3Sum/README.md
Normal file
@ -0,0 +1,36 @@
|
||||
# [15. 3Sum](https://leetcode.com/problems/3sum/)
|
||||
|
||||
## 题目
|
||||
|
||||
Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
|
||||
|
||||
Note:
|
||||
|
||||
The solution set must not contain duplicate triplets.
|
||||
|
||||
Example:
|
||||
|
||||
```c
|
||||
Given array nums = [-1, 0, 1, 2, -1, -4],
|
||||
|
||||
A solution set is:
|
||||
[
|
||||
[-1, 0, 1],
|
||||
[-1, -1, 2]
|
||||
]
|
||||
```
|
||||
|
||||
## 题目大意
|
||||
|
||||
给定一个数组,要求在这个数组中找出 3 个数之和为 0 的所有组合。
|
||||
|
||||
## 解题思路
|
||||
|
||||
用 map 提前计算好任意 2 个数字之和,保存起来,可以将时间复杂度降到 O(n^2)。这一题比较麻烦的一点在于,最后输出解的时候,要求输出不重复的解。数组中同一个数字可能出现多次,同一个数字也可能使用多次,但是最后输出解的时候,不能重复。例如 [-1,-1,2] 和 [2, -1, -1]、[-1, 2, -1] 这 3 个解是重复的,即使 -1 可能出现 100 次,每次使用的 -1 的数组下标都是不同的。
|
||||
|
||||
这里就需要去重和排序了。map 记录每个数字出现的次数,然后对 map 的 key 数组进行排序,最后在这个排序以后的数组里面扫,找到另外 2 个数字能和自己组成 0 的组合。
|
||||
|
||||
|
||||
|
||||
|
||||
|
53
leetcode/0016. 3Sum Closest/16. 3Sum Closest.go
Normal file
53
leetcode/0016. 3Sum Closest/16. 3Sum Closest.go
Normal file
@ -0,0 +1,53 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"math"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// 解法一 O(n^2)
|
||||
func threeSumClosest(nums []int, target int) int {
|
||||
n, res, diff := len(nums), 0, math.MaxInt32
|
||||
if n > 2 {
|
||||
sort.Ints(nums)
|
||||
for i := 0; i < n-2; i++ {
|
||||
for j, k := i+1, n-1; j < k; {
|
||||
sum := nums[i] + nums[j] + nums[k]
|
||||
if abs(sum-target) < diff {
|
||||
res, diff = sum, abs(sum-target)
|
||||
}
|
||||
if sum == target {
|
||||
return res
|
||||
} else if sum > target {
|
||||
k--
|
||||
} else {
|
||||
j++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// 解法二 暴力解法 O(n^3)
|
||||
func threeSumClosest1(nums []int, target int) int {
|
||||
res, difference := 0, math.MaxInt16
|
||||
for i := 0; i < len(nums); i++ {
|
||||
for j := i + 1; j < len(nums); j++ {
|
||||
for k := j + 1; k < len(nums); k++ {
|
||||
if abs(nums[i]+nums[j]+nums[k]-target) < difference {
|
||||
difference = abs(nums[i] + nums[j] + nums[k] - target)
|
||||
res = nums[i] + nums[j] + nums[k]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func abs(a int) int {
|
||||
if a > 0 {
|
||||
return a
|
||||
}
|
||||
return -a
|
||||
}
|
63
leetcode/0016. 3Sum Closest/16. 3Sum Closest_test.go
Normal file
63
leetcode/0016. 3Sum Closest/16. 3Sum Closest_test.go
Normal file
@ -0,0 +1,63 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question16 struct {
|
||||
para16
|
||||
ans16
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para16 struct {
|
||||
a []int
|
||||
target int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans16 struct {
|
||||
one int
|
||||
}
|
||||
|
||||
func Test_Problem16(t *testing.T) {
|
||||
|
||||
qs := []question16{
|
||||
|
||||
question16{
|
||||
para16{[]int{-1, 0, 1, 1, 55}, 3},
|
||||
ans16{2},
|
||||
},
|
||||
|
||||
question16{
|
||||
para16{[]int{0, 0, 0}, 1},
|
||||
ans16{0},
|
||||
},
|
||||
|
||||
question16{
|
||||
para16{[]int{-1, 2, 1, -4}, 1},
|
||||
ans16{2},
|
||||
},
|
||||
|
||||
question16{
|
||||
para16{[]int{1, 1, -1}, 0},
|
||||
ans16{1},
|
||||
},
|
||||
|
||||
question16{
|
||||
para16{[]int{-1, 2, 1, -4}, 1},
|
||||
ans16{2},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 16------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans16, q.para16
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, threeSumClosest(p.a, p.target))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
26
leetcode/0016. 3Sum Closest/README.md
Normal file
26
leetcode/0016. 3Sum Closest/README.md
Normal file
@ -0,0 +1,26 @@
|
||||
# [16. 3Sum Closest](https://leetcode.com/problems/3sum-closest/)
|
||||
|
||||
## 题目
|
||||
|
||||
Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. You may assume that each input would have exactly one solution.
|
||||
|
||||
Example:
|
||||
|
||||
```c
|
||||
Given array nums = [-1, 2, 1, -4], and target = 1.
|
||||
|
||||
The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
|
||||
```
|
||||
|
||||
## 题目大意
|
||||
|
||||
给定一个数组,要求在这个数组中找出 3 个数之和离 target 最近。
|
||||
|
||||
## 解题思路
|
||||
|
||||
这一题看似和第 15 题和第 18 题很像,都是求 3 或者 4 个数之和的问题,但是这一题的做法和 15,18 题完全不同。
|
||||
|
||||
这一题的解法是用两个指针夹逼的方法。先对数组进行排序,i 从头开始往后面扫。这里同样需要注意数组中存在多个重复数字的问题。具体处理方法很多,可以用 map 计数去重。这里笔者简单的处理,i 在循环的时候和前一个数进行比较,如果相等,i 继续往后移,直到移到下一个和前一个数字不同的位置。j,k 两个指针开始一前一后夹逼。j 为 i 的下一个数字,k 为数组最后一个数字,由于经过排序,所以 k 的数字最大。j 往后移动,k 往前移动,逐渐夹逼出最接近 target 的值。
|
||||
|
||||
|
||||
这道题还可以用暴力解法,三层循环找到距离 target 最近的组合。具体见代码。
|
@ -0,0 +1,39 @@
|
||||
package leetcode
|
||||
|
||||
var (
|
||||
letterMap = []string{
|
||||
" ", //0
|
||||
"", //1
|
||||
"abc", //2
|
||||
"def", //3
|
||||
"ghi", //4
|
||||
"jkl", //5
|
||||
"mno", //6
|
||||
"pqrs", //7
|
||||
"tuv", //8
|
||||
"wxyz", //9
|
||||
}
|
||||
res = []string{}
|
||||
)
|
||||
|
||||
func letterCombinations(digits string) []string {
|
||||
if digits == "" {
|
||||
return []string{}
|
||||
}
|
||||
res = []string{}
|
||||
findCombination(&digits, 0, "")
|
||||
return res
|
||||
}
|
||||
|
||||
func findCombination(digits *string, index int, s string) {
|
||||
if index == len(*digits) {
|
||||
res = append(res, s)
|
||||
return
|
||||
}
|
||||
num := (*digits)[index]
|
||||
letter := letterMap[num-'0']
|
||||
for i := 0; i < len(letter); i++ {
|
||||
findCombination(digits, index+1, s+string(letter[i]))
|
||||
}
|
||||
return
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question17 struct {
|
||||
para17
|
||||
ans17
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para17 struct {
|
||||
s string
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans17 struct {
|
||||
one []string
|
||||
}
|
||||
|
||||
func Test_Problem17(t *testing.T) {
|
||||
|
||||
qs := []question17{
|
||||
|
||||
question17{
|
||||
para17{"23"},
|
||||
ans17{[]string{"ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"}},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 17------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans17, q.para17
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, letterCombinations(p.s))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
30
leetcode/0017. Letter Combinations of a Phone Number/README.md
Executable file
30
leetcode/0017. Letter Combinations of a Phone Number/README.md
Executable file
@ -0,0 +1,30 @@
|
||||
# [17. Letter Combinations of a Phone Number](https://leetcode.com/problems/letter-combinations-of-a-phone-number/)
|
||||
|
||||
|
||||
## 题目:
|
||||
|
||||
Given a string containing digits from `2-9` inclusive, return all possible letter combinations that the number could represent.
|
||||
|
||||
A mapping of digit to letters (just like on the telephone buttons) is given below. Note that 1 does not map to any letters.
|
||||
|
||||

|
||||
|
||||
**Example:**
|
||||
|
||||
```c
|
||||
Input: "23"
|
||||
Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
|
||||
```
|
||||
|
||||
**Note:**
|
||||
|
||||
Although the above answer is in lexicographical order, your answer could be in any order you want.
|
||||
|
||||
## 题目大意
|
||||
|
||||
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
|
||||
|
||||
|
||||
## 解题思路
|
||||
|
||||
- DFS 递归深搜即可
|
50
leetcode/0018. 4Sum/18. 4Sum.go
Normal file
50
leetcode/0018. 4Sum/18. 4Sum.go
Normal file
@ -0,0 +1,50 @@
|
||||
package leetcode
|
||||
|
||||
import "sort"
|
||||
|
||||
func fourSum(nums []int, target int) [][]int {
|
||||
res := [][]int{}
|
||||
counter := map[int]int{}
|
||||
for _, value := range nums {
|
||||
counter[value]++
|
||||
}
|
||||
|
||||
uniqNums := []int{}
|
||||
for key := range counter {
|
||||
uniqNums = append(uniqNums, key)
|
||||
}
|
||||
sort.Ints(uniqNums)
|
||||
|
||||
for i := 0; i < len(uniqNums); i++ {
|
||||
if (uniqNums[i]*4 == target) && counter[uniqNums[i]] >= 4 {
|
||||
res = append(res, []int{uniqNums[i], uniqNums[i], uniqNums[i], uniqNums[i]})
|
||||
}
|
||||
for j := i + 1; j < len(uniqNums); j++ {
|
||||
if (uniqNums[i]*3+uniqNums[j] == target) && counter[uniqNums[i]] > 2 {
|
||||
res = append(res, []int{uniqNums[i], uniqNums[i], uniqNums[i], uniqNums[j]})
|
||||
}
|
||||
if (uniqNums[j]*3+uniqNums[i] == target) && counter[uniqNums[j]] > 2 {
|
||||
res = append(res, []int{uniqNums[i], uniqNums[j], uniqNums[j], uniqNums[j]})
|
||||
}
|
||||
if (uniqNums[j]*2+uniqNums[i]*2 == target) && counter[uniqNums[j]] > 1 && counter[uniqNums[i]] > 1 {
|
||||
res = append(res, []int{uniqNums[i], uniqNums[i], uniqNums[j], uniqNums[j]})
|
||||
}
|
||||
for k := j + 1; k < len(uniqNums); k++ {
|
||||
if (uniqNums[i]*2+uniqNums[j]+uniqNums[k] == target) && counter[uniqNums[i]] > 1 {
|
||||
res = append(res, []int{uniqNums[i], uniqNums[i], uniqNums[j], uniqNums[k]})
|
||||
}
|
||||
if (uniqNums[j]*2+uniqNums[i]+uniqNums[k] == target) && counter[uniqNums[j]] > 1 {
|
||||
res = append(res, []int{uniqNums[i], uniqNums[j], uniqNums[j], uniqNums[k]})
|
||||
}
|
||||
if (uniqNums[k]*2+uniqNums[i]+uniqNums[j] == target) && counter[uniqNums[k]] > 1 {
|
||||
res = append(res, []int{uniqNums[i], uniqNums[j], uniqNums[k], uniqNums[k]})
|
||||
}
|
||||
c := target - uniqNums[i] - uniqNums[j] - uniqNums[k]
|
||||
if c > uniqNums[k] && counter[c] > 0 {
|
||||
res = append(res, []int{uniqNums[i], uniqNums[j], uniqNums[k], c})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
63
leetcode/0018. 4Sum/18. 4Sum_test.go
Normal file
63
leetcode/0018. 4Sum/18. 4Sum_test.go
Normal file
@ -0,0 +1,63 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question18 struct {
|
||||
para18
|
||||
ans18
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para18 struct {
|
||||
a []int
|
||||
t int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans18 struct {
|
||||
one [][]int
|
||||
}
|
||||
|
||||
func Test_Problem18(t *testing.T) {
|
||||
|
||||
qs := []question18{
|
||||
|
||||
question18{
|
||||
para18{[]int{1, 1, 1, 1}, 4},
|
||||
ans18{[][]int{[]int{1, 1, 1, 1}}},
|
||||
},
|
||||
|
||||
question18{
|
||||
para18{[]int{0, 1, 5, 0, 1, 5, 5, -4}, 11},
|
||||
ans18{[][]int{[]int{-4, 5, 5, 5}, []int{0, 1, 5, 5}}},
|
||||
},
|
||||
|
||||
question18{
|
||||
para18{[]int{1, 0, -1, 0, -2, 2}, 0},
|
||||
ans18{[][]int{[]int{-1, 0, 0, 1}, []int{-2, -1, 1, 2}, []int{-2, 0, 0, 2}}},
|
||||
},
|
||||
|
||||
question18{
|
||||
para18{[]int{1, 0, -1, 0, -2, 2, 0, 0, 0, 0}, 0},
|
||||
ans18{[][]int{[]int{-1, 0, 0, 1}, []int{-2, -1, 1, 2}, []int{-2, 0, 0, 2}, []int{0, 0, 0, 0}}},
|
||||
},
|
||||
|
||||
question18{
|
||||
para18{[]int{1, 0, -1, 0, -2, 2, 0, 0, 0, 0}, 1},
|
||||
ans18{[][]int{[]int{-1, 0, 0, 1}, []int{-2, -1, 1, 2}, []int{-2, 0, 0, 2}, []int{0, 0, 0, 0}}},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 18------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans18, q.para18
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, fourSum(p.a, p.t))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
38
leetcode/0018. 4Sum/README.md
Normal file
38
leetcode/0018. 4Sum/README.md
Normal file
@ -0,0 +1,38 @@
|
||||
# [18. 4Sum](https://leetcode.com/problems/4sum/)
|
||||
|
||||
## 题目
|
||||
|
||||
Given an array nums of n integers and an integer target, are there elements a, b, c, and d in nums such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
|
||||
|
||||
Note:
|
||||
|
||||
The solution set must not contain duplicate quadruplets.
|
||||
|
||||
Example:
|
||||
|
||||
```c
|
||||
Given array nums = [1, 0, -1, 0, -2, 2], and target = 0.
|
||||
|
||||
A solution set is:
|
||||
[
|
||||
[-1, 0, 0, 1],
|
||||
[-2, -1, 1, 2],
|
||||
[-2, 0, 0, 2]
|
||||
]
|
||||
```
|
||||
|
||||
## 题目大意
|
||||
|
||||
给定一个数组,要求在这个数组中找出 4 个数之和为 0 的所有组合。
|
||||
|
||||
|
||||
## 解题思路
|
||||
|
||||
用 map 提前计算好任意 3 个数字之和,保存起来,可以将时间复杂度降到 O(n^3)。这一题比较麻烦的一点在于,最后输出解的时候,要求输出不重复的解。数组中同一个数字可能出现多次,同一个数字也可能使用多次,但是最后输出解的时候,不能重复。例如 [-1,1,2, -2] 和 [2, -1, -2, 1]、[-2, 2, -1, 1] 这 3 个解是重复的,即使 -1, -2 可能出现 100 次,每次使用的 -1, -2 的数组下标都是不同的。
|
||||
|
||||
这一题是第 15 题的升级版,思路都是完全一致的。这里就需要去重和排序了。map 记录每个数字出现的次数,然后对 map 的 key 数组进行排序,最后在这个排序以后的数组里面扫,找到另外 3 个数字能和自己组成 0 的组合。
|
||||
|
||||
第 15 题和第 18 题的解法一致。
|
||||
|
||||
|
||||
|
@ -0,0 +1,67 @@
|
||||
package leetcode
|
||||
|
||||
/**
|
||||
* Definition for singly-linked list.
|
||||
* type ListNode struct {
|
||||
* Val int
|
||||
* Next *ListNode
|
||||
* }
|
||||
*/
|
||||
|
||||
// 解法一
|
||||
func removeNthFromEnd(head *ListNode, n int) *ListNode {
|
||||
var fast, slow *ListNode
|
||||
fast = head
|
||||
slow = head
|
||||
for i := 0; i < n; i++ {
|
||||
fast = fast.Next
|
||||
}
|
||||
if fast == nil {
|
||||
head = head.Next
|
||||
return head
|
||||
}
|
||||
for fast.Next != nil {
|
||||
fast = fast.Next
|
||||
slow = slow.Next
|
||||
}
|
||||
slow.Next = slow.Next.Next
|
||||
return head
|
||||
}
|
||||
|
||||
// 解法二
|
||||
func removeNthFromEnd1(head *ListNode, n int) *ListNode {
|
||||
if head == nil {
|
||||
return nil
|
||||
}
|
||||
if n <= 0 {
|
||||
return head
|
||||
}
|
||||
current := head
|
||||
len := 0
|
||||
for current != nil {
|
||||
len++
|
||||
current = current.Next
|
||||
}
|
||||
if n > len {
|
||||
return head
|
||||
}
|
||||
if n == len {
|
||||
current := head
|
||||
head = head.Next
|
||||
current.Next = nil
|
||||
return head
|
||||
}
|
||||
current = head
|
||||
i := 0
|
||||
for current != nil {
|
||||
if i == len-n-1 {
|
||||
deleteNode := current.Next
|
||||
current.Next = current.Next.Next
|
||||
deleteNode.Next = nil
|
||||
break
|
||||
}
|
||||
i++
|
||||
current = current.Next
|
||||
}
|
||||
return head
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question19 struct {
|
||||
para19
|
||||
ans19
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para19 struct {
|
||||
one []int
|
||||
n int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans19 struct {
|
||||
one []int
|
||||
}
|
||||
|
||||
func Test_Problem19(t *testing.T) {
|
||||
|
||||
qs := []question19{
|
||||
|
||||
question19{
|
||||
para19{[]int{1, 2, 3, 4, 5}, 1},
|
||||
ans19{[]int{1, 2, 3, 4}},
|
||||
},
|
||||
|
||||
question19{
|
||||
para19{[]int{1, 2, 3, 4, 5}, 2},
|
||||
ans19{[]int{1, 2, 3, 5}},
|
||||
},
|
||||
|
||||
question19{
|
||||
para19{[]int{1, 2, 3, 4, 5}, 3},
|
||||
ans19{[]int{1, 2, 4, 5}},
|
||||
},
|
||||
question19{
|
||||
para19{[]int{1, 2, 3, 4, 5}, 4},
|
||||
ans19{[]int{1, 3, 4, 5}},
|
||||
},
|
||||
|
||||
question19{
|
||||
para19{[]int{1, 2, 3, 4, 5}, 5},
|
||||
ans19{[]int{2, 3, 4, 5}},
|
||||
},
|
||||
|
||||
question19{
|
||||
para19{[]int{1, 2, 3, 4, 5}, 0},
|
||||
ans19{[]int{1, 2, 3, 4, 5}},
|
||||
},
|
||||
|
||||
question19{
|
||||
para19{[]int{1, 2, 3, 4, 5}, 10},
|
||||
ans19{[]int{1, 2, 3, 4, 5}},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 19------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans19, q.para19
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, L2s(removeNthFromEnd(S2l(p.one), p.n)))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
23
leetcode/0019. Remove Nth Node From End of List/README.md
Normal file
23
leetcode/0019. Remove Nth Node From End of List/README.md
Normal file
@ -0,0 +1,23 @@
|
||||
# [19. Remove Nth Node From End of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/)
|
||||
|
||||
## 题目
|
||||
|
||||
Given a linked list, remove the n-th node from the end of list and return its head.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
Given linked list: 1->2->3->4->5, and n = 2.
|
||||
|
||||
After removing the second node from the end, the linked list becomes 1->2->3->5.
|
||||
```
|
||||
|
||||
## 题目大意
|
||||
|
||||
删除链表中倒数第 n 个结点。
|
||||
|
||||
## 解题思路
|
||||
|
||||
这道题比较简单,先循环一次拿到链表的总长度,然后循环到要删除的结点的前一个结点开始删除操作。需要注意的一个特例是,有可能要删除头结点,要单独处理。
|
||||
|
||||
这道题有一种特别简单的解法。设置 2 个指针,一个指针距离前一个指针 n 个距离。同时移动 2 个指针,2 个指针都移动相同的距离。当一个指针移动到了终点,那么前一个指针就是倒数第 n 个节点了。
|
21
leetcode/0020. Valid-Parentheses/20. Valid Parentheses.go
Normal file
21
leetcode/0020. Valid-Parentheses/20. Valid Parentheses.go
Normal file
@ -0,0 +1,21 @@
|
||||
package leetcode
|
||||
|
||||
func isValid(s string) bool {
|
||||
// 空字符串直接返回 true
|
||||
if len(s) == 0 {
|
||||
return true
|
||||
}
|
||||
stack := make([]rune, 0)
|
||||
for _, v := range s {
|
||||
if (v == '[') || (v == '(') || (v == '{') {
|
||||
stack = append(stack, v)
|
||||
} else if ((v == ']') && len(stack) > 0 && stack[len(stack)-1] == '[') ||
|
||||
((v == ')') && len(stack) > 0 && stack[len(stack)-1] == '(') ||
|
||||
((v == '}') && len(stack) > 0 && stack[len(stack)-1] == '{') {
|
||||
stack = stack[:len(stack)-1]
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return len(stack) == 0
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question20 struct {
|
||||
para20
|
||||
ans20
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para20 struct {
|
||||
one string
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans20 struct {
|
||||
one bool
|
||||
}
|
||||
|
||||
func Test_Problem20(t *testing.T) {
|
||||
|
||||
qs := []question20{
|
||||
|
||||
question20{
|
||||
para20{"()[]{}"},
|
||||
ans20{true},
|
||||
},
|
||||
question20{
|
||||
para20{"(]"},
|
||||
ans20{false},
|
||||
},
|
||||
question20{
|
||||
para20{"({[]})"},
|
||||
ans20{true},
|
||||
},
|
||||
question20{
|
||||
para20{"(){[({[]})]}"},
|
||||
ans20{true},
|
||||
},
|
||||
question20{
|
||||
para20{"((([[[{{{"},
|
||||
ans20{false},
|
||||
},
|
||||
question20{
|
||||
para20{"(())]]"},
|
||||
ans20{false},
|
||||
},
|
||||
question20{
|
||||
para20{""},
|
||||
ans20{true},
|
||||
},
|
||||
question20{
|
||||
para20{"["},
|
||||
ans20{false},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 20------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans20, q.para20
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, isValid(p.one))
|
||||
}
|
||||
}
|
59
leetcode/0020. Valid-Parentheses/README.md
Normal file
59
leetcode/0020. Valid-Parentheses/README.md
Normal file
@ -0,0 +1,59 @@
|
||||
# [20. Valid Parentheses](https://leetcode.com/problems/valid-parentheses/description/)
|
||||
|
||||
## 题目
|
||||
|
||||
Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.
|
||||
|
||||
An input string is valid if:
|
||||
|
||||
Open brackets must be closed by the same type of brackets.
|
||||
Open brackets must be closed in the correct order.
|
||||
Note that an empty string is also considered valid.
|
||||
|
||||
Example 1:
|
||||
|
||||
```
|
||||
Input: "()"
|
||||
Output: true
|
||||
|
||||
```
|
||||
|
||||
|
||||
Example 2:
|
||||
|
||||
```
|
||||
Input: "()[]{}"
|
||||
Output: true
|
||||
|
||||
```
|
||||
|
||||
Example 3:
|
||||
|
||||
```
|
||||
Input: "(]"
|
||||
Output: false
|
||||
```
|
||||
|
||||
Example 4:
|
||||
|
||||
```
|
||||
Input: "([)]"
|
||||
Output: false
|
||||
```
|
||||
|
||||
Example 5:
|
||||
|
||||
```
|
||||
Input: "{[]}"
|
||||
Output: true
|
||||
```
|
||||
|
||||
## 题目大意
|
||||
|
||||
括号匹配问题。
|
||||
|
||||
## 解题思路
|
||||
|
||||
遇到左括号就进栈push,遇到右括号并且栈顶为与之对应的左括号,就把栈顶元素出栈。最后看栈里面还有没有其他元素,如果为空,即匹配。
|
||||
|
||||
需要注意,空字符串是满足括号匹配的,即输出 true。
|
@ -0,0 +1,23 @@
|
||||
package leetcode
|
||||
|
||||
/**
|
||||
* Definition for singly-linked list.
|
||||
* type ListNode struct {
|
||||
* Val int
|
||||
* Next *ListNode
|
||||
* }
|
||||
*/
|
||||
func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
|
||||
if l1 == nil {
|
||||
return l2
|
||||
}
|
||||
if l2 == nil {
|
||||
return l1
|
||||
}
|
||||
if l1.Val < l2.Val {
|
||||
l1.Next = mergeTwoLists(l1.Next, l2)
|
||||
return l1
|
||||
}
|
||||
l2.Next = mergeTwoLists(l1, l2.Next)
|
||||
return l2
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question21 struct {
|
||||
para21
|
||||
ans21
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para21 struct {
|
||||
one []int
|
||||
another []int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans21 struct {
|
||||
one []int
|
||||
}
|
||||
|
||||
func Test_Problem21(t *testing.T) {
|
||||
|
||||
qs := []question21{
|
||||
|
||||
question21{
|
||||
para21{[]int{}, []int{}},
|
||||
ans21{[]int{}},
|
||||
},
|
||||
|
||||
question21{
|
||||
para21{[]int{1}, []int{1}},
|
||||
ans21{[]int{1, 1}},
|
||||
},
|
||||
|
||||
question21{
|
||||
para21{[]int{1, 2, 3, 4}, []int{1, 2, 3, 4}},
|
||||
ans21{[]int{1, 1, 2, 2, 3, 3, 4, 4}},
|
||||
},
|
||||
|
||||
question21{
|
||||
para21{[]int{1, 2, 3, 4, 5}, []int{1, 2, 3, 4, 5}},
|
||||
ans21{[]int{1, 1, 2, 2, 3, 3, 4, 4, 5, 5}},
|
||||
},
|
||||
|
||||
question21{
|
||||
para21{[]int{1}, []int{9, 9, 9, 9, 9}},
|
||||
ans21{[]int{1, 9, 9, 9, 9, 9}},
|
||||
},
|
||||
|
||||
question21{
|
||||
para21{[]int{9, 9, 9, 9, 9}, []int{1}},
|
||||
ans21{[]int{1, 9, 9, 9, 9, 9}},
|
||||
},
|
||||
|
||||
question21{
|
||||
para21{[]int{2, 3, 4}, []int{4, 5, 6}},
|
||||
ans21{[]int{2, 3, 4, 4, 5, 6}},
|
||||
},
|
||||
|
||||
question21{
|
||||
para21{[]int{1, 3, 8}, []int{1, 7}},
|
||||
ans21{[]int{1, 1, 3, 7, 8}},
|
||||
},
|
||||
// 如需多个测试,可以复制上方元素。
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 21------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans21, q.para21
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, L2s(mergeTwoLists(S2l(p.one), S2l(p.another))))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
21
leetcode/0021. Merge Two Sorted Lists/README.md
Normal file
21
leetcode/0021. Merge Two Sorted Lists/README.md
Normal file
@ -0,0 +1,21 @@
|
||||
# [21. Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists/)
|
||||
|
||||
## 题目
|
||||
|
||||
Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.
|
||||
|
||||
Example :
|
||||
|
||||
```
|
||||
Input: 1->2->4, 1->3->4
|
||||
Output: 1->1->2->3->4->4
|
||||
|
||||
```
|
||||
|
||||
## 题目大意
|
||||
|
||||
合并 2 个有序链表
|
||||
|
||||
## 解题思路
|
||||
|
||||
按照题意做即可。
|
@ -0,0 +1,23 @@
|
||||
package leetcode
|
||||
|
||||
func generateParenthesis(n int) []string {
|
||||
if n == 0 {
|
||||
return []string{}
|
||||
}
|
||||
res := []string{}
|
||||
findGenerateParenthesis(n, n, "", &res)
|
||||
return res
|
||||
}
|
||||
|
||||
func findGenerateParenthesis(lindex, rindex int, str string, res *[]string) {
|
||||
if lindex == 0 && rindex == 0 {
|
||||
*res = append(*res, str)
|
||||
return
|
||||
}
|
||||
if lindex > 0 {
|
||||
findGenerateParenthesis(lindex-1, rindex, str+"(", res)
|
||||
}
|
||||
if rindex > 0 && lindex < rindex {
|
||||
findGenerateParenthesis(lindex, rindex-1, str+")", res)
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question22 struct {
|
||||
para22
|
||||
ans22
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para22 struct {
|
||||
one int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans22 struct {
|
||||
one []string
|
||||
}
|
||||
|
||||
func Test_Problem22(t *testing.T) {
|
||||
|
||||
qs := []question22{
|
||||
|
||||
question22{
|
||||
para22{3},
|
||||
ans22{[]string{
|
||||
"((()))",
|
||||
"(()())",
|
||||
"(())()",
|
||||
"()(())",
|
||||
"()()()",
|
||||
}},
|
||||
},
|
||||
// 如需多个测试,可以复制上方元素。
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 22------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans22, q.para22
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, generateParenthesis(p.one))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
30
leetcode/0022. Generate Parentheses/README.md
Executable file
30
leetcode/0022. Generate Parentheses/README.md
Executable file
@ -0,0 +1,30 @@
|
||||
# [22. Generate Parentheses](https://leetcode.com/problems/generate-parentheses/)
|
||||
|
||||
|
||||
## 题目
|
||||
|
||||
Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
|
||||
|
||||
For example, given n = 3, a solution set is:
|
||||
|
||||
|
||||
[
|
||||
"((()))",
|
||||
"(()())",
|
||||
"(())()",
|
||||
"()(())",
|
||||
"()()()"
|
||||
]
|
||||
|
||||
|
||||
## 题目大意
|
||||
|
||||
给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。
|
||||
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 这道题乍一看需要判断括号是否匹配的问题,如果真的判断了,那时间复杂度就到 O(n * 2^n)了,虽然也可以 AC,但是时间复杂度巨高。
|
||||
- 这道题实际上不需要判断括号是否匹配的问题。因为在 DFS 回溯的过程中,会让 `(` 和 `)` 成对的匹配上的。
|
||||
|
||||
|
@ -0,0 +1,37 @@
|
||||
package leetcode
|
||||
|
||||
/**
|
||||
* Definition for singly-linked list.
|
||||
* type ListNode struct {
|
||||
* Val int
|
||||
* Next *ListNode
|
||||
* }
|
||||
*/
|
||||
func mergeKLists(lists []*ListNode) *ListNode {
|
||||
length := len(lists)
|
||||
if length < 1 {
|
||||
return nil
|
||||
}
|
||||
if length == 1 {
|
||||
return lists[0]
|
||||
}
|
||||
num := length / 2
|
||||
left := mergeKLists(lists[:num])
|
||||
right := mergeKLists(lists[num:])
|
||||
return mergeTwoLists1(left, right)
|
||||
}
|
||||
|
||||
func mergeTwoLists1(l1 *ListNode, l2 *ListNode) *ListNode {
|
||||
if l1 == nil {
|
||||
return l2
|
||||
}
|
||||
if l2 == nil {
|
||||
return l1
|
||||
}
|
||||
if l1.Val < l2.Val {
|
||||
l1.Next = mergeTwoLists1(l1.Next, l2)
|
||||
return l1
|
||||
}
|
||||
l2.Next = mergeTwoLists1(l1, l2.Next)
|
||||
return l2
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question23 struct {
|
||||
para23
|
||||
ans23
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para23 struct {
|
||||
one [][]int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans23 struct {
|
||||
one []int
|
||||
}
|
||||
|
||||
func Test_Problem23(t *testing.T) {
|
||||
|
||||
qs := []question23{
|
||||
|
||||
question23{
|
||||
para23{[][]int{}},
|
||||
ans23{[]int{}},
|
||||
},
|
||||
|
||||
question23{
|
||||
para23{[][]int{
|
||||
[]int{1},
|
||||
[]int{1},
|
||||
}},
|
||||
ans23{[]int{1, 1}},
|
||||
},
|
||||
|
||||
question23{
|
||||
para23{[][]int{
|
||||
[]int{1, 2, 3, 4},
|
||||
[]int{1, 2, 3, 4},
|
||||
}},
|
||||
ans23{[]int{1, 1, 2, 2, 3, 3, 4, 4}},
|
||||
},
|
||||
|
||||
question23{
|
||||
para23{[][]int{
|
||||
[]int{1, 2, 3, 4, 5},
|
||||
[]int{1, 2, 3, 4, 5},
|
||||
}},
|
||||
ans23{[]int{1, 1, 2, 2, 3, 3, 4, 4, 5, 5}},
|
||||
},
|
||||
|
||||
question23{
|
||||
para23{[][]int{
|
||||
[]int{1},
|
||||
[]int{9, 9, 9, 9, 9},
|
||||
}},
|
||||
ans23{[]int{1, 9, 9, 9, 9, 9}},
|
||||
},
|
||||
|
||||
question23{
|
||||
para23{[][]int{
|
||||
[]int{9, 9, 9, 9, 9},
|
||||
[]int{1},
|
||||
}},
|
||||
ans23{[]int{1, 9, 9, 9, 9, 9}},
|
||||
},
|
||||
|
||||
question23{
|
||||
para23{[][]int{
|
||||
[]int{2, 3, 4},
|
||||
[]int{4, 5, 6},
|
||||
}},
|
||||
ans23{[]int{2, 3, 4, 4, 5, 6}},
|
||||
},
|
||||
|
||||
question23{
|
||||
para23{[][]int{
|
||||
[]int{1, 3, 8},
|
||||
[]int{1, 7},
|
||||
}},
|
||||
ans23{[]int{1, 1, 3, 7, 8}},
|
||||
},
|
||||
// 如需多个测试,可以复制上方元素。
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 23------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
var ls []*ListNode
|
||||
for _, qq := range q.para23.one {
|
||||
ls = append(ls, S2l(qq))
|
||||
}
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", q.para23.one, L2s(mergeKLists(ls)))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
28
leetcode/0023. Merge k Sorted Lists/README.md
Normal file
28
leetcode/0023. Merge k Sorted Lists/README.md
Normal file
@ -0,0 +1,28 @@
|
||||
# [23. Merge k Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/)
|
||||
|
||||
## 题目
|
||||
|
||||
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
|
||||
|
||||
|
||||
|
||||
Example :
|
||||
|
||||
```
|
||||
Input:
|
||||
[
|
||||
1->4->5,
|
||||
1->3->4,
|
||||
2->6
|
||||
]
|
||||
Output: 1->1->2->3->4->4->5->6
|
||||
|
||||
```
|
||||
|
||||
## 题目大意
|
||||
|
||||
合并 K 个有序链表
|
||||
|
||||
## 解题思路
|
||||
|
||||
借助分治的思想,把 K 个有序链表两两合并即可。相当于是第 21 题的加强版。
|
@ -0,0 +1,38 @@
|
||||
package leetcode
|
||||
|
||||
/**
|
||||
* Definition for singly-linked list.
|
||||
* type ListNode struct {
|
||||
* Val int
|
||||
* Next *ListNode
|
||||
* }
|
||||
*/
|
||||
|
||||
func swapPairs(head *ListNode) *ListNode {
|
||||
if head == nil || head.Next == nil {
|
||||
return head
|
||||
}
|
||||
s := head.Next
|
||||
var behind *ListNode
|
||||
for head.Next != nil {
|
||||
headNext := head.Next
|
||||
if behind != nil && behind.Next != nil {
|
||||
behind.Next = headNext
|
||||
}
|
||||
var next *ListNode
|
||||
if head.Next.Next != nil {
|
||||
next = head.Next.Next
|
||||
}
|
||||
if head.Next.Next != nil {
|
||||
head.Next = next
|
||||
} else {
|
||||
head.Next = nil
|
||||
}
|
||||
headNext.Next = head
|
||||
behind = head
|
||||
if head.Next != nil {
|
||||
head = next
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question24 struct {
|
||||
para24
|
||||
ans24
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para24 struct {
|
||||
one []int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans24 struct {
|
||||
one []int
|
||||
}
|
||||
|
||||
func Test_Problem24(t *testing.T) {
|
||||
|
||||
qs := []question24{
|
||||
|
||||
question24{
|
||||
para24{[]int{}},
|
||||
ans24{[]int{}},
|
||||
},
|
||||
|
||||
question24{
|
||||
para24{[]int{1}},
|
||||
ans24{[]int{1}},
|
||||
},
|
||||
|
||||
question24{
|
||||
para24{[]int{1, 2, 3, 4}},
|
||||
ans24{[]int{2, 1, 4, 3}},
|
||||
},
|
||||
|
||||
question24{
|
||||
para24{[]int{1, 2, 3, 4, 5}},
|
||||
ans24{[]int{2, 1, 4, 3, 5}},
|
||||
},
|
||||
|
||||
// 如需多个测试,可以复制上方元素。
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 24------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans24, q.para24
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, L2s(swapPairs(S2l(p.one))))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
||||
|
||||
// convert *ListNode to []int
|
||||
func L2s(head *ListNode) []int {
|
||||
res := []int{}
|
||||
|
||||
for head != nil {
|
||||
res = append(res, head.Val)
|
||||
head = head.Next
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// convert []int to *ListNode
|
||||
func S2l(nums []int) *ListNode {
|
||||
if len(nums) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
res := &ListNode{
|
||||
Val: nums[0],
|
||||
}
|
||||
temp := res
|
||||
for i := 1; i < len(nums); i++ {
|
||||
temp.Next = &ListNode{
|
||||
Val: nums[i],
|
||||
}
|
||||
temp = temp.Next
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
23
leetcode/0024. Swap Nodes in Pairs/README.md
Normal file
23
leetcode/0024. Swap Nodes in Pairs/README.md
Normal file
@ -0,0 +1,23 @@
|
||||
# [24. Swap Nodes in Pairs](https://leetcode.com/problems/swap-nodes-in-pairs/description/)
|
||||
|
||||
## 题目
|
||||
|
||||
Given a linked list, swap every two adjacent nodes and return its head.
|
||||
|
||||
You may not modify the values in the list's nodes, only nodes itself may be changed.
|
||||
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
```c
|
||||
Given 1->2->3->4, you should return the list as 2->1->4->3.
|
||||
```
|
||||
|
||||
## 题目大意
|
||||
|
||||
两两相邻的元素,翻转链表
|
||||
|
||||
## 解题思路
|
||||
|
||||
按照题意做即可。
|
@ -0,0 +1,32 @@
|
||||
package leetcode
|
||||
|
||||
/**
|
||||
* Definition for singly-linked list.
|
||||
* type ListNode struct {
|
||||
* Val int
|
||||
* Next *ListNode
|
||||
* }
|
||||
*/
|
||||
func reverseKGroup(head *ListNode, k int) *ListNode {
|
||||
node := head
|
||||
for i := 0; i < k; i++ {
|
||||
if node == nil {
|
||||
return head
|
||||
}
|
||||
node = node.Next
|
||||
}
|
||||
newHead := reverse(head, node)
|
||||
head.Next = reverseKGroup(node, k)
|
||||
return newHead
|
||||
}
|
||||
|
||||
func reverse(first *ListNode, last *ListNode) *ListNode {
|
||||
prev := last
|
||||
for first != last {
|
||||
tmp := first.Next
|
||||
first.Next = prev
|
||||
prev = first
|
||||
first = tmp
|
||||
}
|
||||
return prev
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question25 struct {
|
||||
para25
|
||||
ans25
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para25 struct {
|
||||
one []int
|
||||
two int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans25 struct {
|
||||
one []int
|
||||
}
|
||||
|
||||
func Test_Problem25(t *testing.T) {
|
||||
|
||||
qs := []question25{
|
||||
|
||||
question25{
|
||||
para25{
|
||||
[]int{1, 2, 3, 4, 5},
|
||||
3,
|
||||
},
|
||||
ans25{[]int{3, 2, 1, 4, 5}},
|
||||
},
|
||||
|
||||
question25{
|
||||
para25{
|
||||
[]int{1, 2, 3, 4, 5},
|
||||
1,
|
||||
},
|
||||
ans25{[]int{1, 2, 3, 4, 5}},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 25------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans25, q.para25
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, L2s(reverseKGroup(S2l(p.one), p.two)))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
33
leetcode/0025. Reverse Nodes in k Group/README.md
Normal file
33
leetcode/0025. Reverse Nodes in k Group/README.md
Normal file
@ -0,0 +1,33 @@
|
||||
# [25. Reverse Nodes in k-Group](https://leetcode.com/problems/reverse-nodes-in-k-group/description/)
|
||||
|
||||
## 题目
|
||||
|
||||
Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.
|
||||
|
||||
k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.
|
||||
|
||||
Example:
|
||||
|
||||
```c
|
||||
Given this linked list: 1->2->3->4->5
|
||||
|
||||
For k = 2, you should return: 2->1->4->3->5
|
||||
|
||||
For k = 3, you should return: 3->2->1->4->5
|
||||
```
|
||||
|
||||
Note:
|
||||
|
||||
- Only constant extra memory is allowed.
|
||||
- You may not alter the values in the list's nodes, only nodes itself may be changed.
|
||||
|
||||
|
||||
## 题目大意
|
||||
|
||||
按照每 K 个元素翻转的方式翻转链表。如果不满足 K 个元素的就不翻转。
|
||||
|
||||
## 解题思路
|
||||
|
||||
|
||||
这一题是 problem 24 的加强版,problem 24 是两两相邻的元素,翻转链表。而 problem 25 要求的是 k 个相邻的元素,翻转链表,problem 相当于是 k = 2 的特殊情况。
|
||||
|
@ -0,0 +1,58 @@
|
||||
package leetcode
|
||||
|
||||
// 解法一
|
||||
func removeDuplicates(nums []int) int {
|
||||
if len(nums) == 0 {
|
||||
return 0
|
||||
}
|
||||
last, finder := 0, 0
|
||||
for last < len(nums)-1 {
|
||||
for nums[finder] == nums[last] {
|
||||
finder++
|
||||
if finder == len(nums) {
|
||||
return last + 1
|
||||
}
|
||||
}
|
||||
nums[last+1] = nums[finder]
|
||||
last++
|
||||
}
|
||||
return last + 1
|
||||
}
|
||||
|
||||
// 解法二
|
||||
func removeDuplicates1(nums []int) int {
|
||||
if len(nums) == 0 {
|
||||
return 0
|
||||
}
|
||||
length := len(nums)
|
||||
lastNum := nums[length-1]
|
||||
i := 0
|
||||
for i = 0; i < length-1; i++ {
|
||||
if nums[i] == lastNum {
|
||||
break
|
||||
}
|
||||
if nums[i+1] == nums[i] {
|
||||
removeElement1(nums, i+1, nums[i])
|
||||
// fmt.Printf("此时 num = %v length = %v\n", nums, length)
|
||||
}
|
||||
}
|
||||
return i + 1
|
||||
}
|
||||
|
||||
func removeElement1(nums []int, start, val int) int {
|
||||
if len(nums) == 0 {
|
||||
return 0
|
||||
}
|
||||
j := start
|
||||
for i := start; i < len(nums); i++ {
|
||||
if nums[i] != val {
|
||||
if i != j {
|
||||
nums[i], nums[j] = nums[j], nums[i]
|
||||
j++
|
||||
} else {
|
||||
j++
|
||||
}
|
||||
}
|
||||
}
|
||||
return j
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question26 struct {
|
||||
para26
|
||||
ans26
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para26 struct {
|
||||
one []int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans26 struct {
|
||||
one int
|
||||
}
|
||||
|
||||
func Test_Problem26(t *testing.T) {
|
||||
|
||||
qs := []question26{
|
||||
|
||||
question26{
|
||||
para26{[]int{1, 1, 2}},
|
||||
ans26{2},
|
||||
},
|
||||
|
||||
question26{
|
||||
para26{[]int{0, 0, 1, 1, 1, 1, 2, 3, 4, 4}},
|
||||
ans26{5},
|
||||
},
|
||||
|
||||
question26{
|
||||
para26{[]int{0, 0, 0, 0, 0}},
|
||||
ans26{1},
|
||||
},
|
||||
|
||||
question26{
|
||||
para26{[]int{1}},
|
||||
ans26{1},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 26------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans26, q.para26
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p.one, removeDuplicates(p.one))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
56
leetcode/0026. Remove Duplicates from Sorted Array/README.md
Normal file
56
leetcode/0026. Remove Duplicates from Sorted Array/README.md
Normal file
@ -0,0 +1,56 @@
|
||||
# [26. Remove Duplicates from Sorted Array](https://leetcode.com/problems/remove-duplicates-from-sorted-array/)
|
||||
|
||||
## 题目
|
||||
|
||||
Given a sorted array nums, remove the duplicates in-place such that each element appear only once and return the new length.
|
||||
|
||||
Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.
|
||||
|
||||
Example 1:
|
||||
|
||||
```c
|
||||
Given nums = [1,1,2],
|
||||
|
||||
Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively.
|
||||
|
||||
It doesn't matter what you leave beyond the returned length.
|
||||
```
|
||||
|
||||
Example 2:
|
||||
|
||||
```c
|
||||
Given nums = [0,0,1,1,1,2,2,3,3,4],
|
||||
|
||||
Your function should return length = 5, with the first five elements of nums being modified to 0, 1, 2, 3, and 4 respectively.
|
||||
|
||||
It doesn't matter what values are set beyond the returned length.
|
||||
```
|
||||
|
||||
Clarification:
|
||||
|
||||
Confused why the returned value is an integer but your answer is an array?
|
||||
|
||||
Note that the input array is passed in by reference, which means modification to the input array will be known to the caller as well.
|
||||
|
||||
Internally you can think of this:
|
||||
|
||||
```c
|
||||
// nums is passed in by reference. (i.e., without making a copy)
|
||||
int len = removeElement(nums, val);
|
||||
|
||||
// any modification to nums in your function would be known by the caller.
|
||||
// using the length returned by your function, it prints the first len elements.
|
||||
for (int i = 0; i < len; i++) {
|
||||
print(nums[i]);
|
||||
}
|
||||
```
|
||||
|
||||
## 题目大意
|
||||
|
||||
给定一个有序数组 nums,对数组中的元素进行去重,使得原数组中的每个元素只有一个。最后返回去重以后数组的长度值。
|
||||
|
||||
## 解题思路
|
||||
|
||||
这道题和第 27 题很像。这道题和第 283 题,第 27 题基本一致,283 题是删除 0,27 题是删除指定元素,这一题是删除重复元素,实质是一样的。
|
||||
|
||||
这里数组的删除并不是真的删除,只是将删除的元素移动到数组后面的空间内,然后返回数组实际剩余的元素个数,OJ 最终判断题目的时候会读取数组剩余个数的元素进行输出。
|
19
leetcode/0027. Remove Element/27. Remove Element.go
Normal file
19
leetcode/0027. Remove Element/27. Remove Element.go
Normal file
@ -0,0 +1,19 @@
|
||||
package leetcode
|
||||
|
||||
func removeElement(nums []int, val int) int {
|
||||
if len(nums) == 0 {
|
||||
return 0
|
||||
}
|
||||
j := 0
|
||||
for i := 0; i < len(nums); i++ {
|
||||
if nums[i] != val {
|
||||
if i != j {
|
||||
nums[i], nums[j] = nums[j], nums[i]
|
||||
j++
|
||||
} else {
|
||||
j++
|
||||
}
|
||||
}
|
||||
}
|
||||
return j
|
||||
}
|
68
leetcode/0027. Remove Element/27. Remove Element_test.go
Normal file
68
leetcode/0027. Remove Element/27. Remove Element_test.go
Normal file
@ -0,0 +1,68 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question27 struct {
|
||||
para27
|
||||
ans27
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para27 struct {
|
||||
one []int
|
||||
two int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans27 struct {
|
||||
one int
|
||||
}
|
||||
|
||||
func Test_Problem27(t *testing.T) {
|
||||
|
||||
qs := []question27{
|
||||
|
||||
question27{
|
||||
para27{[]int{1, 0, 1}, 1},
|
||||
ans27{1},
|
||||
},
|
||||
|
||||
question27{
|
||||
para27{[]int{0, 1, 0, 3, 0, 12}, 0},
|
||||
ans27{3},
|
||||
},
|
||||
|
||||
question27{
|
||||
para27{[]int{0, 1, 0, 3, 0, 0, 0, 0, 1, 12}, 0},
|
||||
ans27{4},
|
||||
},
|
||||
|
||||
question27{
|
||||
para27{[]int{0, 0, 0, 0, 0}, 0},
|
||||
ans27{0},
|
||||
},
|
||||
|
||||
question27{
|
||||
para27{[]int{1}, 1},
|
||||
ans27{0},
|
||||
},
|
||||
|
||||
question27{
|
||||
para27{[]int{0, 1, 2, 2, 3, 0, 4, 2}, 2},
|
||||
ans27{5},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 27------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans27, q.para27
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p.one, removeElement(p.one, p.two))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
60
leetcode/0027. Remove Element/README.md
Normal file
60
leetcode/0027. Remove Element/README.md
Normal file
@ -0,0 +1,60 @@
|
||||
# [27. Remove Element](https://leetcode.com/problems/remove-element/)
|
||||
|
||||
## 题目
|
||||
|
||||
Given an array nums and a value val, remove all instances of that value in-place and return the new length.
|
||||
|
||||
Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.
|
||||
|
||||
The order of elements can be changed. It doesn't matter what you leave beyond the new length.
|
||||
|
||||
Example 1:
|
||||
|
||||
```c
|
||||
Given nums = [3,2,2,3], val = 3,
|
||||
|
||||
Your function should return length = 2, with the first two elements of nums being 2.
|
||||
|
||||
It doesn't matter what you leave beyond the returned length.
|
||||
```
|
||||
|
||||
Example 2:
|
||||
|
||||
```c
|
||||
Given nums = [0,1,2,2,3,0,4,2], val = 2,
|
||||
|
||||
Your function should return length = 5, with the first five elements of nums containing 0, 1, 3, 0, and 4.
|
||||
|
||||
Note that the order of those five elements can be arbitrary.
|
||||
|
||||
It doesn't matter what values are set beyond the returned length.
|
||||
```
|
||||
|
||||
Clarification:
|
||||
|
||||
Confused why the returned value is an integer but your answer is an array?
|
||||
|
||||
Note that the input array is passed in by reference, which means modification to the input array will be known to the caller as well.
|
||||
|
||||
Internally you can think of this:
|
||||
|
||||
```c
|
||||
// nums is passed in by reference. (i.e., without making a copy)
|
||||
int len = removeElement(nums, val);
|
||||
|
||||
// any modification to nums in your function would be known by the caller.
|
||||
// using the length returned by your function, it prints the first len elements.
|
||||
for (int i = 0; i < len; i++) {
|
||||
print(nums[i]);
|
||||
}
|
||||
```
|
||||
|
||||
## 题目大意
|
||||
|
||||
给定一个数组 nums 和一个数值 val,将数组中所有等于 val 的元素删除,并返回剩余的元素个数。
|
||||
|
||||
## 解题思路
|
||||
|
||||
这道题和第 283 题很像。这道题和第 283 题基本一致,283 题是删除 0,这一题是给定的一个 val,实质是一样的。
|
||||
|
||||
这里数组的删除并不是真的删除,只是将删除的元素移动到数组后面的空间内,然后返回数组实际剩余的元素个数,OJ 最终判断题目的时候会读取数组剩余个数的元素进行输出。
|
25
leetcode/0028. Implement strStr()/28. Implement strStr().go
Normal file
25
leetcode/0028. Implement strStr()/28. Implement strStr().go
Normal file
@ -0,0 +1,25 @@
|
||||
package leetcode
|
||||
|
||||
import "strings"
|
||||
|
||||
// 解法一
|
||||
func strStr(haystack string, needle string) int {
|
||||
for i := 0; ; i++ {
|
||||
for j := 0; ; j++ {
|
||||
if j == len(needle) {
|
||||
return i
|
||||
}
|
||||
if i+j == len(haystack) {
|
||||
return -1
|
||||
}
|
||||
if needle[j] != haystack[i+j] {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 解法二
|
||||
func strStr1(haystack string, needle string) int {
|
||||
return strings.Index(haystack, needle)
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question28 struct {
|
||||
para28
|
||||
ans28
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para28 struct {
|
||||
s string
|
||||
p string
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans28 struct {
|
||||
one int
|
||||
}
|
||||
|
||||
func Test_Problem28(t *testing.T) {
|
||||
|
||||
qs := []question28{
|
||||
|
||||
question28{
|
||||
para28{"abab", "ab"},
|
||||
ans28{0},
|
||||
},
|
||||
|
||||
question28{
|
||||
para28{"hello", "ll"},
|
||||
ans28{2},
|
||||
},
|
||||
|
||||
question28{
|
||||
para28{"", "abc"},
|
||||
ans28{0},
|
||||
},
|
||||
|
||||
question28{
|
||||
para28{"abacbabc", "abc"},
|
||||
ans28{5},
|
||||
},
|
||||
|
||||
question28{
|
||||
para28{"abacbabc", "abcd"},
|
||||
ans28{-1},
|
||||
},
|
||||
|
||||
question28{
|
||||
para28{"abacbabc", ""},
|
||||
ans28{0},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 28------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans28, q.para28
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, strStr(p.s, p.p))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
50
leetcode/0028. Implement strStr()/README.md
Normal file
50
leetcode/0028. Implement strStr()/README.md
Normal file
@ -0,0 +1,50 @@
|
||||
# [28. Implement strStr()](https://leetcode.com/problems/implement-strstr/)
|
||||
|
||||
## 题目
|
||||
|
||||
Implement strStr().
|
||||
|
||||
Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
|
||||
|
||||
|
||||
Example 1:
|
||||
|
||||
```c
|
||||
Input: haystack = "hello", needle = "ll"
|
||||
Output: 2
|
||||
```
|
||||
|
||||
Example 2:
|
||||
|
||||
```c
|
||||
Input: haystack = "aaaaa", needle = "bba"
|
||||
Output: -1
|
||||
```
|
||||
|
||||
Clarification:
|
||||
|
||||
What should we return when needle is an empty string? This is a great question to ask during an interview.
|
||||
|
||||
For the purpose of this problem, we will return 0 when needle is an empty string. This is consistent to C's strstr() and Java's indexOf().
|
||||
|
||||
## 题目大意
|
||||
|
||||
|
||||
实现一个查找 substring 的函数。如果在母串中找到了子串,返回子串在母串中出现的下标,如果没有找到,返回 -1,如果子串是空串,则返回 0 。
|
||||
|
||||
## 解题思路
|
||||
|
||||
这一题比较简单,直接写即可。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,49 @@
|
||||
package leetcode
|
||||
|
||||
func findSubstring(s string, words []string) []int {
|
||||
if len(words) == 0 {
|
||||
return []int{}
|
||||
}
|
||||
res := []int{}
|
||||
counter := map[string]int{}
|
||||
for _, w := range words {
|
||||
counter[w]++
|
||||
}
|
||||
length, totalLen, tmpCounter := len(words[0]), len(words[0])*len(words), copyMap(counter)
|
||||
for i, start := 0, 0; i < len(s)-length+1 && start < len(s)-length+1; i++ {
|
||||
//fmt.Printf("sub = %v i = %v lenght = %v start = %v tmpCounter = %v totalLen = %v\n", s[i:i+length], i, length, start, tmpCounter, totalLen)
|
||||
if tmpCounter[s[i:i+length]] > 0 {
|
||||
tmpCounter[s[i:i+length]]--
|
||||
//fmt.Printf("******sub = %v i = %v lenght = %v start = %v tmpCounter = %v totalLen = %v\n", s[i:i+length], i, length, start, tmpCounter, totalLen)
|
||||
if checkWords(tmpCounter) && (i+length-start == totalLen) {
|
||||
res = append(res, start)
|
||||
continue
|
||||
}
|
||||
i = i + length - 1
|
||||
} else {
|
||||
start++
|
||||
i = start - 1
|
||||
tmpCounter = copyMap(counter)
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func checkWords(s map[string]int) bool {
|
||||
flag := true
|
||||
for _, v := range s {
|
||||
if v > 0 {
|
||||
flag = false
|
||||
break
|
||||
}
|
||||
}
|
||||
return flag
|
||||
}
|
||||
|
||||
func copyMap(s map[string]int) map[string]int {
|
||||
c := map[string]int{}
|
||||
for k, v := range s {
|
||||
c[k] = v
|
||||
}
|
||||
return c
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question30 struct {
|
||||
para30
|
||||
ans30
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para30 struct {
|
||||
one string
|
||||
two []string
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans30 struct {
|
||||
one []int
|
||||
}
|
||||
|
||||
func Test_Problem30(t *testing.T) {
|
||||
|
||||
qs := []question30{
|
||||
|
||||
question30{
|
||||
para30{"aaaaaaaa", []string{"aa", "aa", "aa"}},
|
||||
ans30{[]int{0, 1, 2}},
|
||||
},
|
||||
|
||||
question30{
|
||||
para30{"barfoothefoobarman", []string{"foo", "bar"}},
|
||||
ans30{[]int{0, 9}},
|
||||
},
|
||||
|
||||
question30{
|
||||
para30{"wordgoodgoodgoodbestword", []string{"word", "good", "best", "word"}},
|
||||
ans30{[]int{}},
|
||||
},
|
||||
|
||||
question30{
|
||||
para30{"goodgoodgoodgoodgood", []string{"good"}},
|
||||
ans30{[]int{0, 4, 8, 12, 16}},
|
||||
},
|
||||
|
||||
question30{
|
||||
para30{"barofoothefoolbarman", []string{"foo", "bar"}},
|
||||
ans30{[]int{}},
|
||||
},
|
||||
|
||||
question30{
|
||||
para30{"bbarffoothefoobarman", []string{"foo", "bar"}},
|
||||
ans30{[]int{}},
|
||||
},
|
||||
|
||||
question30{
|
||||
para30{"ooroodoofoodtoo", []string{"foo", "doo", "roo", "tee", "oo"}},
|
||||
ans30{[]int{}},
|
||||
},
|
||||
|
||||
question30{
|
||||
para30{"abc", []string{"a", "b", "c"}},
|
||||
ans30{[]int{0}},
|
||||
},
|
||||
|
||||
question30{
|
||||
para30{"a", []string{"b"}},
|
||||
ans30{[]int{}},
|
||||
},
|
||||
|
||||
question30{
|
||||
para30{"ab", []string{"ba"}},
|
||||
ans30{[]int{}},
|
||||
},
|
||||
|
||||
question30{
|
||||
para30{"n", []string{}},
|
||||
ans30{[]int{}},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 30------------------------\n")
|
||||
for _, q := range qs {
|
||||
_, p := q.ans30, q.para30
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, findSubstring(p.one, p.two))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
# [30. Substring with Concatenation of All Words](https://leetcode.com/problems/substring-with-concatenation-of-all-words/)
|
||||
|
||||
## 题目
|
||||
|
||||
You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters.
|
||||
|
||||
Example 1:
|
||||
|
||||
```c
|
||||
Input:
|
||||
s = "barfoothefoobarman",
|
||||
words = ["foo","bar"]
|
||||
Output: [0,9]
|
||||
Explanation: Substrings starting at index 0 and 9 are "barfoor" and "foobar" respectively.
|
||||
The output order does not matter, returning [9,0] is fine too.
|
||||
```
|
||||
|
||||
Example 2:
|
||||
|
||||
```c
|
||||
Input:
|
||||
s = "wordgoodgoodgoodbestword",
|
||||
words = ["word","good","best","word"]
|
||||
Output: []
|
||||
```
|
||||
|
||||
## 题目大意
|
||||
|
||||
给定一个源字符串 s,再给一个字符串数组,要求在源字符串中找到由字符串数组各种组合组成的连续串的起始下标,如果存在多个,在结果中都需要输出。
|
||||
|
||||
## 解题思路
|
||||
|
||||
这一题看似很难,但是有 2 个限定条件也导致这题不是特别难。1. 字符串数组里面的字符串长度都是一样的。2. 要求字符串数组中的字符串都要连续连在一起的,前后顺序可以是任意排列组合。
|
||||
|
||||
解题思路,先将字符串数组里面的所有字符串都存到 map 中,并累计出现的次数。然后从源字符串从头开始扫,每次判断字符串数组里面的字符串时候全部都用完了(计数是否为 0),如果全部都用完了,并且长度正好是字符串数组任意排列组合的总长度,就记录下这个组合的起始下标。如果不符合,就继续考察源字符串的下一个字符,直到扫完整个源字符串。
|
||||
|
||||
|
||||
|
@ -0,0 +1,78 @@
|
||||
package leetcode
|
||||
|
||||
func searchRange(nums []int, target int) []int {
|
||||
return []int{searchFirstEqualElement(nums, target), searchLastEqualElement(nums, target)}
|
||||
|
||||
}
|
||||
|
||||
// 二分查找第一个与 target 相等的元素,时间复杂度 O(logn)
|
||||
func searchFirstEqualElement(nums []int, target int) int {
|
||||
low, high := 0, len(nums)-1
|
||||
for low <= high {
|
||||
mid := low + ((high - low) >> 1)
|
||||
if nums[mid] > target {
|
||||
high = mid - 1
|
||||
} else if nums[mid] < target {
|
||||
low = mid + 1
|
||||
} else {
|
||||
if (mid == 0) || (nums[mid-1] != target) { // 找到第一个与 target 相等的元素
|
||||
return mid
|
||||
}
|
||||
high = mid - 1
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// 二分查找最后一个与 target 相等的元素,时间复杂度 O(logn)
|
||||
func searchLastEqualElement(nums []int, target int) int {
|
||||
low, high := 0, len(nums)-1
|
||||
for low <= high {
|
||||
mid := low + ((high - low) >> 1)
|
||||
if nums[mid] > target {
|
||||
high = mid - 1
|
||||
} else if nums[mid] < target {
|
||||
low = mid + 1
|
||||
} else {
|
||||
if (mid == len(nums)-1) || (nums[mid+1] != target) { // 找到最后一个与 target 相等的元素
|
||||
return mid
|
||||
}
|
||||
low = mid + 1
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// 二分查找第一个大于等于 target 的元素,时间复杂度 O(logn)
|
||||
func searchFirstGreaterElement(nums []int, target int) int {
|
||||
low, high := 0, len(nums)-1
|
||||
for low <= high {
|
||||
mid := low + ((high - low) >> 1)
|
||||
if nums[mid] >= target {
|
||||
if (mid == 0) || (nums[mid-1] < target) { // 找到第一个大于等于 target 的元素
|
||||
return mid
|
||||
}
|
||||
high = mid - 1
|
||||
} else {
|
||||
low = mid + 1
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// 二分查找最后一个小于等于 target 的元素,时间复杂度 O(logn)
|
||||
func searchLastLessElement(nums []int, target int) int {
|
||||
low, high := 0, len(nums)-1
|
||||
for low <= high {
|
||||
mid := low + ((high - low) >> 1)
|
||||
if nums[mid] <= target {
|
||||
if (mid == len(nums)-1) || (nums[mid+1] > target) { // 找到最后一个小于等于 target 的元素
|
||||
return mid
|
||||
}
|
||||
low = mid + 1
|
||||
} else {
|
||||
high = mid - 1
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question34 struct {
|
||||
para34
|
||||
ans34
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para34 struct {
|
||||
nums []int
|
||||
target int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans34 struct {
|
||||
one []int
|
||||
}
|
||||
|
||||
func Test_Problem34(t *testing.T) {
|
||||
|
||||
qs := []question34{
|
||||
|
||||
question34{
|
||||
para34{[]int{5, 7, 7, 8, 8, 10}, 8},
|
||||
ans34{[]int{3, 4}},
|
||||
},
|
||||
|
||||
question34{
|
||||
para34{[]int{5, 7, 7, 8, 8, 10}, 6},
|
||||
ans34{[]int{-1, -1}},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 34------------------------\n")
|
||||
for _, q := range qs {
|
||||
_, p := q.ans34, q.para34
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, searchRange(p.nums, p.target))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
# [34. Find First and Last Position of Element in Sorted Array](https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/)
|
||||
|
||||
|
||||
## 题目:
|
||||
|
||||
Given an array of integers `nums` sorted in ascending order, find the starting and ending position of a given `target` value.
|
||||
|
||||
Your algorithm's runtime complexity must be in the order of *O*(log *n*).
|
||||
|
||||
If the target is not found in the array, return `[-1, -1]`.
|
||||
|
||||
**Example 1:**
|
||||
|
||||
Input: nums = [5,7,7,8,8,10], target = 8
|
||||
Output: [3,4]
|
||||
|
||||
**Example 2:**
|
||||
|
||||
Input: nums = [5,7,7,8,8,10], target = 6
|
||||
Output: [-1,-1]
|
||||
|
||||
## 题目大意
|
||||
|
||||
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。你的算法时间复杂度必须是 O(log n) 级别。如果数组中不存在目标值,返回 [-1, -1]。
|
||||
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 给出一个有序数组 `nums` 和一个数 `target`,要求在数组中找到第一个和这个元素相等的元素下标,最后一个和这个元素相等的元素下标。
|
||||
- 这一题是经典的二分搜索变种题。二分搜索有 4 大基础变种题:
|
||||
1. 查找第一个值等于给定值的元素
|
||||
2. 查找最后一个值等于给定值的元素
|
||||
3. 查找第一个大于等于给定值的元素
|
||||
4. 查找最后一个小于等于给定值的元素
|
||||
|
||||
这一题的解题思路可以分别利用变种 1 和变种 2 的解法就可以做出此题。或者用一次变种 1 的方法,然后循环往后找到最后一个与给定值相等的元素。不过后者这种方法可能会使时间复杂度下降到 O(n),因为有可能数组中 n 个元素都和给定元素相同。(4 大基础变种的实现见代码)
|
85
leetcode/0036. Valid Sudoku/36. Valid Sudoku.go
Normal file
85
leetcode/0036. Valid Sudoku/36. Valid Sudoku.go
Normal file
@ -0,0 +1,85 @@
|
||||
package leetcode
|
||||
|
||||
import "strconv"
|
||||
|
||||
// 解法一 暴力遍历,时间复杂度 O(n^3)
|
||||
func isValidSudoku(board [][]byte) bool {
|
||||
// 判断行 row
|
||||
for i := 0; i < 9; i++ {
|
||||
tmp := [10]int{}
|
||||
for j := 0; j < 9; j++ {
|
||||
cellVal := board[i][j : j+1]
|
||||
if string(cellVal) != "." {
|
||||
index, _ := strconv.Atoi(string(cellVal))
|
||||
if index > 9 || index < 1 {
|
||||
return false
|
||||
}
|
||||
if tmp[index] == 1 {
|
||||
return false
|
||||
}
|
||||
tmp[index] = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
// 判断列 column
|
||||
for i := 0; i < 9; i++ {
|
||||
tmp := [10]int{}
|
||||
for j := 0; j < 9; j++ {
|
||||
cellVal := board[j][i]
|
||||
if string(cellVal) != "." {
|
||||
index, _ := strconv.Atoi(string(cellVal))
|
||||
if index > 9 || index < 1 {
|
||||
return false
|
||||
}
|
||||
if tmp[index] == 1 {
|
||||
return false
|
||||
}
|
||||
tmp[index] = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
// 判断 9宫格 3X3 cell
|
||||
for i := 0; i < 3; i++ {
|
||||
for j := 0; j < 3; j++ {
|
||||
tmp := [10]int{}
|
||||
for ii := i * 3; ii < i*3+3; ii++ {
|
||||
for jj := j * 3; jj < j*3+3; jj++ {
|
||||
cellVal := board[ii][jj]
|
||||
if string(cellVal) != "." {
|
||||
index, _ := strconv.Atoi(string(cellVal))
|
||||
if tmp[index] == 1 {
|
||||
return false
|
||||
}
|
||||
tmp[index] = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// 解法二 添加缓存,时间复杂度 O(n^2)
|
||||
func isValidSudoku1(board [][]byte) bool {
|
||||
rowbuf, colbuf, boxbuf := make([][]bool, 9), make([][]bool, 9), make([][]bool, 9)
|
||||
for i := 0; i < 9; i++ {
|
||||
rowbuf[i] = make([]bool, 9)
|
||||
colbuf[i] = make([]bool, 9)
|
||||
boxbuf[i] = make([]bool, 9)
|
||||
}
|
||||
// 遍历一次,添加缓存
|
||||
for r := 0; r < 9; r++ {
|
||||
for c := 0; c < 9; c++ {
|
||||
if board[r][c] != '.' {
|
||||
num := board[r][c] - '0' - byte(1)
|
||||
if rowbuf[r][num] || colbuf[c][num] || boxbuf[r/3*3+c/3][num] {
|
||||
return false
|
||||
}
|
||||
rowbuf[r][num] = true
|
||||
colbuf[c][num] = true
|
||||
boxbuf[r/3*3+c/3][num] = true // r,c 转换到box方格中
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
79
leetcode/0036. Valid Sudoku/36. Valid Sudoku_test.go
Normal file
79
leetcode/0036. Valid Sudoku/36. Valid Sudoku_test.go
Normal file
@ -0,0 +1,79 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question36 struct {
|
||||
para36
|
||||
ans36
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para36 struct {
|
||||
s [][]byte
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans36 struct {
|
||||
s bool
|
||||
}
|
||||
|
||||
func Test_Problem36(t *testing.T) {
|
||||
|
||||
qs := []question36{
|
||||
|
||||
question36{
|
||||
para36{[][]byte{
|
||||
[]byte{'5', '3', '.', '.', '7', '.', '.', '.', '.'},
|
||||
[]byte{'6', '.', '.', '1', '9', '5', '.', '.', '.'},
|
||||
[]byte{'.', '9', '8', '.', '.', '.', '.', '6', '.'},
|
||||
[]byte{'8', '.', '.', '.', '6', '.', '.', '.', '3'},
|
||||
[]byte{'4', '.', '.', '8', '.', '3', '.', '.', '1'},
|
||||
[]byte{'7', '.', '.', '.', '2', '.', '.', '.', '6'},
|
||||
[]byte{'.', '6', '.', '.', '.', '.', '2', '8', '.'},
|
||||
[]byte{'.', '.', '.', '4', '1', '9', '.', '.', '5'},
|
||||
[]byte{'.', '.', '.', '.', '8', '.', '.', '7', '9'}}},
|
||||
ans36{true},
|
||||
},
|
||||
|
||||
question36{
|
||||
para36{[][]byte{
|
||||
[]byte{'8', '3', '.', '.', '7', '.', '.', '.', '.'},
|
||||
[]byte{'6', '.', '.', '1', '9', '5', '.', '.', '.'},
|
||||
[]byte{'.', '9', '8', '.', '.', '.', '.', '6', '.'},
|
||||
[]byte{'8', '.', '.', '.', '6', '.', '.', '.', '3'},
|
||||
[]byte{'4', '.', '.', '8', '.', '3', '.', '.', '1'},
|
||||
[]byte{'7', '.', '.', '.', '2', '.', '.', '.', '6'},
|
||||
[]byte{'.', '6', '.', '.', '.', '.', '2', '8', '.'},
|
||||
[]byte{'.', '.', '.', '4', '1', '9', '.', '.', '5'},
|
||||
[]byte{'.', '.', '.', '.', '8', '.', '.', '7', '9'}}},
|
||||
ans36{false},
|
||||
},
|
||||
|
||||
question36{
|
||||
para36{[][]byte{
|
||||
[]byte{'.', '8', '7', '6', '5', '4', '3', '2', '1'},
|
||||
[]byte{'2', '.', '.', '.', '.', '.', '.', '.', '.'},
|
||||
[]byte{'3', '.', '.', '.', '.', '.', '.', '.', '.'},
|
||||
[]byte{'4', '.', '.', '.', '.', '.', '.', '.', '.'},
|
||||
[]byte{'5', '.', '.', '.', '.', '.', '.', '.', '.'},
|
||||
[]byte{'6', '.', '.', '.', '.', '.', '.', '.', '.'},
|
||||
[]byte{'7', '.', '.', '.', '.', '.', '.', '.', '.'},
|
||||
[]byte{'8', '.', '.', '.', '.', '.', '.', '.', '.'},
|
||||
[]byte{'9', '.', '.', '.', '.', '.', '.', '.', '.'}}},
|
||||
ans36{true},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 36------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans36, q.para36
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, isValidSudoku1(p.s))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
75
leetcode/0036. Valid Sudoku/README.md
Executable file
75
leetcode/0036. Valid Sudoku/README.md
Executable file
@ -0,0 +1,75 @@
|
||||
# [36. Valid Sudoku](https://leetcode.com/problems/valid-sudoku/)
|
||||
|
||||
|
||||
## 题目:
|
||||
|
||||
Determine if a 9x9 Sudoku board is valid. Only the filled cells need to be validated **according to the following rules**:
|
||||
|
||||
1. Each row must contain the digits `1-9` without repetition.
|
||||
2. Each column must contain the digits `1-9` without repetition.
|
||||
3. Each of the 9 `3x3` sub-boxes of the grid must contain the digits `1-9` without repetition.
|
||||
|
||||

|
||||
|
||||
A partially filled sudoku which is valid.
|
||||
|
||||
The Sudoku board could be partially filled, where empty cells are filled with the character `'.'`.
|
||||
|
||||
**Example 1:**
|
||||
|
||||
|
||||
Input:
|
||||
[
|
||||
["5","3",".",".","7",".",".",".","."],
|
||||
["6",".",".","1","9","5",".",".","."],
|
||||
[".","9","8",".",".",".",".","6","."],
|
||||
["8",".",".",".","6",".",".",".","3"],
|
||||
["4",".",".","8",".","3",".",".","1"],
|
||||
["7",".",".",".","2",".",".",".","6"],
|
||||
[".","6",".",".",".",".","2","8","."],
|
||||
[".",".",".","4","1","9",".",".","5"],
|
||||
[".",".",".",".","8",".",".","7","9"]
|
||||
]
|
||||
Output: true
|
||||
|
||||
|
||||
**Example 2:**
|
||||
|
||||
|
||||
Input:
|
||||
[
|
||||
["8","3",".",".","7",".",".",".","."],
|
||||
["6",".",".","1","9","5",".",".","."],
|
||||
[".","9","8",".",".",".",".","6","."],
|
||||
["8",".",".",".","6",".",".",".","3"],
|
||||
["4",".",".","8",".","3",".",".","1"],
|
||||
["7",".",".",".","2",".",".",".","6"],
|
||||
[".","6",".",".",".",".","2","8","."],
|
||||
[".",".",".","4","1","9",".",".","5"],
|
||||
[".",".",".",".","8",".",".","7","9"]
|
||||
]
|
||||
Output: false
|
||||
Explanation: Same as Example 1, except with the 5 in the top left corner being
|
||||
modified to 8. Since there are two 8's in the top left 3x3 sub-box, it is invalid.
|
||||
|
||||
|
||||
**Note:**
|
||||
|
||||
- A Sudoku board (partially filled) could be valid but is not necessarily solvable.
|
||||
- Only the filled cells need to be validated according to the mentioned rules.
|
||||
- The given board contain only digits `1-9` and the character `'.'`.
|
||||
- The given board size is always `9x9`.
|
||||
|
||||
## 题目大意
|
||||
|
||||
判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。
|
||||
|
||||
1. 数字 1-9 在每一行只能出现一次。
|
||||
2. 数字 1-9 在每一列只能出现一次。
|
||||
3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
|
||||
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 给出一个数独的棋盘,要求判断这个棋盘当前是否满足数独的要求:即行列是否都只包含 1-9,每个九宫格里面是否也只包含 1-9 。
|
||||
- 注意这题和第 37 题是不同的,这一题是判断当前棋盘状态是否满足数独的要求,而第 37 题是要求求解数独。本题中的棋盘有些是无解的,但是棋盘状态是满足题意的。
|
63
leetcode/0037. Sudoku Solver/37. Sudoku Solver.go
Normal file
63
leetcode/0037. Sudoku Solver/37. Sudoku Solver.go
Normal file
@ -0,0 +1,63 @@
|
||||
package leetcode
|
||||
|
||||
type position struct {
|
||||
x int
|
||||
y int
|
||||
}
|
||||
|
||||
func solveSudoku(board [][]byte) {
|
||||
pos, find := []position{}, false
|
||||
for i := 0; i < len(board); i++ {
|
||||
for j := 0; j < len(board[0]); j++ {
|
||||
if board[i][j] == '.' {
|
||||
pos = append(pos, position{x: i, y: j})
|
||||
}
|
||||
}
|
||||
}
|
||||
putSudoku(&board, pos, 0, &find)
|
||||
}
|
||||
|
||||
func putSudoku(board *[][]byte, pos []position, index int, succ *bool) {
|
||||
if *succ == true {
|
||||
return
|
||||
}
|
||||
if index == len(pos) {
|
||||
*succ = true
|
||||
return
|
||||
}
|
||||
for i := 1; i < 10; i++ {
|
||||
if checkSudoku(board, pos[index], i) && !*succ {
|
||||
(*board)[pos[index].x][pos[index].y] = byte(i) + '0'
|
||||
putSudoku(board, pos, index+1, succ)
|
||||
if *succ == true {
|
||||
return
|
||||
}
|
||||
(*board)[pos[index].x][pos[index].y] = '.'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func checkSudoku(board *[][]byte, pos position, val int) bool {
|
||||
// 判断横行是否有重复数字
|
||||
for i := 0; i < len((*board)[0]); i++ {
|
||||
if (*board)[pos.x][i] != '.' && int((*board)[pos.x][i]-'0') == val {
|
||||
return false
|
||||
}
|
||||
}
|
||||
// 判断竖行是否有重复数字
|
||||
for i := 0; i < len((*board)); i++ {
|
||||
if (*board)[i][pos.y] != '.' && int((*board)[i][pos.y]-'0') == val {
|
||||
return false
|
||||
}
|
||||
}
|
||||
// 判断九宫格是否有重复数字
|
||||
posx, posy := pos.x-pos.x%3, pos.y-pos.y%3
|
||||
for i := posx; i < posx+3; i++ {
|
||||
for j := posy; j < posy+3; j++ {
|
||||
if (*board)[i][j] != '.' && int((*board)[i][j]-'0') == val {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
62
leetcode/0037. Sudoku Solver/37. Sudoku Solver_test.go
Normal file
62
leetcode/0037. Sudoku Solver/37. Sudoku Solver_test.go
Normal file
@ -0,0 +1,62 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question37 struct {
|
||||
para37
|
||||
ans37
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para37 struct {
|
||||
s [][]byte
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans37 struct {
|
||||
s [][]byte
|
||||
}
|
||||
|
||||
func Test_Problem37(t *testing.T) {
|
||||
|
||||
qs := []question37{
|
||||
|
||||
question37{
|
||||
para37{[][]byte{
|
||||
[]byte{'5', '3', '.', '.', '7', '.', '.', '.', '.'},
|
||||
[]byte{'6', '.', '.', '1', '9', '5', '.', '.', '.'},
|
||||
[]byte{'.', '9', '8', '.', '.', '.', '.', '6', '.'},
|
||||
[]byte{'8', '.', '.', '.', '6', '.', '.', '.', '3'},
|
||||
[]byte{'4', '.', '.', '8', '.', '3', '.', '.', '1'},
|
||||
[]byte{'7', '.', '.', '.', '2', '.', '.', '.', '6'},
|
||||
[]byte{'.', '6', '.', '.', '.', '.', '2', '8', '.'},
|
||||
[]byte{'.', '.', '.', '4', '1', '9', '.', '.', '5'},
|
||||
[]byte{'.', '.', '.', '.', '8', '.', '.', '7', '9'}}},
|
||||
ans37{[][]byte{
|
||||
[]byte{'5', '3', '4', '6', '7', '8', '9', '1', '2'},
|
||||
[]byte{'6', '7', '2', '1', '9', '5', '3', '4', '8'},
|
||||
[]byte{'1', '9', '8', '3', '4', '2', '5', '6', '7'},
|
||||
[]byte{'8', '5', '9', '7', '6', '1', '4', '2', '3'},
|
||||
[]byte{'4', '2', '6', '8', '5', '3', '7', '9', '1'},
|
||||
[]byte{'7', '1', '3', '9', '2', '4', '8', '5', '6'},
|
||||
[]byte{'9', '6', '1', '5', '3', '7', '2', '8', '4'},
|
||||
[]byte{'2', '8', '7', '4', '1', '9', '6', '3', '5'},
|
||||
[]byte{'3', '4', '5', '2', '8', '6', '1', '7', '9'}}},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 37------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans37, q.para37
|
||||
fmt.Printf("【input】:%v \n\n", p)
|
||||
solveSudoku(p.s)
|
||||
fmt.Printf("【output】:%v \n\n", p)
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
48
leetcode/0037. Sudoku Solver/README.md
Executable file
48
leetcode/0037. Sudoku Solver/README.md
Executable file
@ -0,0 +1,48 @@
|
||||
# [37. Sudoku Solver](https://leetcode.com/problems/sudoku-solver/)
|
||||
|
||||
|
||||
|
||||
## 题目:
|
||||
|
||||
Write a program to solve a Sudoku puzzle by filling the empty cells.
|
||||
|
||||
A sudoku solution must satisfy **all of the following rules**:
|
||||
|
||||
1. Each of the digits `1-9` must occur exactly once in each row.
|
||||
2. Each of the digits `1-9` must occur exactly once in each column.
|
||||
3. Each of the the digits `1-9` must occur exactly once in each of the 9 `3x3` sub-boxes of the grid.
|
||||
|
||||
Empty cells are indicated by the character `'.'`.
|
||||
|
||||

|
||||
|
||||
A sudoku puzzle...
|
||||
|
||||

|
||||
|
||||
...and its solution numbers marked in red.
|
||||
|
||||
**Note:**
|
||||
|
||||
- The given board contain only digits `1-9` and the character `'.'`.
|
||||
- You may assume that the given Sudoku puzzle will have a single unique solution.
|
||||
- The given board size is always `9x9`.
|
||||
|
||||
## 题目大意
|
||||
|
||||
|
||||
编写一个程序,通过已填充的空格来解决数独问题。一个数独的解法需遵循如下规则:
|
||||
|
||||
1. 数字 1-9 在每一行只能出现一次。
|
||||
2. 数字 1-9 在每一列只能出现一次。
|
||||
3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
|
||||
|
||||
空白格用 '.' 表示。
|
||||
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 给出一个数独谜题,要求解出这个数独
|
||||
- 解题思路 DFS 暴力回溯枚举。数独要求每横行,每竖行,每九宫格内,`1-9` 的数字不能重复,每次放下一个数字的时候,在这 3 个地方都需要判断一次。
|
||||
- 另外找到一组解以后就不需要再继续回溯了,直接返回即可。
|
||||
|
29
leetcode/0039. Combination Sum/39. Combination Sum.go
Normal file
29
leetcode/0039. Combination Sum/39. Combination Sum.go
Normal file
@ -0,0 +1,29 @@
|
||||
package leetcode
|
||||
|
||||
import "sort"
|
||||
|
||||
func combinationSum(candidates []int, target int) [][]int {
|
||||
if len(candidates) == 0 {
|
||||
return [][]int{}
|
||||
}
|
||||
c, res := []int{}, [][]int{}
|
||||
sort.Ints(candidates)
|
||||
findcombinationSum(candidates, target, 0, c, &res)
|
||||
return res
|
||||
}
|
||||
|
||||
func findcombinationSum(nums []int, target, index int, c []int, res *[][]int) {
|
||||
if target <= 0 {
|
||||
if target == 0 {
|
||||
b := make([]int, len(c))
|
||||
copy(b, c)
|
||||
*res = append(*res, b)
|
||||
}
|
||||
return
|
||||
}
|
||||
for i := index; i < len(nums); i++ {
|
||||
c = append(c, nums[i])
|
||||
findcombinationSum(nums, target-nums[i], i, c, res) // 注意这里迭代的时候 index 依旧不变,因为一个元素可以取多次
|
||||
c = c[:len(c)-1]
|
||||
}
|
||||
}
|
48
leetcode/0039. Combination Sum/39. Combination Sum_test.go
Normal file
48
leetcode/0039. Combination Sum/39. Combination Sum_test.go
Normal file
@ -0,0 +1,48 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question39 struct {
|
||||
para39
|
||||
ans39
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para39 struct {
|
||||
n []int
|
||||
k int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans39 struct {
|
||||
one [][]int
|
||||
}
|
||||
|
||||
func Test_Problem39(t *testing.T) {
|
||||
|
||||
qs := []question39{
|
||||
|
||||
question39{
|
||||
para39{[]int{2, 3, 6, 7}, 7},
|
||||
ans39{[][]int{[]int{7}, []int{2, 2, 3}}},
|
||||
},
|
||||
|
||||
question39{
|
||||
para39{[]int{2, 3, 5}, 8},
|
||||
ans39{[][]int{[]int{2, 2, 2, 2}, []int{2, 3, 3}, []int{3, 5}}},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 39------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans39, q.para39
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, combinationSum(p.n, p.k))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
48
leetcode/0039. Combination Sum/README.md
Executable file
48
leetcode/0039. Combination Sum/README.md
Executable file
@ -0,0 +1,48 @@
|
||||
# [39. Combination Sum](https://leetcode.com/problems/combination-sum/)
|
||||
|
||||
|
||||
## 题目
|
||||
|
||||
Given a **set** of candidate numbers (`candidates`) **(without duplicates)** and a target number (`target`), find all unique combinations in `candidates` where the candidate numbers sums to `target`.
|
||||
|
||||
The **same** repeated number may be chosen from `candidates` unlimited number of times.
|
||||
|
||||
**Note:**
|
||||
|
||||
- All numbers (including `target`) will be positive integers.
|
||||
- The solution set must not contain duplicate combinations.
|
||||
|
||||
**Example 1:**
|
||||
|
||||
|
||||
Input: candidates = [2,3,6,7], target = 7,
|
||||
A solution set is:
|
||||
[
|
||||
[7],
|
||||
[2,2,3]
|
||||
]
|
||||
|
||||
|
||||
**Example 2:**
|
||||
|
||||
|
||||
Input: candidates = [2,3,5], target = 8,
|
||||
A solution set is:
|
||||
[
|
||||
[2,2,2,2],
|
||||
[2,3,3],
|
||||
[3,5]
|
||||
]
|
||||
|
||||
|
||||
## 题目大意
|
||||
|
||||
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
|
||||
|
||||
candidates 中的数字可以无限制重复被选取。
|
||||
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 题目要求出总和为 sum 的所有组合,组合需要去重。
|
||||
- 这一题和第 47 题类似,只不过元素可以反复使用。
|
34
leetcode/0040. Combination Sum II/40. Combination Sum II.go
Normal file
34
leetcode/0040. Combination Sum II/40. Combination Sum II.go
Normal file
@ -0,0 +1,34 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
func combinationSum2(candidates []int, target int) [][]int {
|
||||
if len(candidates) == 0 {
|
||||
return [][]int{}
|
||||
}
|
||||
c, res := []int{}, [][]int{}
|
||||
sort.Ints(candidates) // 这里是去重的关键逻辑
|
||||
findcombinationSum2(candidates, target, 0, c, &res)
|
||||
return res
|
||||
}
|
||||
|
||||
func findcombinationSum2(nums []int, target, index int, c []int, res *[][]int) {
|
||||
if target == 0 {
|
||||
b := make([]int, len(c))
|
||||
copy(b, c)
|
||||
*res = append(*res, b)
|
||||
return
|
||||
}
|
||||
for i := index; i < len(nums); i++ {
|
||||
if i > index && nums[i] == nums[i-1] { // 这里是去重的关键逻辑,本次不取重复数字,下次循环可能会取重复数字
|
||||
continue
|
||||
}
|
||||
if target >= nums[i] {
|
||||
c = append(c, nums[i])
|
||||
findcombinationSum2(nums, target-nums[i], i+1, c, res)
|
||||
c = c[:len(c)-1]
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question40 struct {
|
||||
para40
|
||||
ans40
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para40 struct {
|
||||
n []int
|
||||
k int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans40 struct {
|
||||
one [][]int
|
||||
}
|
||||
|
||||
func Test_Problem40(t *testing.T) {
|
||||
|
||||
qs := []question40{
|
||||
|
||||
question40{
|
||||
para40{[]int{10, 1, 2, 7, 6, 1, 5}, 8},
|
||||
ans40{[][]int{[]int{1, 7}, []int{1, 2, 5}, []int{2, 6}, []int{1, 1, 6}}},
|
||||
},
|
||||
|
||||
question40{
|
||||
para40{[]int{2, 5, 2, 1, 2}, 5},
|
||||
ans40{[][]int{[]int{1, 2, 2}, []int{5}}},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 40------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans40, q.para40
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, combinationSum2(p.n, p.k))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
48
leetcode/0040. Combination Sum II/README.md
Executable file
48
leetcode/0040. Combination Sum II/README.md
Executable file
@ -0,0 +1,48 @@
|
||||
# [40. Combination Sum II](https://leetcode.com/problems/combination-sum-ii/)
|
||||
|
||||
|
||||
## 题目
|
||||
|
||||
Given a collection of candidate numbers (`candidates`) and a target number (`target`), find all unique combinations in `candidates` where the candidate numbers sums to `target`.
|
||||
|
||||
Each number in `candidates` may only be used **once** in the combination.
|
||||
|
||||
**Note:**
|
||||
|
||||
- All numbers (including `target`) will be positive integers.
|
||||
- The solution set must not contain duplicate combinations.
|
||||
|
||||
**Example 1:**
|
||||
|
||||
|
||||
Input: candidates = [10,1,2,7,6,1,5], target = 8,
|
||||
A solution set is:
|
||||
[
|
||||
[1, 7],
|
||||
[1, 2, 5],
|
||||
[2, 6],
|
||||
[1, 1, 6]
|
||||
]
|
||||
|
||||
|
||||
**Example 2:**
|
||||
|
||||
|
||||
Input: candidates = [2,5,2,1,2], target = 5,
|
||||
A solution set is:
|
||||
[
|
||||
[1,2,2],
|
||||
[5]
|
||||
]
|
||||
|
||||
## 题目大意
|
||||
|
||||
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
|
||||
|
||||
candidates 中的每个数字在每个组合中只能使用一次。
|
||||
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 题目要求出总和为 sum 的所有组合,组合需要去重。这一题是第 39 题的加强版,第 39 题中元素可以重复利用(重复元素可无限次使用),这一题中元素只能有限次数的利用,因为存在重复元素,并且每个元素只能用一次(重复元素只能使用有限次)
|
||||
- 这一题和第 47 题类似,只不过元素可以反复使用。
|
@ -0,0 +1,14 @@
|
||||
package leetcode
|
||||
|
||||
func firstMissingPositive(nums []int) int {
|
||||
numMap := make(map[int]int, len(nums))
|
||||
for _, v := range nums {
|
||||
numMap[v] = v
|
||||
}
|
||||
for index := 1; index < len(nums)+1; index++ {
|
||||
if _, ok := numMap[index]; !ok {
|
||||
return index
|
||||
}
|
||||
}
|
||||
return len(nums) + 1
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question41 struct {
|
||||
para41
|
||||
ans41
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para41 struct {
|
||||
one []int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans41 struct {
|
||||
one int
|
||||
}
|
||||
|
||||
func Test_Problem41(t *testing.T) {
|
||||
|
||||
qs := []question41{
|
||||
|
||||
question41{
|
||||
para41{[]int{10, -1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, -3}},
|
||||
ans41{6},
|
||||
},
|
||||
|
||||
question41{
|
||||
para41{[]int{10, -1, 8, 6, 7, 3, -2, 5, 4, 2, 1, -3}},
|
||||
ans41{9},
|
||||
},
|
||||
|
||||
question41{
|
||||
para41{[]int{1}},
|
||||
ans41{2},
|
||||
},
|
||||
|
||||
question41{
|
||||
para41{[]int{0, 2, 2, 1, 1}},
|
||||
ans41{3},
|
||||
},
|
||||
|
||||
question41{
|
||||
para41{[]int{}},
|
||||
ans41{1},
|
||||
},
|
||||
|
||||
question41{
|
||||
para41{[]int{1, 2, 0}},
|
||||
ans41{3},
|
||||
},
|
||||
|
||||
question41{
|
||||
para41{[]int{3, 4, -1, 1}},
|
||||
ans41{2},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 41------------------------\n")
|
||||
for _, q := range qs {
|
||||
_, p := q.ans41, q.para41
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, firstMissingPositive(p.one))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
39
leetcode/0041. First-Missing-Positive/README.md
Normal file
39
leetcode/0041. First-Missing-Positive/README.md
Normal file
@ -0,0 +1,39 @@
|
||||
# [41. First Missing Positive](https://leetcode.com/problems/first-missing-positive/description/)
|
||||
|
||||
## 题目
|
||||
|
||||
Given an unsorted integer array, find the smallest missing positive integer.
|
||||
|
||||
Example 1:
|
||||
|
||||
```
|
||||
Input: [1,2,0]
|
||||
Output: 3
|
||||
```
|
||||
|
||||
Example 2:
|
||||
|
||||
```
|
||||
Input: [3,4,-1,1]
|
||||
Output: 2
|
||||
```
|
||||
|
||||
Example 3:
|
||||
|
||||
```
|
||||
Input: [7,8,9,11,12]
|
||||
Output: 1
|
||||
```
|
||||
|
||||
Note:
|
||||
|
||||
Your algorithm should run in O(n) time and uses constant extra space.
|
||||
|
||||
## 题目大意
|
||||
|
||||
找到缺失的第一个正整数。
|
||||
|
||||
## 解题思路
|
||||
|
||||
|
||||
为了减少时间复杂度,可以把 input 数组都装到 map 中,然后 i 循环从 1 开始,依次比对 map 中是否存在 i,只要不存在 i 就立即返回结果,即所求。
|
@ -0,0 +1,23 @@
|
||||
package leetcode
|
||||
|
||||
func trap(height []int) int {
|
||||
res, left, right, maxLeft, maxRight := 0, 0, len(height)-1, 0, 0
|
||||
for left <= right {
|
||||
if height[left] <= height[right] {
|
||||
if height[left] > maxLeft {
|
||||
maxLeft = height[left]
|
||||
} else {
|
||||
res += maxLeft - height[left]
|
||||
}
|
||||
left++
|
||||
} else {
|
||||
if height[right] >= maxRight {
|
||||
maxRight = height[right]
|
||||
} else {
|
||||
res += maxRight - height[right]
|
||||
}
|
||||
right--
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question42 struct {
|
||||
para42
|
||||
ans42
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para42 struct {
|
||||
one []int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans42 struct {
|
||||
one int
|
||||
}
|
||||
|
||||
func Test_Problem42(t *testing.T) {
|
||||
|
||||
qs := []question42{
|
||||
|
||||
question42{
|
||||
para42{[]int{0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1}},
|
||||
ans42{6},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 42------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans42, q.para42
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, trap(p.one))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
29
leetcode/0042. Trapping Rain Water/README.md
Normal file
29
leetcode/0042. Trapping Rain Water/README.md
Normal file
@ -0,0 +1,29 @@
|
||||
# [42. Trapping Rain Water](https://leetcode.com/problems/trapping-rain-water/)
|
||||
|
||||
## 题目
|
||||
|
||||
Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
|
||||
|
||||

|
||||
|
||||
|
||||
The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcos for contributing this image!
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
```c
|
||||
Input: [0,1,0,2,1,0,1,3,2,1,2,1]
|
||||
Output: 6
|
||||
```
|
||||
|
||||
## 题目大意
|
||||
|
||||
从 x 轴开始,给出一个数组,数组里面的数字代表从 (0,0) 点开始,宽度为 1 个单位,高度为数组元素的值。如果下雨了,问这样一个容器能装多少单位的水?
|
||||
|
||||
## 解题思路
|
||||
|
||||
|
||||

|
||||
|
||||
每个数组里面的元素值可以想象成一个左右都有壁的圆柱筒。例如上图中左边的第二个元素 1,当前左边最大的元素是 2 ,所以 2 高度的水会装到 1 的上面(因为想象成了左右都有筒壁)。这道题的思路就是左指针从 0 开始往右扫,右指针从最右边开始往左扫。额外还需要 2 个变量分别记住左边最大的高度和右边最大高度。遍历扫数组元素的过程中,如果左指针的高度比右指针的高度小,就不断的移动左指针,否则移动右指针。循环的终止条件就是左右指针碰上以后就结束。只要数组中元素的高度比保存的局部最大高度小,就累加 res 的值,否则更新局部最大高度。最终解就是 res 的值。
|
29
leetcode/0046. Permutations/46. Permutations.go
Normal file
29
leetcode/0046. Permutations/46. Permutations.go
Normal file
@ -0,0 +1,29 @@
|
||||
package leetcode
|
||||
|
||||
func permute(nums []int) [][]int {
|
||||
if len(nums) == 0 {
|
||||
return [][]int{}
|
||||
}
|
||||
used, p, res := make([]bool, len(nums)), []int{}, [][]int{}
|
||||
generatePermutation(nums, 0, p, &res, &used)
|
||||
return res
|
||||
}
|
||||
|
||||
func generatePermutation(nums []int, index int, p []int, res *[][]int, used *[]bool) {
|
||||
if index == len(nums) {
|
||||
temp := make([]int, len(p))
|
||||
copy(temp, p)
|
||||
*res = append(*res, temp)
|
||||
return
|
||||
}
|
||||
for i := 0; i < len(nums); i++ {
|
||||
if !(*used)[i] {
|
||||
(*used)[i] = true
|
||||
p = append(p, nums[i])
|
||||
generatePermutation(nums, index+1, p, res, used)
|
||||
p = p[:len(p)-1]
|
||||
(*used)[i] = false
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
42
leetcode/0046. Permutations/46. Permutations_test.go
Normal file
42
leetcode/0046. Permutations/46. Permutations_test.go
Normal file
@ -0,0 +1,42 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question46 struct {
|
||||
para46
|
||||
ans46
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para46 struct {
|
||||
s []int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans46 struct {
|
||||
one [][]int
|
||||
}
|
||||
|
||||
func Test_Problem46(t *testing.T) {
|
||||
|
||||
qs := []question46{
|
||||
|
||||
question46{
|
||||
para46{[]int{1, 2, 3}},
|
||||
ans46{[][]int{[]int{1, 2, 3}, []int{1, 3, 2}, []int{2, 1, 3}, []int{2, 3, 1}, []int{3, 1, 2}, []int{3, 2, 1}}},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 46------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans46, q.para46
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, permute(p.s))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
30
leetcode/0046. Permutations/README.md
Executable file
30
leetcode/0046. Permutations/README.md
Executable file
@ -0,0 +1,30 @@
|
||||
# [46. Permutations](https://leetcode.com/problems/permutations/)
|
||||
|
||||
|
||||
## 题目
|
||||
|
||||
Given a collection of **distinct** integers, return all possible permutations.
|
||||
|
||||
**Example:**
|
||||
|
||||
|
||||
Input: [1,2,3]
|
||||
Output:
|
||||
[
|
||||
[1,2,3],
|
||||
[1,3,2],
|
||||
[2,1,3],
|
||||
[2,3,1],
|
||||
[3,1,2],
|
||||
[3,2,1]
|
||||
]
|
||||
|
||||
|
||||
## 题目大意
|
||||
|
||||
给定一个没有重复数字的序列,返回其所有可能的全排列。
|
||||
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 求出一个数组的排列组合中的所有排列,用 DFS 深搜即可。
|
35
leetcode/0047. Permutations II/47. Permutations II.go
Normal file
35
leetcode/0047. Permutations II/47. Permutations II.go
Normal file
@ -0,0 +1,35 @@
|
||||
package leetcode
|
||||
|
||||
import "sort"
|
||||
|
||||
func permuteUnique(nums []int) [][]int {
|
||||
if len(nums) == 0 {
|
||||
return [][]int{}
|
||||
}
|
||||
used, p, res := make([]bool, len(nums)), []int{}, [][]int{}
|
||||
sort.Ints(nums) // 这里是去重的关键逻辑
|
||||
generatePermutation47(nums, 0, p, &res, &used)
|
||||
return res
|
||||
}
|
||||
|
||||
func generatePermutation47(nums []int, index int, p []int, res *[][]int, used *[]bool) {
|
||||
if index == len(nums) {
|
||||
temp := make([]int, len(p))
|
||||
copy(temp, p)
|
||||
*res = append(*res, temp)
|
||||
return
|
||||
}
|
||||
for i := 0; i < len(nums); i++ {
|
||||
if !(*used)[i] {
|
||||
if i > 0 && nums[i] == nums[i-1] && !(*used)[i-1] { // 这里是去重的关键逻辑
|
||||
continue
|
||||
}
|
||||
(*used)[i] = true
|
||||
p = append(p, nums[i])
|
||||
generatePermutation47(nums, index+1, p, res, used)
|
||||
p = p[:len(p)-1]
|
||||
(*used)[i] = false
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
52
leetcode/0047. Permutations II/47. Permutations II_test.go
Normal file
52
leetcode/0047. Permutations II/47. Permutations II_test.go
Normal file
@ -0,0 +1,52 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question47 struct {
|
||||
para47
|
||||
ans47
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para47 struct {
|
||||
s []int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans47 struct {
|
||||
one [][]int
|
||||
}
|
||||
|
||||
func Test_Problem47(t *testing.T) {
|
||||
|
||||
qs := []question47{
|
||||
|
||||
question47{
|
||||
para47{[]int{1, 1, 2}},
|
||||
ans47{[][]int{[]int{1, 1, 2}, []int{1, 2, 1}, []int{2, 1, 1}}},
|
||||
},
|
||||
|
||||
question47{
|
||||
para47{[]int{1, 2, 2}},
|
||||
ans47{[][]int{[]int{1, 2, 2}, []int{2, 2, 1}, []int{2, 1, 2}}},
|
||||
},
|
||||
|
||||
question47{
|
||||
para47{[]int{2, 2, 2}},
|
||||
ans47{[][]int{[]int{2, 2, 2}}},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 47------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans47, q.para47
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, permuteUnique(p.s))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
28
leetcode/0047. Permutations II/README.md
Executable file
28
leetcode/0047. Permutations II/README.md
Executable file
@ -0,0 +1,28 @@
|
||||
# [47. Permutations II](https://leetcode.com/problems/permutations-ii/)
|
||||
|
||||
|
||||
## 题目
|
||||
|
||||
Given a collection of numbers that might contain duplicates, return all possible unique permutations.
|
||||
|
||||
**Example:**
|
||||
|
||||
|
||||
Input: [1,1,2]
|
||||
Output:
|
||||
[
|
||||
[1,1,2],
|
||||
[1,2,1],
|
||||
[2,1,1]
|
||||
]
|
||||
|
||||
|
||||
## 题目大意
|
||||
|
||||
给定一个可包含重复数字的序列,返回所有不重复的全排列。
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 这一题是第 46 题的加强版,第 46 题中求数组的排列,数组中元素不重复,但是这一题中,数组元素会重复,所以需要最终排列出来的结果需要去重。
|
||||
- 去重的方法是经典逻辑,将数组排序以后,判断重复元素再做逻辑判断。
|
||||
- 其他思路和第 46 题完全一致,DFS 深搜即可。
|
26
leetcode/0048. Rotate Image/48. Rotate Image.go
Normal file
26
leetcode/0048. Rotate Image/48. Rotate Image.go
Normal file
@ -0,0 +1,26 @@
|
||||
package leetcode
|
||||
|
||||
func rotate(matrix [][]int) {
|
||||
row := len(matrix)
|
||||
if row <= 0 {
|
||||
return
|
||||
}
|
||||
column := len(matrix[0])
|
||||
// rotate by diagonal 对角线变换
|
||||
for i := 0; i < row; i++ {
|
||||
for j := i + 1; j < column; j++ {
|
||||
tmp := matrix[i][j]
|
||||
matrix[i][j] = matrix[j][i]
|
||||
matrix[j][i] = tmp
|
||||
}
|
||||
}
|
||||
// rotate by vertical centerline 竖直轴对称翻转
|
||||
halfColumn := column / 2
|
||||
for i := 0; i < row; i++ {
|
||||
for j := 0; j < halfColumn; j++ {
|
||||
tmp := matrix[i][j]
|
||||
matrix[i][j] = matrix[i][column-j-1]
|
||||
matrix[i][column-j-1] = tmp
|
||||
}
|
||||
}
|
||||
}
|
50
leetcode/0048. Rotate Image/48. Rotate Image_test.go
Normal file
50
leetcode/0048. Rotate Image/48. Rotate Image_test.go
Normal file
@ -0,0 +1,50 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question48 struct {
|
||||
para48
|
||||
ans48
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para48 struct {
|
||||
s [][]int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans48 struct {
|
||||
s [][]int
|
||||
}
|
||||
|
||||
func Test_Problem48(t *testing.T) {
|
||||
|
||||
qs := []question48{
|
||||
|
||||
question48{
|
||||
para48{[][]int{[]int{1, 2, 3}, []int{4, 5, 6}, []int{7, 8, 9}}},
|
||||
ans48{[][]int{[]int{7, 4, 1}, []int{8, 5, 2}, []int{9, 6, 3}}},
|
||||
},
|
||||
|
||||
question48{
|
||||
para48{[][]int{[]int{5, 1, 9, 11}, []int{2, 4, 8, 10}, []int{13, 3, 6, 7}, []int{15, 14, 12, 16}}},
|
||||
ans48{[][]int{[]int{15, 13, 2, 5}, []int{14, 3, 4, 1}, []int{12, 6, 8, 9}, []int{16, 7, 10, 11}}},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 48------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans48, q.para48
|
||||
fmt.Printf("【input】:%v \n", p)
|
||||
rotate(p.s)
|
||||
fmt.Printf("【output】:%v\n", p)
|
||||
fmt.Printf("\n")
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
91
leetcode/0048. Rotate Image/README.md
Executable file
91
leetcode/0048. Rotate Image/README.md
Executable file
@ -0,0 +1,91 @@
|
||||
# [48. Rotate Image](https://leetcode.com/problems/rotate-image/)
|
||||
|
||||
## 题目
|
||||
|
||||
You are given an *n* x *n* 2D matrix representing an image.
|
||||
|
||||
Rotate the image by 90 degrees (clockwise).
|
||||
|
||||
**Note:**
|
||||
|
||||
You have to rotate the image **[in-place](https://en.wikipedia.org/wiki/In-place_algorithm)**, which means you have to modify the input 2D matrix directly. **DO NOT** allocate another 2D matrix and do the rotation.
|
||||
|
||||
**Example 1:**
|
||||
|
||||
|
||||
Given input matrix =
|
||||
[
|
||||
[1,2,3],
|
||||
[4,5,6],
|
||||
[7,8,9]
|
||||
],
|
||||
|
||||
rotate the input matrix in-place such that it becomes:
|
||||
[
|
||||
[7,4,1],
|
||||
[8,5,2],
|
||||
[9,6,3]
|
||||
]
|
||||
|
||||
|
||||
**Example 2:**
|
||||
|
||||
|
||||
Given input matrix =
|
||||
[
|
||||
[ 5, 1, 9,11],
|
||||
[ 2, 4, 8,10],
|
||||
[13, 3, 6, 7],
|
||||
[15,14,12,16]
|
||||
],
|
||||
|
||||
rotate the input matrix in-place such that it becomes:
|
||||
[
|
||||
[15,13, 2, 5],
|
||||
[14, 3, 4, 1],
|
||||
[12, 6, 8, 9],
|
||||
[16, 7,10,11]
|
||||
]
|
||||
|
||||
|
||||
## 题目大意
|
||||
|
||||
给定一个 n × n 的二维矩阵表示一个图像。将图像顺时针旋转 90 度。说明:你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。
|
||||
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 给出一个二维数组,要求顺时针旋转 90 度。
|
||||
- 这一题比较简单,按照题意做就可以。这里给出 2 种旋转方法的实现,顺时针旋转和逆时针旋转。
|
||||
|
||||
```c
|
||||
/*
|
||||
* clockwise rotate 顺时针旋转
|
||||
* first reverse up to down, then swap the symmetry
|
||||
* 1 2 3 7 8 9 7 4 1
|
||||
* 4 5 6 => 4 5 6 => 8 5 2
|
||||
* 7 8 9 1 2 3 9 6 3
|
||||
*/
|
||||
void rotate(vector<vector<int> > &matrix) {
|
||||
reverse(matrix.begin(), matrix.end());
|
||||
for (int i = 0; i < matrix.size(); ++i) {
|
||||
for (int j = i + 1; j < matrix[i].size(); ++j)
|
||||
swap(matrix[i][j], matrix[j][i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* anticlockwise rotate 逆时针旋转
|
||||
* first reverse left to right, then swap the symmetry
|
||||
* 1 2 3 3 2 1 3 6 9
|
||||
* 4 5 6 => 6 5 4 => 2 5 8
|
||||
* 7 8 9 9 8 7 1 4 7
|
||||
*/
|
||||
void anti_rotate(vector<vector<int> > &matrix) {
|
||||
for (auto vi : matrix) reverse(vi.begin(), vi.end());
|
||||
for (int i = 0; i < matrix.size(); ++i) {
|
||||
for (int j = i + 1; j < matrix[i].size(); ++j)
|
||||
swap(matrix[i][j], matrix[j][i]);
|
||||
}
|
||||
}
|
||||
```
|
32
leetcode/0049. Group Anagrams/49. Group Anagrams.go
Normal file
32
leetcode/0049. Group Anagrams/49. Group Anagrams.go
Normal file
@ -0,0 +1,32 @@
|
||||
package leetcode
|
||||
|
||||
import "sort"
|
||||
|
||||
type sortRunes []rune
|
||||
|
||||
func (s sortRunes) Less(i, j int) bool {
|
||||
return s[i] < s[j]
|
||||
}
|
||||
|
||||
func (s sortRunes) Swap(i, j int) {
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
|
||||
func (s sortRunes) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func groupAnagrams(strs []string) [][]string {
|
||||
record, res := map[string][]string{}, [][]string{}
|
||||
for _, str := range strs {
|
||||
sByte := []rune(str)
|
||||
sort.Sort(sortRunes(sByte))
|
||||
sstrs := record[string(sByte)]
|
||||
sstrs = append(sstrs, str)
|
||||
record[string(sByte)] = sstrs
|
||||
}
|
||||
for _, v := range record {
|
||||
res = append(res, v)
|
||||
}
|
||||
return res
|
||||
}
|
41
leetcode/0049. Group Anagrams/49. Group Anagrams_test.go
Normal file
41
leetcode/0049. Group Anagrams/49. Group Anagrams_test.go
Normal file
@ -0,0 +1,41 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question49 struct {
|
||||
para49
|
||||
ans49
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para49 struct {
|
||||
one []string
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans49 struct {
|
||||
one [][]string
|
||||
}
|
||||
|
||||
func Test_Problem49(t *testing.T) {
|
||||
|
||||
qs := []question49{
|
||||
|
||||
question49{
|
||||
para49{[]string{"eat", "tea", "tan", "ate", "nat", "bat"}},
|
||||
ans49{[][]string{[]string{"ate", "eat", "tea"}, []string{"nat", "tan"}, []string{"bat"}}},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 49------------------------\n")
|
||||
for _, q := range qs {
|
||||
_, p := q.ans49, q.para49
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, groupAnagrams(p.one))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
31
leetcode/0049. Group Anagrams/README.md
Normal file
31
leetcode/0049. Group Anagrams/README.md
Normal file
@ -0,0 +1,31 @@
|
||||
# [49. Group Anagrams](https://leetcode.com/problems/group-anagrams/)
|
||||
|
||||
## 题目
|
||||
|
||||
Given an array of strings, group anagrams together.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
```c
|
||||
Input: ["eat", "tea", "tan", "ate", "nat", "bat"],
|
||||
Output:
|
||||
[
|
||||
["ate","eat","tea"],
|
||||
["nat","tan"],
|
||||
["bat"]
|
||||
]
|
||||
```
|
||||
|
||||
Note:
|
||||
|
||||
- All inputs will be in lowercase.
|
||||
- The order of your output does not matter.
|
||||
|
||||
## 题目大意
|
||||
|
||||
给出一个字符串数组,要求对字符串数组里面有 Anagrams 关系的字符串进行分组。Anagrams 关系是指两个字符串的字符完全相同,顺序不同,两者是由排列组合组成。
|
||||
|
||||
## 解题思路
|
||||
|
||||
这道题可以将每个字符串都排序,排序完成以后,相同 Anagrams 的字符串必然排序结果一样。把排序以后的字符串当做 key 存入到 map 中。遍历数组以后,就能得到一个 map,key 是排序以后的字符串,value 对应的是这个排序字符串以后的 Anagrams 字符串集合。最后再将这些 value 对应的字符串数组输出即可。
|
20
leetcode/0050. Pow(x, n)/50. Pow(x, n).go
Normal file
20
leetcode/0050. Pow(x, n)/50. Pow(x, n).go
Normal file
@ -0,0 +1,20 @@
|
||||
package leetcode
|
||||
|
||||
// 时间复杂度 O(log n),空间复杂度 O(1)
|
||||
func myPow(x float64, n int) float64 {
|
||||
if n == 0 {
|
||||
return 1
|
||||
}
|
||||
if n == 1 {
|
||||
return x
|
||||
}
|
||||
if n < 0 {
|
||||
n = -n
|
||||
x = 1 / x
|
||||
}
|
||||
tmp := myPow(x, n/2)
|
||||
if n%2 == 0 {
|
||||
return tmp * tmp
|
||||
}
|
||||
return tmp * tmp * x
|
||||
}
|
53
leetcode/0050. Pow(x, n)/50. Pow(x, n)_test.go
Normal file
53
leetcode/0050. Pow(x, n)/50. Pow(x, n)_test.go
Normal file
@ -0,0 +1,53 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question50 struct {
|
||||
para50
|
||||
ans50
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para50 struct {
|
||||
x float64
|
||||
n int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans50 struct {
|
||||
one float64
|
||||
}
|
||||
|
||||
func Test_Problem50(t *testing.T) {
|
||||
|
||||
qs := []question50{
|
||||
|
||||
question50{
|
||||
para50{2.00000, 10},
|
||||
ans50{1024.00000},
|
||||
},
|
||||
|
||||
question50{
|
||||
para50{2.10000, 3},
|
||||
ans50{9.26100},
|
||||
},
|
||||
|
||||
question50{
|
||||
para50{2.00000, -2},
|
||||
ans50{0.25000},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 50------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans50, q.para50
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, myPow(p.x, p.n))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
42
leetcode/0050. Pow(x, n)/README.md
Executable file
42
leetcode/0050. Pow(x, n)/README.md
Executable file
@ -0,0 +1,42 @@
|
||||
# [50. Pow(x, n)](https://leetcode.com/problems/powx-n/)
|
||||
|
||||
|
||||
## 题目
|
||||
|
||||
Implement [pow(*x*, *n*)](http://www.cplusplus.com/reference/valarray/pow/), which calculates *x* raised to the power *n* (xn).
|
||||
|
||||
**Example 1:**
|
||||
|
||||
|
||||
Input: 2.00000, 10
|
||||
Output: 1024.00000
|
||||
|
||||
|
||||
**Example 2:**
|
||||
|
||||
|
||||
Input: 2.10000, 3
|
||||
Output: 9.26100
|
||||
|
||||
|
||||
**Example 3:**
|
||||
|
||||
|
||||
Input: 2.00000, -2
|
||||
Output: 0.25000
|
||||
Explanation: 2-2 = 1/22 = 1/4 = 0.25
|
||||
|
||||
|
||||
**Note:**
|
||||
|
||||
- -100.0 < *x* < 100.0
|
||||
- *n* is a 32-bit signed integer, within the range [−2^31, 2^31− 1]
|
||||
|
||||
## 题目大意
|
||||
|
||||
实现 pow(x, n) ,即计算 x 的 n 次幂函数。
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 要求计算 Pow(x, n)
|
||||
- 这一题用递归的方式,不断的将 n 2 分下去。注意 n 的正负数,n 的奇偶性。
|
85
leetcode/0051. N-Queens/51. N-Queens.go
Normal file
85
leetcode/0051. N-Queens/51. N-Queens.go
Normal file
@ -0,0 +1,85 @@
|
||||
package leetcode
|
||||
|
||||
// 解法一 DFS
|
||||
func solveNQueens(n int) [][]string {
|
||||
col, dia1, dia2, row, res := make([]bool, n), make([]bool, 2*n-1), make([]bool, 2*n-1), []int{}, [][]string{}
|
||||
putQueen(n, 0, &col, &dia1, &dia2, &row, &res)
|
||||
return res
|
||||
}
|
||||
|
||||
// 尝试在一个n皇后问题中, 摆放第index行的皇后位置
|
||||
func putQueen(n, index int, col, dia1, dia2 *[]bool, row *[]int, res *[][]string) {
|
||||
if index == n {
|
||||
*res = append(*res, generateBoard(n, row))
|
||||
return
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
// 尝试将第index行的皇后摆放在第i列
|
||||
if !(*col)[i] && !(*dia1)[index+i] && !(*dia2)[index-i+n-1] {
|
||||
*row = append(*row, i)
|
||||
(*col)[i] = true
|
||||
(*dia1)[index+i] = true
|
||||
(*dia2)[index-i+n-1] = true
|
||||
putQueen(n, index+1, col, dia1, dia2, row, res)
|
||||
(*col)[i] = false
|
||||
(*dia1)[index+i] = false
|
||||
(*dia2)[index-i+n-1] = false
|
||||
*row = (*row)[:len(*row)-1]
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func generateBoard(n int, row *[]int) []string {
|
||||
board := []string{}
|
||||
res := ""
|
||||
for i := 0; i < n; i++ {
|
||||
res += "."
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
board = append(board, res)
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
tmp := []byte(board[i])
|
||||
tmp[(*row)[i]] = 'Q'
|
||||
board[i] = string(tmp)
|
||||
}
|
||||
return board
|
||||
}
|
||||
|
||||
// 解法二 二进制操作法
|
||||
// class Solution
|
||||
// {
|
||||
// int n;
|
||||
// string getNq(int p)
|
||||
// {
|
||||
// string s(n, '.');
|
||||
// s[p] = 'Q';
|
||||
// return s;
|
||||
// }
|
||||
// void nQueens(int p, int l, int m, int r, vector<vector<string>> &res)
|
||||
// {
|
||||
// static vector<string> ans;
|
||||
// if (p >= n)
|
||||
// {
|
||||
// res.push_back(ans);
|
||||
// return ;
|
||||
// }
|
||||
// int mask = l | m | r;
|
||||
// for (int i = 0, b = 1; i < n; ++ i, b <<= 1)
|
||||
// if (!(mask & b))
|
||||
// {
|
||||
// ans.push_back(getNq(i));
|
||||
// nQueens(p + 1, (l | b) >> 1, m | b, (r | b) << 1, res);
|
||||
// ans.pop_back();
|
||||
// }
|
||||
// }
|
||||
// public:
|
||||
// vector<vector<string> > solveNQueens(int n)
|
||||
// {
|
||||
// this->n = n;
|
||||
// vector<vector<string>> res;
|
||||
// nQueens(0, 0, 0, 0, res);
|
||||
// return res;
|
||||
// }
|
||||
// };
|
50
leetcode/0051. N-Queens/51. N-Queens_test.go
Normal file
50
leetcode/0051. N-Queens/51. N-Queens_test.go
Normal file
@ -0,0 +1,50 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question51 struct {
|
||||
para51
|
||||
ans51
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para51 struct {
|
||||
one int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans51 struct {
|
||||
one [][]string
|
||||
}
|
||||
|
||||
func Test_Problem51(t *testing.T) {
|
||||
|
||||
qs := []question51{
|
||||
|
||||
question51{
|
||||
para51{4},
|
||||
ans51{[][]string{
|
||||
[]string{".Q..",
|
||||
"...Q",
|
||||
"Q...",
|
||||
"..Q."},
|
||||
[]string{"..Q.",
|
||||
"Q...",
|
||||
"...Q",
|
||||
".Q.."},
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 51------------------------\n")
|
||||
for _, q := range qs {
|
||||
_, p := q.ans51, q.para51
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, solveNQueens(p.one))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
43
leetcode/0051. N-Queens/README.md
Executable file
43
leetcode/0051. N-Queens/README.md
Executable file
@ -0,0 +1,43 @@
|
||||
# [51. N-Queens](https://leetcode.com/problems/n-queens/)
|
||||
|
||||
|
||||
## 题目
|
||||
|
||||
The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.
|
||||
|
||||

|
||||
|
||||
Given an integer *n*, return all distinct solutions to the *n*-queens puzzle.
|
||||
|
||||
Each solution contains a distinct board configuration of the *n*-queens' placement, where `'Q'` and `'.'` both indicate a queen and an empty space respectively.
|
||||
|
||||
**Example:**
|
||||
|
||||
|
||||
Input: 4
|
||||
Output: [
|
||||
[".Q..", // Solution 1
|
||||
"...Q",
|
||||
"Q...",
|
||||
"..Q."],
|
||||
|
||||
["..Q.", // Solution 2
|
||||
"Q...",
|
||||
"...Q",
|
||||
".Q.."]
|
||||
]
|
||||
Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above.
|
||||
|
||||
|
||||
## 题目大意
|
||||
|
||||
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。
|
||||
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 求解 n 皇后问题
|
||||
- 利用 col 数组记录列信息,col 有 `n` 列。用 dia1,dia2 记录从左下到右上的对角线,从左上到右下的对角线的信息,dia1 和 dia2 分别都有 `2*n-1` 个。
|
||||
- dia1 对角线的规律是 `i + j 是定值`,例如[0,0],为 0;[1,0]、[0,1] 为 1;[2,0]、[1,1]、[0,2] 为 2;
|
||||
- dia2 对角线的规律是 `i - j 是定值`,例如[0,7],为 -7;[0,6]、[1,7] 为 -6;[0,5]、[1,6]、[2,7] 为 -5;为了使他们从 0 开始,i - j + n - 1 偏移到 0 开始,所以 dia2 的规律是 `i - j + n - 1 为定值`。
|
||||
|
62
leetcode/0052. N-Queens II/52. N-Queens II.go
Normal file
62
leetcode/0052. N-Queens II/52. N-Queens II.go
Normal file
@ -0,0 +1,62 @@
|
||||
package leetcode
|
||||
|
||||
// 解法一,暴力打表法
|
||||
func totalNQueens(n int) int {
|
||||
res := []int{0, 1, 0, 0, 2, 10, 4, 40, 92, 352, 724}
|
||||
return res[n]
|
||||
}
|
||||
|
||||
// 解法二,DFS 回溯法
|
||||
func totalNQueens1(n int) int {
|
||||
col, dia1, dia2, row, res := make([]bool, n), make([]bool, 2*n-1), make([]bool, 2*n-1), []int{}, 0
|
||||
putQueen52(n, 0, &col, &dia1, &dia2, &row, &res)
|
||||
return res
|
||||
}
|
||||
|
||||
// 尝试在一个n皇后问题中, 摆放第index行的皇后位置
|
||||
func putQueen52(n, index int, col, dia1, dia2 *[]bool, row *[]int, res *int) {
|
||||
if index == n {
|
||||
*res++
|
||||
return
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
// 尝试将第index行的皇后摆放在第i列
|
||||
if !(*col)[i] && !(*dia1)[index+i] && !(*dia2)[index-i+n-1] {
|
||||
*row = append(*row, i)
|
||||
(*col)[i] = true
|
||||
(*dia1)[index+i] = true
|
||||
(*dia2)[index-i+n-1] = true
|
||||
putQueen52(n, index+1, col, dia1, dia2, row, res)
|
||||
(*col)[i] = false
|
||||
(*dia1)[index+i] = false
|
||||
(*dia2)[index-i+n-1] = false
|
||||
*row = (*row)[:len(*row)-1]
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 解法三 二进制位操作法
|
||||
// class Solution {
|
||||
// public:
|
||||
// int totalNQueens(int n) {
|
||||
// int ans=0;
|
||||
// int row=0,leftDiagonal=0,rightDiagonal=0;
|
||||
// int bit=(1<<n)-1;//to clear high bits of the 32-bit int
|
||||
// Queens(bit,row,leftDiagonal,rightDiagonal,ans);
|
||||
// return ans;
|
||||
// }
|
||||
// void Queens(int bit,int row,int leftDiagonal,int rightDiagonal,int &ans){
|
||||
// int cur=(~(row|leftDiagonal|rightDiagonal))&bit;//possible place for this queen
|
||||
// if (!cur) return;//no pos for this queen
|
||||
// while(cur){
|
||||
// int curPos=(cur&(~cur + 1))&bit;//choose possible place in the right
|
||||
// //update row,ld and rd
|
||||
// row+=curPos;
|
||||
// if (row==bit) ans++;//last row
|
||||
// else Queens(bit,row,((leftDiagonal|curPos)<<1)&bit,((rightDiagonal|curPos)>>1)&bit,ans);
|
||||
// cur-=curPos;//for next possible place
|
||||
// row-=curPos;//reset row
|
||||
// }
|
||||
// }
|
||||
// };
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user