mirror of
https://github.com/halfrost/LeetCode-Go.git
synced 2025-07-05 08:27:30 +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 中,等待扫到“另一半”数字的时候,再取出来返回结果。
|
51
leetcode/0002.Add-Two-Numbers/2. Add Two Numbers.go
Normal file
51
leetcode/0002.Add-Two-Numbers/2. Add Two Numbers.go
Normal file
@ -0,0 +1,51 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"github.com/halfrost/LeetCode-Go/structures"
|
||||
)
|
||||
|
||||
// ListNode define
|
||||
type ListNode = structures.ListNode
|
||||
|
||||
/**
|
||||
* 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
|
||||
}
|
81
leetcode/0002.Add-Two-Numbers/2. Add Two Numbers_test.go
Normal file
81
leetcode/0002.Add-Two-Numbers/2. Add Two Numbers_test.go
Normal file
@ -0,0 +1,81 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/halfrost/LeetCode-Go/structures"
|
||||
)
|
||||
|
||||
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, structures.List2Ints(addTwoNumbers(structures.Ints2List(p.one), structures.Ints2List(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,29 @@
|
||||
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
|
||||
}
|
||||
|
||||
func max(a int, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
@ -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 题类似,用的思想都是"滑动窗口"。
|
||||
|
||||
滑动窗口的右边界不断的右移,只要没有重复的字符,就持续向右扩大窗口边界。一旦出现了重复字符,就需要缩小左边界,直到重复的字符移出了左边界,然后继续移动滑动窗口的右边界。以此类推,每次移动需要计算当前长度,并判断是否需要更新最大长度,最终最大的值就是题目中的所求。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,57 @@
|
||||
package leetcode
|
||||
|
||||
func findMedianSortedArrays(nums1 []int, nums2 []int) float64 {
|
||||
// 假设 nums1 的长度小
|
||||
if len(nums1) > len(nums2) {
|
||||
return findMedianSortedArrays(nums2, nums1)
|
||||
}
|
||||
low, high, k, nums1Mid, nums2Mid := 0, len(nums1), (len(nums1)+len(nums2)+1)>>1, 0, 0
|
||||
for low <= high {
|
||||
// nums1: ……………… nums1[nums1Mid-1] | nums1[nums1Mid] ……………………
|
||||
// nums2: ……………… nums2[nums2Mid-1] | nums2[nums2Mid] ……………………
|
||||
nums1Mid = low + (high-low)>>1 // 分界限右侧是 mid,分界线左侧是 mid - 1
|
||||
nums2Mid = k - nums1Mid
|
||||
if nums1Mid > 0 && nums1[nums1Mid-1] > nums2[nums2Mid] { // nums1 中的分界线划多了,要向左边移动
|
||||
high = nums1Mid - 1
|
||||
} else if nums1Mid != len(nums1) && nums1[nums1Mid] < nums2[nums2Mid-1] { // nums1 中的分界线划少了,要向右边移动
|
||||
low = nums1Mid + 1
|
||||
} else {
|
||||
// 找到合适的划分了,需要输出最终结果了
|
||||
// 分为奇数偶数 2 种情况
|
||||
break
|
||||
}
|
||||
}
|
||||
midLeft, midRight := 0, 0
|
||||
if nums1Mid == 0 {
|
||||
midLeft = nums2[nums2Mid-1]
|
||||
} else if nums2Mid == 0 {
|
||||
midLeft = nums1[nums1Mid-1]
|
||||
} else {
|
||||
midLeft = max(nums1[nums1Mid-1], nums2[nums2Mid-1])
|
||||
}
|
||||
if (len(nums1)+len(nums2))&1 == 1 {
|
||||
return float64(midLeft)
|
||||
}
|
||||
if nums1Mid == len(nums1) {
|
||||
midRight = nums2[nums2Mid]
|
||||
} else if nums2Mid == len(nums2) {
|
||||
midRight = nums1[nums1Mid]
|
||||
} else {
|
||||
midRight = min(nums1[nums1Mid], nums2[nums2Mid])
|
||||
}
|
||||
return float64(midLeft+midRight) / 2
|
||||
}
|
||||
|
||||
func max(a int, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func min(a int, b int) int {
|
||||
if a > b {
|
||||
return b
|
||||
}
|
||||
return a
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question4 struct {
|
||||
para4
|
||||
ans4
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para4 struct {
|
||||
nums1 []int
|
||||
nums2 []int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans4 struct {
|
||||
one float64
|
||||
}
|
||||
|
||||
func Test_Problem4(t *testing.T) {
|
||||
|
||||
qs := []question4{
|
||||
|
||||
question4{
|
||||
para4{[]int{1, 3}, []int{2}},
|
||||
ans4{2.0},
|
||||
},
|
||||
|
||||
question4{
|
||||
para4{[]int{1, 2}, []int{3, 4}},
|
||||
ans4{2.5},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 4------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans4, q.para4
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, findMedianSortedArrays(p.nums1, p.nums2))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
47
leetcode/0004.Median-of-Two-Sorted-Arrays/README.md
Executable file
47
leetcode/0004.Median-of-Two-Sorted-Arrays/README.md
Executable file
@ -0,0 +1,47 @@
|
||||
# [4. Median of Two Sorted Arrays](https://leetcode.com/problems/median-of-two-sorted-arrays/)
|
||||
|
||||
|
||||
## 题目:
|
||||
|
||||
There are two sorted arrays **nums1** and **nums2** of size m and n respectively.
|
||||
|
||||
Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
|
||||
|
||||
You may assume **nums1** and **nums2** cannot be both empty.
|
||||
|
||||
**Example 1:**
|
||||
|
||||
nums1 = [1, 3]
|
||||
nums2 = [2]
|
||||
|
||||
The median is 2.0
|
||||
|
||||
**Example 2:**
|
||||
|
||||
nums1 = [1, 2]
|
||||
nums2 = [3, 4]
|
||||
|
||||
The median is (2 + 3)/2 = 2.5
|
||||
|
||||
|
||||
## 题目大意
|
||||
|
||||
|
||||
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。
|
||||
|
||||
请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
|
||||
|
||||
你可以假设 nums1 和 nums2 不会同时为空。
|
||||
|
||||
|
||||
|
||||
## 解题思路
|
||||
|
||||
|
||||
- 给出两个有序数组,要求找出这两个数组合并以后的有序数组中的中位数。要求时间复杂度为 O(log (m+n))。
|
||||
- 这一题最容易想到的办法是把两个数组合并,然后取出中位数。但是合并有序数组的操作是 `O(max(n,m))` 的,不符合题意。看到题目给的 `log` 的时间复杂度,很容易联想到二分搜索。
|
||||
- 由于要找到最终合并以后数组的中位数,两个数组的总大小也知道,所以中间这个位置也是知道的。只需要二分搜索一个数组中切分的位置,另一个数组中切分的位置也能得到。为了使得时间复杂度最小,所以二分搜索两个数组中长度较小的那个数组。
|
||||
- 关键的问题是如何切分数组 1 和数组 2 。其实就是如何切分数组 1 。先随便二分产生一个 `midA`,切分的线何时算满足了中位数的条件呢?即,线左边的数都小于右边的数,即,`nums1[midA-1] ≤ nums2[midB] && nums2[midB-1] ≤ nums1[midA]` 。如果这些条件都不满足,切分线就需要调整。如果 `nums1[midA] < nums2[midB-1]`,说明 `midA` 这条线划分出来左边的数小了,切分线应该右移;如果 `nums1[midA-1] > nums2[midB]`,说明 midA 这条线划分出来左边的数大了,切分线应该左移。经过多次调整以后,切分线总能找到满足条件的解。
|
||||
- 假设现在找到了切分的两条线了,`数组 1` 在切分线两边的下标分别是 `midA - 1` 和 `midA`。`数组 2` 在切分线两边的下标分别是 `midB - 1` 和 `midB`。最终合并成最终数组,如果数组长度是奇数,那么中位数就是 `max(nums1[midA-1], nums2[midB-1])`。如果数组长度是偶数,那么中间位置的两个数依次是:`max(nums1[midA-1], nums2[midB-1])` 和 `min(nums1[midA], nums2[midB])`,那么中位数就是 `(max(nums1[midA-1], nums2[midB-1]) + min(nums1[midA], nums2[midB])) / 2`。图示见下图:
|
||||
|
||||

|
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,74 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"github.com/halfrost/LeetCode-Go/structures"
|
||||
)
|
||||
|
||||
// ListNode define
|
||||
type ListNode = structures.ListNode
|
||||
|
||||
/**
|
||||
* 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,64 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/halfrost/LeetCode-Go/structures"
|
||||
)
|
||||
|
||||
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}},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 19------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans19, q.para19
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, structures.List2Ints(removeNthFromEnd(structures.Ints2List(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,30 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"github.com/halfrost/LeetCode-Go/structures"
|
||||
)
|
||||
|
||||
// ListNode define
|
||||
type ListNode = structures.ListNode
|
||||
|
||||
/**
|
||||
* 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,81 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/halfrost/LeetCode-Go/structures"
|
||||
)
|
||||
|
||||
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, structures.List2Ints(mergeTwoLists(structures.Ints2List(p.one), structures.Ints2List(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,44 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"github.com/halfrost/LeetCode-Go/structures"
|
||||
)
|
||||
|
||||
// ListNode define
|
||||
type ListNode = structures.ListNode
|
||||
|
||||
/**
|
||||
* 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,104 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/halfrost/LeetCode-Go/structures"
|
||||
)
|
||||
|
||||
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, structures.Ints2List(qq))
|
||||
}
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", q.para23.one, structures.List2Ints(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 题的加强版。
|
45
leetcode/0024.Swap-Nodes-in-Pairs/24. Swap Nodes in Pairs.go
Normal file
45
leetcode/0024.Swap-Nodes-in-Pairs/24. Swap Nodes in Pairs.go
Normal file
@ -0,0 +1,45 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"github.com/halfrost/LeetCode-Go/structures"
|
||||
)
|
||||
|
||||
// ListNode define
|
||||
type ListNode = structures.ListNode
|
||||
|
||||
/**
|
||||
* 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,61 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/halfrost/LeetCode-Go/structures"
|
||||
)
|
||||
|
||||
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, structures.List2Ints(swapPairs(structures.Ints2List(p.one))))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
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,39 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"github.com/halfrost/LeetCode-Go/structures"
|
||||
)
|
||||
|
||||
// ListNode define
|
||||
type ListNode = structures.ListNode
|
||||
|
||||
/**
|
||||
* 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,56 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/halfrost/LeetCode-Go/structures"
|
||||
)
|
||||
|
||||
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, structures.List2Ints(reverseKGroup(structures.Ints2List(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 。
|
||||
|
||||
## 解题思路
|
||||
|
||||
这一题比较简单,直接写即可。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
100
leetcode/0029.Divide-Two-Integers/29. Divide Two Integers.go
Normal file
100
leetcode/0029.Divide-Two-Integers/29. Divide Two Integers.go
Normal file
@ -0,0 +1,100 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"math"
|
||||
)
|
||||
|
||||
// 解法一 递归版的二分搜索
|
||||
func divide(dividend int, divisor int) int {
|
||||
sign, res := -1, 0
|
||||
// low, high := 0, abs(dividend)
|
||||
if dividend == 0 {
|
||||
return 0
|
||||
}
|
||||
if divisor == 1 {
|
||||
return dividend
|
||||
}
|
||||
if dividend == math.MinInt32 && divisor == -1 {
|
||||
return math.MaxInt32
|
||||
}
|
||||
if dividend > 0 && divisor > 0 || dividend < 0 && divisor < 0 {
|
||||
sign = 1
|
||||
}
|
||||
if dividend > math.MaxInt32 {
|
||||
dividend = math.MaxInt32
|
||||
}
|
||||
// 如果把递归改成非递归,可以改成下面这段代码
|
||||
// for low <= high {
|
||||
// quotient := low + (high-low)>>1
|
||||
// if ((quotient+1)*abs(divisor) > abs(dividend) && quotient*abs(divisor) <= abs(dividend)) || ((quotient+1)*abs(divisor) >= abs(dividend) && quotient*abs(divisor) < abs(dividend)) {
|
||||
// if (quotient+1)*abs(divisor) == abs(dividend) {
|
||||
// res = quotient + 1
|
||||
// break
|
||||
// }
|
||||
// res = quotient
|
||||
// break
|
||||
// }
|
||||
// if (quotient+1)*abs(divisor) > abs(dividend) && quotient*abs(divisor) > abs(dividend) {
|
||||
// high = quotient - 1
|
||||
// }
|
||||
// if (quotient+1)*abs(divisor) < abs(dividend) && quotient*abs(divisor) < abs(dividend) {
|
||||
// low = quotient + 1
|
||||
// }
|
||||
// }
|
||||
res = binarySearchQuotient(0, abs(dividend), abs(divisor), abs(dividend))
|
||||
if res > math.MaxInt32 {
|
||||
return sign * math.MaxInt32
|
||||
}
|
||||
if res < math.MinInt32 {
|
||||
return sign * math.MinInt32
|
||||
}
|
||||
return sign * res
|
||||
}
|
||||
|
||||
func binarySearchQuotient(low, high, val, dividend int) int {
|
||||
quotient := low + (high-low)>>1
|
||||
if ((quotient+1)*val > dividend && quotient*val <= dividend) || ((quotient+1)*val >= dividend && quotient*val < dividend) {
|
||||
if (quotient+1)*val == dividend {
|
||||
return quotient + 1
|
||||
}
|
||||
return quotient
|
||||
}
|
||||
if (quotient+1)*val > dividend && quotient*val > dividend {
|
||||
return binarySearchQuotient(low, quotient-1, val, dividend)
|
||||
}
|
||||
if (quotient+1)*val < dividend && quotient*val < dividend {
|
||||
return binarySearchQuotient(quotient+1, high, val, dividend)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// 解法二 非递归版的二分搜索
|
||||
func divide1(divided int, divisor int) int {
|
||||
if divided == math.MinInt32 && divisor == -1 {
|
||||
return math.MaxInt32
|
||||
}
|
||||
result := 0
|
||||
sign := -1
|
||||
if divided > 0 && divisor > 0 || divided < 0 && divisor < 0 {
|
||||
sign = 1
|
||||
}
|
||||
dvd, dvs := abs(divided), abs(divisor)
|
||||
for dvd >= dvs {
|
||||
temp := dvs
|
||||
m := 1
|
||||
for temp<<1 <= dvd {
|
||||
temp <<= 1
|
||||
m <<= 1
|
||||
}
|
||||
dvd -= temp
|
||||
result += m
|
||||
}
|
||||
return sign * result
|
||||
}
|
||||
|
||||
func abs(a int) int {
|
||||
if a > 0 {
|
||||
return a
|
||||
}
|
||||
return -a
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question29 struct {
|
||||
para29
|
||||
ans29
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para29 struct {
|
||||
dividend int
|
||||
divisor int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans29 struct {
|
||||
one int
|
||||
}
|
||||
|
||||
func Test_Problem29(t *testing.T) {
|
||||
|
||||
qs := []question29{
|
||||
|
||||
question29{
|
||||
para29{10, 3},
|
||||
ans29{3},
|
||||
},
|
||||
|
||||
question29{
|
||||
para29{7, -3},
|
||||
ans29{-2},
|
||||
},
|
||||
|
||||
question29{
|
||||
para29{-1, 1},
|
||||
ans29{-1},
|
||||
},
|
||||
|
||||
question29{
|
||||
para29{1, -1},
|
||||
ans29{-1},
|
||||
},
|
||||
|
||||
question29{
|
||||
para29{2147483647, 3},
|
||||
ans29{715827882},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 29------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans29, q.para29
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, divide(p.dividend, p.divisor))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
47
leetcode/0029.Divide-Two-Integers/README.md
Executable file
47
leetcode/0029.Divide-Two-Integers/README.md
Executable file
@ -0,0 +1,47 @@
|
||||
# [29. Divide Two Integers](https://leetcode.com/problems/divide-two-integers/)
|
||||
|
||||
|
||||
## 题目:
|
||||
|
||||
Given two integers `dividend` and `divisor`, divide two integers without using multiplication, division and mod operator.
|
||||
|
||||
Return the quotient after dividing `dividend` by `divisor`.
|
||||
|
||||
The integer division should truncate toward zero.
|
||||
|
||||
**Example 1:**
|
||||
|
||||
Input: dividend = 10, divisor = 3
|
||||
Output: 3
|
||||
|
||||
**Example 2:**
|
||||
|
||||
Input: dividend = 7, divisor = -3
|
||||
Output: -2
|
||||
|
||||
**Note:**
|
||||
|
||||
- Both dividend and divisor will be 32-bit signed integers.
|
||||
- The divisor will never be 0.
|
||||
- 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 2^31 − 1 when the division result overflows.
|
||||
|
||||
|
||||
## 题目大意
|
||||
|
||||
给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。返回被除数 dividend 除以除数 divisor 得到的商。
|
||||
|
||||
说明:
|
||||
|
||||
- 被除数和除数均为 32 位有符号整数。
|
||||
- 除数不为 0。
|
||||
- 假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−2^31, 2^31 − 1]。本题中,如果除法结果溢出,则返回 2^31 − 1。
|
||||
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 给出除数和被除数,要求计算除法运算以后的商。注意值的取值范围在 [−2^31, 2^31 − 1] 之中。超过范围的都按边界计算。
|
||||
- 这一题可以用二分搜索来做。要求除法运算之后的商,把商作为要搜索的目标。商的取值范围是 [0, dividend],所以从 0 到被除数之间搜索。利用二分,找到(商 + 1 ) * 除数 > 被除数并且 商 * 除数 ≤ 被除数 或者 (商+1)* 除数 ≥ 被除数并且商 * 除数 < 被除数的时候,就算找到了商,其余情况继续二分即可。最后还要注意符号和题目规定的 Int32 取值范围。
|
||||
- 二分的写法常写错的 3 点:
|
||||
1. low ≤ high (注意二分循环退出的条件是小于等于)
|
||||
2. mid = low + (high-low)>>1 (防止溢出)
|
||||
3. low = mid + 1 ; high = mid - 1 (注意更新 low 和 high 的值,如果更新不对就会死循环)
|
@ -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,34 @@
|
||||
package leetcode
|
||||
|
||||
func search33(nums []int, target int) int {
|
||||
if len(nums) == 0 {
|
||||
return -1
|
||||
}
|
||||
low, high := 0, len(nums)-1
|
||||
for low <= high {
|
||||
mid := low + (high-low)>>1
|
||||
if nums[mid] == target {
|
||||
return mid
|
||||
} else if nums[mid] > nums[low] { // 在数值大的一部分区间里
|
||||
if nums[low] <= target && target < nums[mid] {
|
||||
high = mid - 1
|
||||
} else {
|
||||
low = mid + 1
|
||||
}
|
||||
} else if nums[mid] < nums[high] { // 在数值小的一部分区间里
|
||||
if nums[mid] < target && target <= nums[high] {
|
||||
low = mid + 1
|
||||
} else {
|
||||
high = mid - 1
|
||||
}
|
||||
} else {
|
||||
if nums[low] == nums[mid] {
|
||||
low++
|
||||
}
|
||||
if nums[high] == nums[mid] {
|
||||
high--
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question33 struct {
|
||||
para33
|
||||
ans33
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para33 struct {
|
||||
nums []int
|
||||
target int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans33 struct {
|
||||
one int
|
||||
}
|
||||
|
||||
func Test_Problem33(t *testing.T) {
|
||||
|
||||
qs := []question33{
|
||||
|
||||
question33{
|
||||
para33{[]int{3, 1}, 1},
|
||||
ans33{1},
|
||||
},
|
||||
|
||||
question33{
|
||||
para33{[]int{4, 5, 6, 7, 0, 1, 2}, 0},
|
||||
ans33{4},
|
||||
},
|
||||
|
||||
question33{
|
||||
para33{[]int{4, 5, 6, 7, 0, 1, 2}, 3},
|
||||
ans33{-1},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 33------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans33, q.para33
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, search33(p.nums, p.target))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
36
leetcode/0033.Search-in-Rotated-Sorted-Array/README.md
Executable file
36
leetcode/0033.Search-in-Rotated-Sorted-Array/README.md
Executable file
@ -0,0 +1,36 @@
|
||||
# [33. Search in Rotated Sorted Array](https://leetcode.com/problems/search-in-rotated-sorted-array/)
|
||||
|
||||
## 题目:
|
||||
|
||||
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
|
||||
|
||||
(i.e., `[0,1,2,4,5,6,7]` might become `[4,5,6,7,0,1,2]`).
|
||||
|
||||
You are given a target value to search. If found in the array return its index, otherwise return `-1`.
|
||||
|
||||
You may assume no duplicate exists in the array.
|
||||
|
||||
Your algorithm's runtime complexity must be in the order of *O*(log *n*).
|
||||
|
||||
**Example 1:**
|
||||
|
||||
Input: nums = [4,5,6,7,0,1,2], target = 0
|
||||
Output: 4
|
||||
|
||||
**Example 2:**
|
||||
|
||||
Input: nums = [4,5,6,7,0,1,2], target = 3
|
||||
Output: -1
|
||||
|
||||
|
||||
## 题目大意
|
||||
|
||||
假设按照升序排序的数组在预先未知的某个点上进行了旋转。( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。你可以假设数组中不存在重复的元素。
|
||||
|
||||
你的算法时间复杂度必须是 O(log n) 级别。
|
||||
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 给出一个数组,数组中本来是从小到大排列的,并且数组中没有重复数字。但是现在把后面随机一段有序的放到数组前面,这样形成了前后两端有序的子序列。在这样的一个数组里面查找一个数,设计一个 O(log n) 的算法。如果找到就输出数组的小标,如果没有找到,就输出 -1 。
|
||||
- 由于数组基本有序,虽然中间有一个“断开点”,还是可以使用二分搜索的算法来实现。现在数组前面一段是数值比较大的数,后面一段是数值偏小的数。如果 mid 落在了前一段数值比较大的区间内了,那么一定有 `nums[mid] > nums[low]`,如果是落在后面一段数值比较小的区间内,`nums[mid] ≤ nums[low]` 。如果 mid 落在了后一段数值比较小的区间内了,那么一定有 `nums[mid] < nums[high]`,如果是落在前面一段数值比较大的区间内,`nums[mid] ≤ nums[high]` 。还有 `nums[low] == nums[mid]` 和 `nums[high] == nums[mid]` 的情况,单独处理即可。最后找到则输出 mid,没有找到则输出 -1 。
|
@ -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 大基础变种的实现见代码)
|
@ -0,0 +1,17 @@
|
||||
package leetcode
|
||||
|
||||
func searchInsert(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 (mid == len(nums)-1) || (nums[mid+1] >= target) {
|
||||
return mid + 1
|
||||
}
|
||||
low = mid + 1
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question35 struct {
|
||||
para35
|
||||
ans35
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para35 struct {
|
||||
nums []int
|
||||
target int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans35 struct {
|
||||
one int
|
||||
}
|
||||
|
||||
func Test_Problem35(t *testing.T) {
|
||||
|
||||
qs := []question35{
|
||||
|
||||
question35{
|
||||
para35{[]int{1, 3, 5, 6}, 5},
|
||||
ans35{2},
|
||||
},
|
||||
|
||||
question35{
|
||||
para35{[]int{1, 3, 5, 6}, 2},
|
||||
ans35{1},
|
||||
},
|
||||
|
||||
question35{
|
||||
para35{[]int{1, 3, 5, 6}, 7},
|
||||
ans35{4},
|
||||
},
|
||||
|
||||
question35{
|
||||
para35{[]int{1, 3, 5, 6}, 0},
|
||||
ans35{0},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 35------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans35, q.para35
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, searchInsert(p.nums, p.target))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
40
leetcode/0035.Search-Insert-Position/README.md
Executable file
40
leetcode/0035.Search-Insert-Position/README.md
Executable file
@ -0,0 +1,40 @@
|
||||
# [35. Search Insert Position](https://leetcode.com/problems/search-insert-position/)
|
||||
|
||||
|
||||
## 题目:
|
||||
|
||||
Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.
|
||||
|
||||
You may assume no duplicates in the array.
|
||||
|
||||
**Example 1:**
|
||||
|
||||
Input: [1,3,5,6], 5
|
||||
Output: 2
|
||||
|
||||
**Example 2:**
|
||||
|
||||
Input: [1,3,5,6], 2
|
||||
Output: 1
|
||||
|
||||
**Example 3:**
|
||||
|
||||
Input: [1,3,5,6], 7
|
||||
Output: 4
|
||||
|
||||
**Example 4:**
|
||||
|
||||
Input: [1,3,5,6], 0
|
||||
Output: 0
|
||||
|
||||
|
||||
## 题目大意
|
||||
|
||||
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
|
||||
|
||||
你可以假设数组中无重复元素。
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 给出一个已经从小到大排序后的数组,要求在数组中找到插入 target 元素的位置。
|
||||
- 这一题是经典的二分搜索的变种题,在有序数组中找到最后一个比 target 小的元素。
|
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 就立即返回结果,即所求。
|
23
leetcode/0042.Trapping-Rain-Water/42. Trapping Rain Water.go
Normal file
23
leetcode/0042.Trapping-Rain-Water/42. Trapping Rain Water.go
Normal file
@ -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
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user