diff --git a/animation-simulation/二分查找及其变种/leetcode 81不完全有序查找目标元素(包含重复值) .md b/animation-simulation/二分查找及其变种/leetcode 81不完全有序查找目标元素(包含重复值) .md
index 2e666cb..af8da3f 100644
--- a/animation-simulation/二分查找及其变种/leetcode 81不完全有序查找目标元素(包含重复值) .md
+++ b/animation-simulation/二分查找及其变种/leetcode 81不完全有序查找目标元素(包含重复值) .md
@@ -73,3 +73,35 @@ class Solution {
}
}
```
+
+Go Code:
+
+```go
+func search(nums []int, target int) bool {
+ l, r := 0, len(nums) - 1
+ for l <= r {
+ m := l + (r - l) / 2
+ if nums[m] == target {
+ return true
+ }
+ // 先判断哪边是递增的,再查找范围
+ if nums[m] == nums[l] {
+ l++
+ } else if nums[l] < nums[m] {
+ // 判断target是否在有序的那边就行了。
+ if nums[l] <= target && target < nums[m] {
+ r = m - 1
+ } else {
+ l = m + 1
+ }
+ } else if nums[l] > nums[m] {
+ if nums[m] < target && target <= nums[r] {
+ l = m + 1
+ } else {
+ r = m - 1
+ }
+ }
+ }
+ return false
+}
+```
diff --git a/animation-simulation/二分查找及其变种/leetcode153搜索旋转数组的最小值.md b/animation-simulation/二分查找及其变种/leetcode153搜索旋转数组的最小值.md
index 5ab4c35..bd4447d 100644
--- a/animation-simulation/二分查找及其变种/leetcode153搜索旋转数组的最小值.md
+++ b/animation-simulation/二分查找及其变种/leetcode153搜索旋转数组的最小值.md
@@ -104,3 +104,23 @@ public:
}
};
```
+
+Go Code:
+
+```go
+func findMin(nums []int) int {
+ l, r := 0, len(nums) - 1
+ for l < r {
+ if nums[l] < nums[r] {
+ return nums[l]
+ }
+ m := l + (r - l) / 2
+ if nums[l] > nums[m] {
+ r = m
+ } else {
+ l = m + 1
+ }
+ }
+ return nums[l]
+}
+```
diff --git a/animation-simulation/二分查找及其变种/leetcode33不完全有序查找目标元素(不包含重复值).md b/animation-simulation/二分查找及其变种/leetcode33不完全有序查找目标元素(不包含重复值).md
index 6960c09..c9f6a73 100644
--- a/animation-simulation/二分查找及其变种/leetcode33不完全有序查找目标元素(不包含重复值).md
+++ b/animation-simulation/二分查找及其变种/leetcode33不完全有序查找目标元素(不包含重复值).md
@@ -127,4 +127,34 @@ class Solution {
}
```
-##
+Go Code:
+
+```go
+func search(nums []int, target int) int {
+ l, r := 0, len(nums) - 1
+ for l <= r {
+ m := (l + r) / 2
+ if target == nums[m] {
+ return m
+ }
+ // 先判断哪边是有序的
+ if nums[m] < nums[r] {
+ // 再判断target在左右哪边
+ if target > nums[m] && target <= nums[r] {
+ l = m + 1
+ } else {
+ r = m - 1
+ }
+ } else {
+ if target < nums[m] && target >= nums[l] {
+ r = m - 1
+ } else {
+ l = m + 1
+ }
+ }
+ }
+ return -1
+}
+```
+
+##
diff --git a/animation-simulation/二分查找及其变种/leetcode34查找第一个位置和最后一个位置.md b/animation-simulation/二分查找及其变种/leetcode34查找第一个位置和最后一个位置.md
index 5bd9cab..8460644 100644
--- a/animation-simulation/二分查找及其变种/leetcode34查找第一个位置和最后一个位置.md
+++ b/animation-simulation/二分查找及其变种/leetcode34查找第一个位置和最后一个位置.md
@@ -166,3 +166,45 @@ class Solution {
}
}
```
+
+Go Code:
+
+```go
+func searchRange(nums []int, target int) []int {
+ upper := upperBound(nums, target)
+ lower := lowerBound(nums, target)
+
+ if (upper < lower) {
+ return []int{-1, -1}
+ }
+ return []int{lower, upper}
+}
+
+// upperBound 计算上边界
+func upperBound(nums []int, target int) int {
+ l, r := 0, len(nums) - 1
+ for l <= r {
+ m := l + (r - l) / 2
+ if target >= nums[m] {
+ l = m + 1
+ } else if target < nums[m] {
+ r = m - 1
+ }
+ }
+ return r
+}
+
+// lowerBound 计算下边界
+func lowerBound(nums []int, target int) int {
+ l, r := 0, len(nums) - 1
+ for l <= r {
+ m := l + (r - l) / 2
+ if target <= nums[m] {
+ r = m - 1
+ } else if target > nums[m] {
+ l = m + 1
+ }
+ }
+ return l
+}
+```
diff --git a/animation-simulation/二分查找及其变种/leetcode35搜索插入位置.md b/animation-simulation/二分查找及其变种/leetcode35搜索插入位置.md
index 1268ca7..235ebb6 100644
--- a/animation-simulation/二分查找及其变种/leetcode35搜索插入位置.md
+++ b/animation-simulation/二分查找及其变种/leetcode35搜索插入位置.md
@@ -1,8 +1,8 @@
-> 如果阅读时,发现错误,或者动画不可以显示的问题可以添加我微信好友 **[tan45du_one](https://raw.githubusercontent.com/tan45du/tan45du.github.io/master/个人微信.15egrcgqd94w.jpg)** ,备注 github + 题目 + 问题 向我反馈
+> 如果阅读时,发现错误,或者动画不可以显示的问题可以添加我微信好友 **[tan45du_one](https://raw.githubusercontent.com/tan45du/tan45du.github.io/master/个人微信.15egrcgqd94w.jpg)** ,备注 github + 题目 + 问题 向我反馈
>
> 感谢支持,该仓库会一直维护,希望对各位有一丢丢帮助。
>
-> 另外希望手机阅读的同学可以来我的 [**公众号:袁厨的算法小屋**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png) 两个平台同步,想要和题友一起刷题,互相监督的同学,可以在我的小屋点击[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)进入。
+> 另外希望手机阅读的同学可以来我的 [**公众号:袁厨的算法小屋**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png) 两个平台同步,想要和题友一起刷题,互相监督的同学,可以在我的小屋点击[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)进入。
#### [35. 搜索插入位置](https://leetcode-cn.com/problems/search-insert-position/)
@@ -52,10 +52,10 @@ class Solution {
//查询成功
if (target == nums[mid]) {
return mid;
- //右区间
+ //右区间
} else if (nums[mid] < target) {
- left = mid + 1;
- //左区间
+ left = mid + 1;
+ //左区间
} else if (nums[mid] > target) {
right = mid - 1;
}
@@ -65,3 +65,23 @@ class Solution {
}
}
```
+
+Go Code:
+
+```go
+func searchInsert(nums []int, target int) int {
+ l, r := 0, len(nums) - 1
+ for l <= r {
+ m := l + (r - l) / 2
+ if target == nums[m] {
+ return m
+ }
+ if target < nums[m] {
+ r = m - 1
+ } else if target > nums[m] {
+ l = m + 1
+ }
+ }
+ return l
+}
+```
diff --git a/animation-simulation/二分查找及其变种/二维数组的二分查找.md b/animation-simulation/二分查找及其变种/二维数组的二分查找.md
index 11635f8..be00baa 100644
--- a/animation-simulation/二分查找及其变种/二维数组的二分查找.md
+++ b/animation-simulation/二分查找及其变种/二维数组的二分查找.md
@@ -83,3 +83,30 @@ class Solution {
}
}
```
+
+Go Code:
+
+```go
+func searchMatrix(matrix [][]int, target int) bool {
+ if len(matrix) == 0 {
+ return false
+ }
+ row, col := len(matrix), len(matrix[0])
+ // 将二维数组拉平为一维。
+ l, r := 0, row * col - 1
+ for l <= r {
+ m := l + (r - l) / 2
+ // 将一维的坐标转换为二维
+ x, y := m / col, m % col
+ if matrix[x][y] == target {
+ return true
+ } else if matrix[x][y] < target {
+ l = m + 1
+ } else if matrix[x][y] > target {
+ // 二分查找时,把所有的情况都要写出来,避免直接else
+ r = m - 1
+ }
+ }
+ return false
+}
+```
diff --git a/animation-simulation/二叉树/二叉树中序遍历(迭代).md b/animation-simulation/二叉树/二叉树中序遍历(迭代).md
index 7b58f4c..4a5c188 100644
--- a/animation-simulation/二叉树/二叉树中序遍历(迭代).md
+++ b/animation-simulation/二叉树/二叉树中序遍历(迭代).md
@@ -34,7 +34,7 @@ class Solution {
TreeNode cur = new TreeNode(-1);
cur = root;
Stack stack = new Stack<>();
- while (!stack.isEmpty() || cur != null) {
+ while (!stack.isEmpty() || cur != null) {
//找到当前应该遍历的那个节点
while (cur != null) {
stack.push(cur);
@@ -47,7 +47,7 @@ class Solution {
cur = temp.right;
}
return arr;
- }
+ }
}
```
@@ -78,4 +78,30 @@ class Solution {
}
```
-###
+Go Code:
+
+```go
+func inorderTraversal(root *TreeNode) []int {
+ res := []int{}
+ if root == nil {
+ return res
+ }
+ stk := []*TreeNode{}
+ cur := root
+ for len(stk) != 0 || cur != nil {
+ // 找到当前应该遍历的那个节点,并且把左子节点都入栈
+ for cur != nil {
+ stk = append(stk, cur)
+ cur = cur.Left
+ }
+ // 没有左子节点,则开始执行出栈操作
+ temp := stk[len(stk) - 1]
+ stk = stk[: len(stk) - 1]
+ res = append(res, temp.Val)
+ cur = temp.Right
+ }
+ return res
+}
+```
+
+###
diff --git a/animation-simulation/二叉树/二叉树基础.md b/animation-simulation/二叉树/二叉树基础.md
index 49a76e2..36a7d23 100644
--- a/animation-simulation/二叉树/二叉树基础.md
+++ b/animation-simulation/二叉树/二叉树基础.md
@@ -426,6 +426,34 @@ class Solution {
}
```
+Go Code:
+
+```go
+func levelOrder(root *TreeNode) [][]int {
+ res := [][]int{}
+ if root == nil {
+ return res
+ }
+ // 初始化队列时,记得把root节点加进去。
+ que := []*TreeNode{root}
+ for len(que) != 0 {
+ t := []int{}
+ // 这里一定要先求出来que的长度,因为在迭代的过程中,que的长度是变化的。
+ l := len(que)
+ for i := 0; i < l; i++ {
+ temp := que[0]
+ que = que[1:]
+ // 子节点不为空,就入队
+ if temp.Left != nil { que = append(que, temp.Left) }
+ if temp.Right != nil { que = append(que, temp.Right) }
+ t = append(t, temp.Val)
+ }
+ res = append(res, t)
+ }
+ return res
+}
+```
+
时间复杂度:O(n) 空间复杂度:O(n)
大家如果吃透了二叉树的层序遍历的话,可以顺手把下面几道题目解决掉,思路一致,甚至都不用拐弯
diff --git a/animation-simulation/二叉树/二叉树的前序遍历(栈).md b/animation-simulation/二叉树/二叉树的前序遍历(栈).md
index a40de9b..82cad7d 100644
--- a/animation-simulation/二叉树/二叉树的前序遍历(栈).md
+++ b/animation-simulation/二叉树/二叉树的前序遍历(栈).md
@@ -49,10 +49,10 @@ class Solution {
public List preorderTraversal(TreeNode root) {
List list = new ArrayList<>();
Stack stack = new Stack<>();
- if (root == null) return list;
+ if (root == null) return list;
stack.push(root);
while (!stack.isEmpty()) {
- TreeNode temp = stack.pop();
+ TreeNode temp = stack.pop();
if (temp.right != null) {
stack.push(temp.right);
}
@@ -95,3 +95,27 @@ class Solution {
}
}
```
+
+Go Code:
+
+```go
+func preorderTraversal(root *TreeNode) []int {
+ res := []int{}
+ if root == nil {
+ return res
+ }
+ stk := []*TreeNode{root}
+ for len(stk) != 0 {
+ temp := stk[len(stk) - 1]
+ stk = stk[: len(stk) - 1]
+ if temp.Right != nil {
+ stk = append(stk, temp.Right)
+ }
+ if temp.Left != nil {
+ stk = append(stk, temp.Left)
+ }
+ res = append(res, temp.Val)
+ }
+ return res
+}
+```
diff --git a/animation-simulation/二叉树/二叉树的后续遍历 (迭代).md b/animation-simulation/二叉树/二叉树的后续遍历 (迭代).md
index 280c3e3..cc6fd8b 100644
--- a/animation-simulation/二叉树/二叉树的后续遍历 (迭代).md
+++ b/animation-simulation/二叉树/二叉树的后续遍历 (迭代).md
@@ -12,7 +12,7 @@
我们知道后序遍历的顺序是,` 对于树中的某节点, 先遍历该节点的左子树, 再遍历其右子树, 最后遍历该节点`。
-那么我们如何利用栈来解决呢?
+那么我们如何利用栈来解决呢?
我们直接来看动画,看动画之前,但是我们`需要带着问题看动画`,问题搞懂之后也就搞定了后序遍历。
@@ -104,6 +104,36 @@ class Solution {
}
```
+Go Code:
+
+```go
+func postorderTraversal(root *TreeNode) []int {
+ res := []int{}
+ if root == nil {
+ return res
+ }
+ stk := []*TreeNode{}
+ cur := root
+ var pre *TreeNode
+ for len(stk) != 0 || cur != nil {
+ for cur != nil {
+ stk = append(stk, cur)
+ cur = cur.Left
+ }
+ // 这里符合本文最后的说法,使用先获取栈顶元素但是不弹出,根据栈顶元素的情况进行响应的处理。
+ temp := stk[len(stk) - 1]
+ if temp.Right == nil || temp.Right == pre {
+ stk = stk[: len(stk) - 1]
+ res = append(res, temp.Val)
+ pre = temp
+ } else {
+ cur = temp.Right
+ }
+ }
+ return res
+}
+```
+
当然也可以修改下代码逻辑将 `cur = stack.pop()` 改成 `cur = stack.peek()`,下面再修改一两行代码也可以实现,这里这样写是方便动画模拟,大家可以随意发挥。
时间复杂度 O(n), 空间复杂度 O(n)
diff --git a/animation-simulation/前缀和/leetcode523连续的子数组和.md b/animation-simulation/前缀和/leetcode523连续的子数组和.md
index d458082..8662f2a 100644
--- a/animation-simulation/前缀和/leetcode523连续的子数组和.md
+++ b/animation-simulation/前缀和/leetcode523连续的子数组和.md
@@ -100,3 +100,35 @@ public:
}
};
```
+
+Go Code:
+
+```go
+func checkSubarraySum(nums []int, k int) bool {
+ m := map[int]int{}
+ // 由于前缀和%k可能为0,所以需要给出没有元素的时候,索引位置,即-1
+ m[0] = -1
+ sum := 0
+ for i, num := range nums {
+ sum += num
+ key := sum % k
+ /*
+ // 题目中告诉k >= 1
+ key := sum
+ if k != 0 {
+ key = sum % k
+ }
+ */
+ if v, ok := m[key]; ok {
+ if i - v >= 2 {
+ return true
+ }
+ // 避免更新最小索引
+ continue
+ }
+ // 保存的是最小的索引
+ m[key] = i
+ }
+ return false
+}
+```
diff --git a/animation-simulation/前缀和/leetcode560和为K的子数组.md b/animation-simulation/前缀和/leetcode560和为K的子数组.md
index 60cb9b3..5464a2f 100644
--- a/animation-simulation/前缀和/leetcode560和为K的子数组.md
+++ b/animation-simulation/前缀和/leetcode560和为K的子数组.md
@@ -182,3 +182,24 @@ public:
}
};
```
+
+Go Code:
+
+```GO
+func subarraySum(nums []int, k int) int {
+ m := map[int]int{}
+ // m存的是前缀和,没有元素的时候,和为0,且有1个子数组(空数组)满足条件,即m[0] = 1
+ m[0] = 1
+ sum := 0
+ cnt := 0
+ for _, num := range nums {
+ sum += num
+ if v, ok := m[sum - k]; ok {
+ cnt += v
+ }
+ // 更新满足前缀和的子数组数量
+ m[sum]++
+ }
+ return cnt
+}
+```
diff --git a/animation-simulation/前缀和/leetcode724寻找数组的中心索引.md b/animation-simulation/前缀和/leetcode724寻找数组的中心索引.md
index cb7d5d6..37cd6ff 100644
--- a/animation-simulation/前缀和/leetcode724寻找数组的中心索引.md
+++ b/animation-simulation/前缀和/leetcode724寻找数组的中心索引.md
@@ -107,3 +107,23 @@ public:
}
};
```
+
+Go Code:
+
+```go
+func pivotIndex(nums []int) int {
+ presum := 0
+ for _, num := range nums {
+ presum += num
+ }
+ var leftsum int
+ for i, num := range nums {
+ // 比较左半和右半是否相同
+ if presum - leftsum - num == leftsum {
+ return i
+ }
+ leftsum += num
+ }
+ return -1
+}
+```
diff --git a/animation-simulation/前缀和/leetcode974和可被K整除的子数组.md b/animation-simulation/前缀和/leetcode974和可被K整除的子数组.md
index 8a10495..4ff58c6 100644
--- a/animation-simulation/前缀和/leetcode974和可被K整除的子数组.md
+++ b/animation-simulation/前缀和/leetcode974和可被K整除的子数组.md
@@ -129,3 +129,21 @@ public:
}
};
```
+
+Go Code:
+
+```go
+func subarraysDivByK(nums []int, k int) int {
+ m := make(map[int]int)
+ cnt := 0
+ sum := 0
+ m[0] = 1
+ for _, num := range nums {
+ sum += num
+ key := (sum % k + k) % k
+ cnt += m[key]
+ m[key]++
+ }
+ return cnt
+}
+```
diff --git a/animation-simulation/单调队列单调栈/leetcode739每日温度.md b/animation-simulation/单调队列单调栈/leetcode739每日温度.md
index 6ef56d0..9ba0b91 100644
--- a/animation-simulation/单调队列单调栈/leetcode739每日温度.md
+++ b/animation-simulation/单调队列单调栈/leetcode739每日温度.md
@@ -58,3 +58,25 @@ class Solution {
}
}
```
+
+GO Code:
+
+```go
+func dailyTemperatures(temperatures []int) []int {
+ l := len(temperatures)
+ if l == 0 {
+ return temperatures
+ }
+ stack := []int{}
+ arr := make([]int, l)
+ for i := 0; i < l; i++ {
+ for len(stack) != 0 && temperatures[i] > temperatures[stack[len(stack) - 1]] {
+ idx := stack[len(stack) - 1]
+ arr[idx] = i - idx
+ stack = stack[: len(stack) - 1]
+ }
+ // 栈保存的是索引
+ stack = append(stack, i)
+ }
+ return arr
+}
diff --git a/animation-simulation/单调队列单调栈/剑指offer59队列的最大值.md b/animation-simulation/单调队列单调栈/剑指offer59队列的最大值.md
index dd481e9..86044b7 100644
--- a/animation-simulation/单调队列单调栈/剑指offer59队列的最大值.md
+++ b/animation-simulation/单调队列单调栈/剑指offer59队列的最大值.md
@@ -89,4 +89,56 @@ class MaxQueue {
}
```
+GO Code:
+
+```go
+type MaxQueue struct {
+ que []int // 普通队列
+ deq []int // 双端队列
+ size int // que的队列长度
+}
+
+
+func Constructor() MaxQueue {
+ return MaxQueue{
+ que: []int{},
+ deq: []int{},
+ }
+}
+
+// Is_empty 表示队列是否为空
+func (mq *MaxQueue) Is_empty() bool {
+ return mq.size == 0
+}
+
+// Max_value 取最大值值,返回我们双端队列的对头即可,因为我们双端队列是单调递减的嘛
+func (mq *MaxQueue) Max_value() int {
+ if mq.Is_empty() { return -1 }
+ return mq.deq[0]
+}
+
+// Push_back 入队
+func (mq *MaxQueue) Push_back(value int) {
+ mq.que = append(mq.que, value)
+ // 维护单调递减队列
+ for len(mq.deq) != 0 && mq.deq[len(mq.deq) - 1] < value {
+ mq.deq = mq.deq[:len(mq.deq) - 1]
+ }
+ mq.deq = append(mq.deq, value)
+ mq.size++
+}
+
+// Pop_front 弹出队列头元素,并且返回其值。
+func (mq *MaxQueue) Pop_front() int {
+ if mq.Is_empty() { return -1 }
+ ans := mq.que[0]
+ mq.que = mq.que[1:]
+ if mq.deq[0] == ans {
+ mq.deq = mq.deq[1:]
+ }
+ mq.size--
+ return ans
+}
+```
+
###
diff --git a/animation-simulation/单调队列单调栈/接雨水.md b/animation-simulation/单调队列单调栈/接雨水.md
index f1c93af..69b6950 100644
--- a/animation-simulation/单调队列单调栈/接雨水.md
+++ b/animation-simulation/单调队列单调栈/接雨水.md
@@ -117,4 +117,35 @@ class Solution {
}
```
+GO Code:
+
+```go
+func trap(height []int) int {
+ stack := []int{}
+ water := 0
+ // 最左边部分不会接雨水,左边持续升高时,stack都会弹出所有元素。
+ for i := 0; i< len(height); i++ {
+ for len(stack) != 0 && height[i] > height[stack[len(stack) - 1]] {
+ popnum := stack[len(stack) - 1]
+ // 出现相同高度的情况(其实也可以不用处理,如果不处理,相同高度时后面的hig为0,会产生很多无效的计算)
+ for len(stack) != 0 && height[popnum] == height[stack[len(stack) - 1]] {
+ stack = stack[:len(stack) - 1]
+ }
+ if len(stack) == 0 { break }
+ le, ri := stack[len(stack) - 1], i
+ hig := min(height[ri], height[le]) - height[popnum]
+ wid := ri - le - 1
+ water += wid * hig
+ }
+ stack = append(stack, i)
+ }
+ return water
+}
+
+func min(a, b int) int {
+ if a < b { return a }
+ return b
+}
+```
+
###
diff --git a/animation-simulation/单调队列单调栈/最小栈.md b/animation-simulation/单调队列单调栈/最小栈.md
index c080e81..56b09ce 100644
--- a/animation-simulation/单调队列单调栈/最小栈.md
+++ b/animation-simulation/单调队列单调栈/最小栈.md
@@ -73,4 +73,47 @@ class MinStack {
}
```
+GO Code:
+
+```go
+type MinStack struct {
+ stack []int
+ minStk []int
+}
+
+/** initialize your data structure here. */
+func Constructor() MinStack {
+ return MinStack{
+ stack: []int{},
+ minStk: []int{},
+ }
+}
+
+// Push 入栈,如果插入值,当前插入值小于栈顶元素,则入栈,栈顶元素保存的则为当前栈的最小元素
+func (m *MinStack) Push(x int) {
+ m.stack = append(m.stack, x)
+ if len(m.minStk) == 0 || m.minStk[len(m.minStk) - 1] >= x {
+ m.minStk = append(m.minStk, x)
+ }
+}
+
+// Pop 出栈,如果stack出栈等于minStk栈顶元素,则说明此时栈内的最小元素改变了。
+func (m *MinStack) Pop() {
+ temp := m.stack[len(m.stack) - 1]
+ m.stack = m.stack[: len(m.stack) - 1]
+ if temp == m.minStk[len(m.minStk) - 1] {
+ m.minStk = m.minStk[: len(m.minStk) - 1]
+ }
+}
+
+// Top stack的栈顶元素
+func (m *MinStack) Top() int {
+ return m.stack[len(m.stack) - 1]
+}
+
+// GetMin minStk的栈顶元素
+func (m *MinStack) GetMin() int {
+ return m.minStk[len(m.minStk) - 1]
+}
+```
###
diff --git a/animation-simulation/单调队列单调栈/滑动窗口的最大值.md b/animation-simulation/单调队列单调栈/滑动窗口的最大值.md
index 05362e1..dc98a1a 100644
--- a/animation-simulation/单调队列单调栈/滑动窗口的最大值.md
+++ b/animation-simulation/单调队列单调栈/滑动窗口的最大值.md
@@ -72,3 +72,37 @@ class Solution {
}
}
```
+
+GO Code:
+
+```go
+func maxSlidingWindow(nums []int, k int) []int {
+ l := len(nums)
+ if l == 0 {
+ return nums
+ }
+
+ arr := []int{}
+ // 维护一个单调递减的双向队列
+ deque := []int{}
+ for i := 0; i < k; i++ {
+ for len(deque) != 0 && deque[len(deque) - 1] < nums[i] {
+ deque = deque[:len(deque) - 1]
+ }
+ deque = append(deque, nums[i])
+ }
+
+ arr = append(arr, deque[0])
+ for i := k; i < l; i++ {
+ if nums[i - k] == deque[0] {
+ deque = deque[1:]
+ }
+ for len(deque) != 0 && deque[len(deque) - 1] < nums[i] {
+ deque = deque[:len(deque) - 1]
+ }
+ deque = append(deque, nums[i])
+ arr = append(arr, deque[0])
+ }
+ return arr
+}
+```
diff --git a/animation-simulation/数组篇/leetcode1438绝对值不超过限制的最长子数组.md b/animation-simulation/数组篇/leetcode1438绝对值不超过限制的最长子数组.md
index e89e1d8..04f3e92 100644
--- a/animation-simulation/数组篇/leetcode1438绝对值不超过限制的最长子数组.md
+++ b/animation-simulation/数组篇/leetcode1438绝对值不超过限制的最长子数组.md
@@ -260,3 +260,48 @@ class Solution {
}
}
```
+
+
+Go Code:
+
+```go
+func longestSubarray(nums []int, limit int) int {
+ maxdeq := []int{} // 递减队列
+ mindeq := []int{} // 递增队列
+
+ length := len(nums)
+ left, right, maxwin := 0, 0, 0
+ for right < length {
+ for len(maxdeq) != 0 && maxdeq[len(maxdeq) - 1] < nums[right] {
+ maxdeq = maxdeq[: len(maxdeq) - 1]
+ }
+ maxdeq = append(maxdeq, nums[right])
+
+ for len(mindeq) != 0 && mindeq[len(mindeq) - 1] > nums[right] {
+ mindeq = mindeq[: len(mindeq) - 1]
+ }
+ mindeq = append(mindeq, nums[right])
+
+ for maxdeq[0] - mindeq[0] > limit {
+ if maxdeq[0] == nums[left] {
+ maxdeq = maxdeq[1:]
+ }
+ if mindeq[0] == nums[left] {
+ mindeq = mindeq[1:]
+ }
+ left++
+ }
+ maxwin = max(maxwin, right - left + 1)
+ right++
+ }
+ return maxwin
+}
+
+func max(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
+}
+```
+
diff --git a/animation-simulation/数组篇/leetcode1两数之和.md b/animation-simulation/数组篇/leetcode1两数之和.md
index 2f7e75b..27e672e 100644
--- a/animation-simulation/数组篇/leetcode1两数之和.md
+++ b/animation-simulation/数组篇/leetcode1两数之和.md
@@ -202,3 +202,20 @@ class Solution {
}
}
```
+
+
+Go Code:
+
+```go
+func twoSum(nums []int, target int) []int {
+ m := make(map[int]int)
+ for i, num := range nums {
+ if v, ok := m[target - num]; ok {
+ return []int{v, i}
+ }
+ m[num] = i
+ }
+ return []int{}
+}
+```
+
diff --git a/animation-simulation/数组篇/leetcode219数组中重复元素2.md b/animation-simulation/数组篇/leetcode219数组中重复元素2.md
index d38fe71..d0fce1b 100644
--- a/animation-simulation/数组篇/leetcode219数组中重复元素2.md
+++ b/animation-simulation/数组篇/leetcode219数组中重复元素2.md
@@ -45,7 +45,7 @@ class Solution {
if (map.containsKey(nums[i])) {
//判断是否小于K,如果小于等于则直接返回
int abs = Math.abs(i - map.get(nums[i]));
- if (abs <= k) return true;//小于等于则返回
+ if (abs <= k) return true;//小于等于则返回
}
//更新索引,此时有两种情况,不存在,或者存在时,将后出现的索引保存
map.put(nums[i],i);
@@ -72,7 +72,7 @@ class Solution:
# 判断是否小于K,如果小于等于则直接返回
a = abs(i - m[nums[i]])
if a <= k:
- return True# 小于等于则返回
+ return True# 小于等于则返回
# 更新索引,此时有两种情况,不存在,或者存在时,将后出现的索引保存
m[nums[i]] = i
return False
@@ -222,3 +222,25 @@ class Solution {
}
}
```
+
+Go Code:
+
+```go
+func containsNearbyDuplicate(nums []int, k int) bool {
+ length := len(nums)
+ if length == 0 {
+ return false
+ }
+ m := map[int]int{}
+ for i := 0; i < length; i++ {
+ if v, ok := m[nums[i]]; ok {
+ if i - v <= k {
+ return true
+ }
+ }
+ m[nums[i]] = i
+ }
+ return false
+}
+```
+
diff --git a/animation-simulation/数组篇/leetcode27移除元素.md b/animation-simulation/数组篇/leetcode27移除元素.md
index 8875367..128ad7e 100644
--- a/animation-simulation/数组篇/leetcode27移除元素.md
+++ b/animation-simulation/数组篇/leetcode27移除元素.md
@@ -182,3 +182,25 @@ class Solution {
}
}
```
+
+
+Go Code:
+
+```go
+func removeElement(nums []int, val int) int {
+ length := len(nums)
+ if length == 0 {
+ return 0
+ }
+ i := 0
+ for j := 0; j < length; j++ {
+ if nums[j] == val {
+ continue
+ }
+ nums[i] = nums[j]
+ i++
+ }
+ return i
+}
+```
+
diff --git a/animation-simulation/数组篇/leetcode41缺失的第一个正数.md b/animation-simulation/数组篇/leetcode41缺失的第一个正数.md
index a93de55..5c6deeb 100644
--- a/animation-simulation/数组篇/leetcode41缺失的第一个正数.md
+++ b/animation-simulation/数组篇/leetcode41缺失的第一个正数.md
@@ -273,3 +273,28 @@ public:
}
};
```
+
+
+Go Code:
+
+```go
+func firstMissingPositive(nums []int) int {
+ length := len(nums)
+ if length == 0 { return 1 }
+ for i := 0; i < length; i++ {
+ // 将不在正确位置的元素放在正确的位置上。
+ for nums[i] > 0 && nums[i] < length + 1 && nums[i] != i + 1 && nums[i] != nums[nums[i] - 1] {
+ j := nums[i] - 1
+ nums[i], nums[j] = nums[j], nums[i]
+ }
+ }
+ // 第一个不在正确位置上的元素就是结果。
+ for i := 0; i < length; i++ {
+ if nums[i] != i + 1 {
+ return i + 1
+ }
+ }
+ return length + 1
+}
+```
+
diff --git a/animation-simulation/数组篇/leetcode485最大连续1的个数.md b/animation-simulation/数组篇/leetcode485最大连续1的个数.md
index 66c07c2..501bc85 100644
--- a/animation-simulation/数组篇/leetcode485最大连续1的个数.md
+++ b/animation-simulation/数组篇/leetcode485最大连续1的个数.md
@@ -22,7 +22,7 @@
下面我们通过一个视频模拟代码执行步骤大家一下就能搞懂了。
-![leetcode485最长连续1的个数](https://cdn.jsdelivr.net/gh/tan45du/test1@master/20210122/leetcode485最长连续1的个数.7avzcthkit80.gif)
+ ![leetcode485最长连续1的个数](https://cdn.jsdelivr.net/gh/tan45du/test1@master/20210122/leetcode485最长连续1的个数.7avzcthkit80.gif)
下面我们直接看代码吧
@@ -207,3 +207,28 @@ public:
}
};
```
+
+Go Code:
+
+```go
+func findMaxConsecutiveOnes(nums []int) int {
+ cnt, maxCnt := 0, 0
+ for i := 0; i < len(nums); i++ {
+ if nums[i] == 1 {
+ cnt++
+ } else {
+ maxCnt = max(maxCnt, cnt)
+ cnt = 0
+ }
+ }
+ return max(maxCnt, cnt)
+}
+
+func max(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
+}
+```
+
diff --git a/animation-simulation/数组篇/leetcode54螺旋矩阵.md b/animation-simulation/数组篇/leetcode54螺旋矩阵.md
index 8685b9d..b666538 100644
--- a/animation-simulation/数组篇/leetcode54螺旋矩阵.md
+++ b/animation-simulation/数组篇/leetcode54螺旋矩阵.md
@@ -180,3 +180,42 @@ class Solution {
}
}
```
+
+
+Go Code:
+
+```go
+func spiralOrder(matrix [][]int) []int {
+ res := []int{}
+ left, right := 0, len(matrix[0]) - 1
+ top, down := 0, len(matrix) - 1
+
+ for {
+ for i := left; i <= right; i++ {
+ res = append(res, matrix[top][i])
+ }
+ top++
+ if top > down { break }
+
+ for i := top; i <= down; i++ {
+ res = append(res, matrix[i][right])
+ }
+ right--
+ if left > right { break }
+
+ for i := right; i >= left; i-- {
+ res = append(res, matrix[down][i])
+ }
+ down--
+ if top > down { break }
+
+ for i := down; i >= top; i-- {
+ res = append(res, matrix[i][left])
+ }
+ left++
+ if left > right { break }
+ }
+ return res
+}
+```
+
diff --git a/animation-simulation/数组篇/leetcode560和为K的子数组.md b/animation-simulation/数组篇/leetcode560和为K的子数组.md
index 2e73caf..2e339e6 100644
--- a/animation-simulation/数组篇/leetcode560和为K的子数组.md
+++ b/animation-simulation/数组篇/leetcode560和为K的子数组.md
@@ -217,3 +217,23 @@ public:
}
};
```
+
+Go Code:
+
+```go
+func subarraySum(nums []int, k int) int {
+ m := map[int]int{}
+ m[0] = 1
+ sum := 0
+ cnt := 0
+ for _, num := range nums {
+ sum += num
+ if v, ok := m[sum - k]; ok {
+ cnt += v
+ }
+ m[sum]++
+ }
+ return cnt
+}
+```
+
diff --git a/animation-simulation/数组篇/leetcode59螺旋矩阵2.md b/animation-simulation/数组篇/leetcode59螺旋矩阵2.md
index a43f204..dd5bf29 100644
--- a/animation-simulation/数组篇/leetcode59螺旋矩阵2.md
+++ b/animation-simulation/数组篇/leetcode59螺旋矩阵2.md
@@ -360,3 +360,49 @@ class Solution {
}
}
```
+
+
+Go Code:
+
+```go
+func generateMatrix(n int) [][]int {
+ res := make([][]int, n)
+ for i := 0; i < n; i++ {
+ res[i] = make([]int, n)
+ }
+ left, right := 0, n - 1
+ top, buttom := 0, n - 1
+ size, num := n * n, 1
+ for {
+ for i := left; i <= right; i++ {
+ res[top][i] = num
+ num++
+ }
+ top++
+ if num > size { break }
+
+ for i := top; i <= buttom; i++ {
+ res[i][right] = num
+ num++
+ }
+ right--
+ if num > size { break }
+
+ for i := right; i >= left; i-- {
+ res[buttom][i] = num
+ num++
+ }
+ buttom--
+ if num > size { break }
+
+ for i := buttom; i >= top; i-- {
+ res[i][left] = num
+ num++
+ }
+ left++
+ if num > size { break }
+ }
+ return res
+}
+```
+
diff --git a/animation-simulation/数组篇/leetcode66加一.md b/animation-simulation/数组篇/leetcode66加一.md
index 204a51b..8e02a98 100644
--- a/animation-simulation/数组篇/leetcode66加一.md
+++ b/animation-simulation/数组篇/leetcode66加一.md
@@ -2,7 +2,7 @@
>
> 感谢支持,该仓库会一直维护,希望对各位有一丢丢帮助。
>
-> 另外希望手机阅读的同学可以来我的 [**公众号:袁厨的算法小屋**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png) 两个平台同步,想要和题友一起刷题,互相监督的同学,可以在我的小屋点击[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)进入。
+> 另外希望手机阅读的同学可以来我的 [**公众号:袁厨的算法小屋**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png) 两个平台同步,想要和题友一起刷题,互相监督的同学,可以在我的小屋点击[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)进入。
#### [66. 加一](https://leetcode-cn.com/problems/plus-one/)
@@ -56,10 +56,10 @@ class Solution {
if (digits[i] != 0) {
return digits;
}
-
+
}
//第三种情况,因为数组初始化每一位都为0,我们只需将首位设为1即可
- int[] arr = new int[len+1];
+ int[] arr = new int[len+1];
arr[0] = 1;
return arr;
}
@@ -122,3 +122,20 @@ class Solution {
}
}
```
+
+Go Code:
+
+```go
+func plusOne(digits []int) []int {
+ l := len(digits)
+ for i := l - 1; i >= 0; i-- {
+ digits[i] = (digits[i] + 1) % 10
+ if digits[i] != 0 {
+ return digits
+ }
+ }
+ digits = append([]int{1}, digits...)
+ return digits
+}
+```
+
diff --git a/animation-simulation/数组篇/leetcode75颜色分类.md b/animation-simulation/数组篇/leetcode75颜色分类.md
index 4f69ce5..669bf80 100644
--- a/animation-simulation/数组篇/leetcode75颜色分类.md
+++ b/animation-simulation/数组篇/leetcode75颜色分类.md
@@ -48,7 +48,7 @@ class Solution {
//这里和三向切分不完全一致
int i = left;
int right = len-1;
-
+
while (i <= right) {
if (nums[i] == 2) {
swap(nums,i,right--);
@@ -57,7 +57,7 @@ class Solution {
} else {
i++;
}
- }
+ }
}
public void swap (int[] nums, int i, int j) {
int temp = nums[i];
@@ -72,7 +72,7 @@ Python3 Code:
```python
from typing import List
class Solution:
- def sortColors(self, nums: List[int]):
+ def sortColors(self, nums: List[int]):
leng = len(nums)
left = 0
# 这里和三向切分不完全一致
@@ -89,7 +89,7 @@ class Solution:
else:
i += 1
return nums
-
+
def swap(self, nums: List[int], i: int, j: int):
temp = nums[i]
nums[i] = nums[j]
@@ -112,7 +112,7 @@ public:
} else {
i++;
}
- }
+ }
}
};
```
@@ -149,6 +149,32 @@ class Solution {
}
```
+Go Code:
+
+```go
+func sortColors(nums []int) {
+ length := len(nums)
+ left, right := 0, length - 1
+ i := left
+ for i <= right {
+ if nums[i] == 2 {
+ // 把2换到最后
+ nums[i], nums[right] = nums[right], nums[i]
+ right--
+ } else if nums[i] == 0 {
+ // 把0换到最前面
+ nums[i], nums[left] = nums[left], nums[i]
+ i++
+ left++
+ } else {
+ i++
+ }
+ }
+}
+```
+
+
+
另外我们看这段代码,有什么问题呢?那就是我们即使完全符合时,仍会交换元素,这样会大大降低我们的效率。
例如:[0,0,0,1,1,1,2,2,2]
@@ -177,7 +203,7 @@ class Solution {
int len = nums.length;
int right = len - 1;
for (int i = 0; i <= right; ++i) {
- if (nums[i] == 0) {
+ if (nums[i] == 0) {
swap(nums,i,left);
left++;
}
@@ -190,7 +216,7 @@ class Solution {
}
}
}
-
+
}
public void swap (int[] nums,int i, int j) {
int temp = nums[i];
@@ -220,7 +246,7 @@ class Solution:
# 如果不等于 1 则需要继续判断,所以不移动 i 指针,i--
if nums[i] != 1:
i -= 1
- i += 1
+ i += 1
return nums
def swap(self, nums: List[int], i: int, j: int):
@@ -238,7 +264,7 @@ public:
int left = 0, len = nums.size();
int right = len - 1;
for (int i = 0; i <= right; ++i) {
- if (nums[i] == 0) {
+ if (nums[i] == 0) {
swap(nums[i],nums[left++]);
}
if (nums[i] == 2) {
@@ -265,7 +291,7 @@ class Solution {
//nums.swapAt(i, left) 直接调用系统方法
self.swap(&nums, i, left) // 保持风格统一走自定义交换
left += 1
- }
+ }
if nums[i] == 2 {
//nums.swapAt(i, right) 直接调用系统方法
self.swap(&nums, i, right) // 保持风格统一走自定义交换
@@ -286,3 +312,28 @@ class Solution {
}
}
```
+
+Go Code:
+
+```go
+func sortColors(nums []int) {
+ length := len(nums)
+ left, right := 0, length - 1
+ for i := 0; i <= right; i++ {
+ if nums[i] == 0 {
+ // 为0时,和头交换
+ nums[i], nums[left] = nums[left], nums[i]
+ left++
+ } else if nums[i] == 2 {
+ // 为2时,和尾交换
+ nums[i], nums[right] = nums[right], nums[i]
+ right--
+ // 不为1时,需要把i减回去
+ if nums[i] != 1 {
+ i--
+ }
+ }
+ }
+}
+```
+
diff --git a/animation-simulation/数组篇/剑指offer3数组中重复的数.md b/animation-simulation/数组篇/剑指offer3数组中重复的数.md
index c0f077b..188d8cd 100644
--- a/animation-simulation/数组篇/剑指offer3数组中重复的数.md
+++ b/animation-simulation/数组篇/剑指offer3数组中重复的数.md
@@ -2,7 +2,7 @@
>
> 感谢支持,该仓库会一直维护,希望对各位有一丢丢帮助。
>
-> 另外希望手机阅读的同学可以来我的 [**公众号:袁厨的算法小屋**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png) 两个平台同步,想要和题友一起刷题,互相监督的同学,可以在我的小屋点击[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)进入。
+> 另外希望手机阅读的同学可以来我的 [**公众号:袁厨的算法小屋**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png) 两个平台同步,想要和题友一起刷题,互相监督的同学,可以在我的小屋点击[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)进入。
#### [剑指 Offer 03. 数组中重复的数字](https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/)
@@ -16,7 +16,7 @@
输入:
[2, 3, 1, 0, 2, 5, 3]
-输出:2 或 3
+输出:2 或 3
#### **HashSet**
@@ -174,3 +174,24 @@ class Solution {
}
}
```
+
+Go Code:
+
+```go
+func findRepeatNumber(nums []int) int {
+ l := len(nums)
+ if l == 0 {
+ return -1
+ }
+ for i := 0; i < l; i++ {
+ // 将nums[i]换到i的位置。
+ for nums[i] != i {
+ if nums[i] == nums[nums[i]] {
+ return nums[i]
+ }
+ nums[i], nums[nums[i]] = nums[nums[i]], nums[i]
+ }
+ }
+ return -1
+}
+```
diff --git a/animation-simulation/数组篇/长度最小的子数组.md b/animation-simulation/数组篇/长度最小的子数组.md
index 2128917..c4a9495 100644
--- a/animation-simulation/数组篇/长度最小的子数组.md
+++ b/animation-simulation/数组篇/长度最小的子数组.md
@@ -119,3 +119,35 @@ class Solution {
}
}
```
+
+
+Go Code:
+
+```go
+func minSubArrayLen(target int, nums []int) int {
+ length := len(nums)
+ winLen := length + 1
+ i := 0
+ sum := 0
+ for j := 0; j < length; j++ {
+ sum += nums[j]
+ for sum >= target {
+ winLen = min(winLen, j - i + 1)
+ sum -= nums[i]
+ i++
+ }
+ }
+ if winLen == length + 1 {
+ return 0
+ }
+ return winLen
+}
+
+func min(a, b int) int {
+ if a < b {
+ return a
+ }
+ return b
+}
+```
+
diff --git a/animation-simulation/求和问题/三数之和.md b/animation-simulation/求和问题/三数之和.md
index 991b27e..50d156e 100644
--- a/animation-simulation/求和问题/三数之和.md
+++ b/animation-simulation/求和问题/三数之和.md
@@ -162,3 +162,52 @@ class Solution {
}
}
```
+
+
+Go Code:
+
+```go
+func threeSum(nums []int) [][]int {
+ res := [][]int{}
+ length := len(nums)
+ if length < 3 {
+ return res
+ }
+
+ sort.Ints(nums)
+ for i := 0; i < length - 2; i++ {
+ // 去重
+ if i != 0 && nums[i] == nums[i - 1] {
+ continue
+ }
+ l, r := i + 1, length - 1
+ for l < r {
+ /*
+ // 下面两个for循环的去重也可以用下面的代码替换
+ if l != i + 1 && nums[l] == nums[l - 1] {
+ l++
+ continue
+ }
+ */
+ if nums[i] + nums[l] + nums[r] == 0 {
+ res = append(res, []int{nums[i], nums[l], nums[r]})
+ for l < r && nums[l] == nums[l + 1] {
+ l++
+ }
+ for l < r && nums[r] == nums[r - 1] {
+ r--
+ }
+ l++
+ r--
+ } else if nums[i] + nums[l] + nums[r] < 0 {
+ l++
+ } else {
+ r--
+ }
+
+ }
+ }
+ return res
+}
+```
+
diff --git a/animation-simulation/求和问题/两数之和.md b/animation-simulation/求和问题/两数之和.md
index f853fa3..1e995ec 100644
--- a/animation-simulation/求和问题/两数之和.md
+++ b/animation-simulation/求和问题/两数之和.md
@@ -54,6 +54,21 @@ class Solution {
}
```
+Go Code:
+
+```go
+func twoSum(nums []int, target int) []int {
+ m := make(map[int]int)
+ for i, num := range nums {
+ if v, ok := m[target - num]; ok {
+ return []int{v, i}
+ }
+ m[num] = i
+ }
+ return []int{}
+}
+```
+
### 双指针(暴力)法
#### 解析
diff --git a/animation-simulation/求和问题/四数之和.md b/animation-simulation/求和问题/四数之和.md
index ac0c8d5..e1a98ef 100644
--- a/animation-simulation/求和问题/四数之和.md
+++ b/animation-simulation/求和问题/四数之和.md
@@ -95,3 +95,61 @@ class Solution {
}
}
```
+
+
+Go Code:
+
+```go
+func fourSum(nums []int, target int) [][]int {
+ res := [][]int{}
+ length := len(nums)
+ if length < 4 {
+ return res
+ }
+
+ sort.Ints(nums)
+ for i := 0; i < length - 3; i++ {
+ // 去重
+ if i != 0 && nums[i] == nums[i - 1] {
+ continue
+ }
+ for j := i + 1; j < length - 2; j++ {
+ // 去重
+ if j != i + 1 && nums[j] == nums[j - 1] {
+ continue
+ }
+ l, r := j + 1, length - 1
+ for l < r {
+ /*
+ // 下面两个for循环的去重也可以用下面的代码替换
+ if l != i + 1 && nums[l] == nums[l - 1] {
+ l++
+ continue
+ }
+ */
+ sum := nums[i] + nums[j] + nums[l] + nums[r]
+ if sum == target {
+ res = append(res, []int{nums[i], nums[j], nums[l], nums[r]})
+ for l < r && nums[l] == nums[l + 1] {
+ l++
+ }
+ for l < r && nums[r] == nums[r - 1] {
+ r--
+ }
+ l++
+ r--
+ } else if sum < target {
+ l++
+ } else {
+ r--
+ }
+
+ }
+ }
+ }
+ return res
+}
+```
+
+
+
diff --git a/animation-simulation/求次数问题/只出现一次的数.md b/animation-simulation/求次数问题/只出现一次的数.md
index c5f563e..a0c4791 100644
--- a/animation-simulation/求次数问题/只出现一次的数.md
+++ b/animation-simulation/求次数问题/只出现一次的数.md
@@ -131,6 +131,26 @@ class Solution:
return y
```
+Go Code:
+
+```go
+func singleNumber(nums []int) int {
+ if len(nums) == 1 {
+ return nums[0]
+ }
+ m := map[int]int{}
+ for _, x := range nums {
+ m[x]++
+ }
+ for k, v := range m {
+ if v == 1 {
+ return k
+ }
+ }
+ return 0
+}
+```
+
### 排序搜索法
#### 解析
@@ -208,6 +228,28 @@ class Solution:
return nums[len(nums) - 1]
```
+
+Go Code:
+
+```go
+func singleNumber(nums []int) int {
+ if len(nums) == 1 {
+ return nums[0]
+ }
+ sort.Ints(nums)
+ for i := 1; i < len(nums) - 1; i+=2 {
+ if nums[i] == nums[i - 1] {
+ continue
+ } else {
+ return nums[i - 1]
+ }
+ }
+ return nums[len(nums) - 1]
+}
+```
+
+
+
### HashSet
#### 解析
@@ -565,4 +607,17 @@ class Solution:
return reduce(lambda num, x: num ^ x, nums, 0)
```
+Go Code:
+
+```go
+func singleNumber(nums []int) int {
+ res := 0
+ for _, x := range nums {
+ res ^= x
+ }
+ return res
+
+}
+```
+
本题一共介绍了 6 种解题方法,肯定还有别的方法,欢迎大家讨论。大家可以在做题的时候一题多解。这样能大大提高自己解题能力。下面我们来看一下这些方法如何应用到其他题目上。
diff --git a/animation-simulation/求次数问题/只出现一次的数2.md b/animation-simulation/求次数问题/只出现一次的数2.md
index 755a9e7..fedf872 100644
--- a/animation-simulation/求次数问题/只出现一次的数2.md
+++ b/animation-simulation/求次数问题/只出现一次的数2.md
@@ -2,7 +2,7 @@
>
> 感谢支持,该仓库会一直维护,希望对各位有一丢丢帮助。
>
-> 另外希望手机阅读的同学可以来我的 [**公众号:袁厨的算法小屋**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png) 两个平台同步,想要和题友一起刷题,互相监督的同学,可以在我的小屋点击[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)进入。
+> 另外希望手机阅读的同学可以来我的 [**公众号:袁厨的算法小屋**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png) 两个平台同步,想要和题友一起刷题,互相监督的同学,可以在我的小屋点击[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)进入。
#### [137. 只出现一次的数字 II](https://leetcode-cn.com/problems/single-number-ii/)
@@ -216,6 +216,27 @@ class Solution:
return res
```
+Go Code:
+
+```go
+func singleNumber(nums []int) int {
+ res := 0
+ // Go语言中,int占32位以上
+ for i := 0; i < 64; i++ {
+ cnt := 0
+ for j := 0; j < len(nums); j++ {
+ if (nums[j] >> i & 1) == 1 {
+ cnt++
+ }
+ }
+ if cnt % 3 != 0{
+ res = res | 1 << i
+ }
+ }
+ return res
+}
+```
+
我们来解析一下我们的代码:
> **<<** 左移运算符:运算数的各二进位全部左移若干位,由 **<<** 右边的数字指定了移动的位数,高位丢弃,低位补 0。
diff --git a/animation-simulation/求次数问题/只出现一次的数3.md b/animation-simulation/求次数问题/只出现一次的数3.md
index af9e1de..700c184 100644
--- a/animation-simulation/求次数问题/只出现一次的数3.md
+++ b/animation-simulation/求次数问题/只出现一次的数3.md
@@ -263,3 +263,26 @@ class Solution:
arr[1] ^= y
return arr
```
+
+Go Code:
+
+```go
+func singleNumber(nums []int) []int {
+ temp := 0
+ for _, x := range nums {
+ temp ^= x
+ }
+ // 保留最后那个1,为了区分两个数
+ group := temp & (^temp + 1)
+
+ res := make([]int, 2)
+ for _, x := range nums {
+ if group & x == 0{
+ res[0] ^= x
+ } else {
+ res[1] ^= x
+ }
+ }
+ return res
+}
+```
diff --git a/animation-simulation/链表篇/234. 回文链表.md b/animation-simulation/链表篇/234. 回文链表.md
index 134f042..10e2404 100644
--- a/animation-simulation/链表篇/234. 回文链表.md
+++ b/animation-simulation/链表篇/234. 回文链表.md
@@ -173,6 +173,30 @@ class Solution {
}
```
+Go Code:
+
+```go
+func isPalindrome(head *ListNode) bool {
+ // 将节点中的值按顺序放在arr中。
+ arr := []int{}
+ node := head
+ for node != nil {
+ arr = append(arr, node.Val)
+ node = node.Next
+ }
+ // 双指针判断是否为回文
+ l, r := 0, len(arr) - 1
+ for l < r {
+ if arr[l] != arr[r] {
+ return false
+ }
+ l++
+ r--
+ }
+ return true
+}
+```
+
这个方法可以直接通过,但是这个方法需要辅助数组,那我们还有其他更好的方法吗?
**双指针翻转链表法**
@@ -201,7 +225,7 @@ class Solution {
ListNode backhalf = reverse(midnode.next);
//遍历两部分链表,判断值是否相等
ListNode p1 = head;
- ListNode p2 = backhalf;
+ ListNode p2 = backhalf;
while (p2 != null) {
if (p1.val != p2.val) {
//若要还原,记得这里也要reverse
@@ -210,11 +234,11 @@ class Solution {
}
p1 = p1.next;
p2 = p2.next;
- }
+ }
//还原链表并返回结果,这一步是需要注意的,我们不可以破坏初始结构,我们只是判断是否为回文,
//当然如果没有这一步也是可以AC,但是面试的时候题目要求可能会有这一条。
midnode.next = reverse(backhalf);
- return true;
+ return true;
}
//找到中点
public ListNode searchmidnode (ListNode head) {
@@ -223,7 +247,7 @@ class Solution {
while (fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
- }
+ }
return slow;
}
//翻转链表
@@ -258,7 +282,7 @@ public:
ListNode * backhalf = reverse(midnode->next);
//遍历两部分链表,判断值是否相等
ListNode * p1 = head;
- ListNode * p2 = backhalf;
+ ListNode * p2 = backhalf;
while (p2 != nullptr) {
if (p1->val != p2->val) {
//若要还原,记得这里也要reverse
@@ -267,11 +291,11 @@ public:
}
p1 = p1->next;
p2 = p2->next;
- }
+ }
//还原链表并返回结果,这一步是需要注意的,我们不可以破坏初始结构,我们只是判断是否为回文,
//当然如果没有这一步也是可以AC,但是面试的时候题目要求可能会有这一条。
midnode->next = reverse(backhalf);
- return true;
+ return true;
}
//找到中间的部分
ListNode * searchmidnode (ListNode * head) {
@@ -280,7 +304,7 @@ public:
while (fast->next != nullptr && fast->next->next != nullptr) {
fast = fast->next->next;
slow = slow->next;
- }
+ }
return slow;
}
//翻转链表
@@ -302,55 +326,55 @@ JS Code:
```javascript
var isPalindrome = function (head) {
- if (head === null || head.next === null) {
- return true;
- }
- //找到中间节点,也就是翻转的头节点,这个在昨天的题目中讲到
- //但是今天和昨天有一些不一样的地方就是,如果有两个中间节点返回第一个,昨天的题目是第二个
- let midnode = searchmidnode(head);
- //原地翻转链表,需要两个辅助指针。这个也是面试题目,大家可以做一下
- //这里我们用的是midnode.next需要注意,因为我们找到的是中点,但是我们翻转的是后半部分
- let backhalf = reverse(midnode.next);
- //遍历两部分链表,判断值是否相等
- let p1 = head;
- let p2 = backhalf;
- while (p2 != null) {
- if (p1.val != p2.val) {
- //若要还原,记得这里也要reverse
- midnode.next = reverse(backhalf);
- return false;
+ if (head === null || head.next === null) {
+ return true;
}
- p1 = p1.next;
- p2 = p2.next;
- }
- //还原链表并返回结果,这一步是需要注意的,我们不可以破坏初始结构,我们只是判断是否为回文,
- //当然如果没有这一步也是可以AC,但是面试的时候题目要求可能会有这一条。
- midnode.next = reverse(backhalf);
- return true;
+ //找到中间节点,也就是翻转的头节点,这个在昨天的题目中讲到
+ //但是今天和昨天有一些不一样的地方就是,如果有两个中间节点返回第一个,昨天的题目是第二个
+ let midnode = searchmidnode(head);
+ //原地翻转链表,需要两个辅助指针。这个也是面试题目,大家可以做一下
+ //这里我们用的是midnode.next需要注意,因为我们找到的是中点,但是我们翻转的是后半部分
+ let backhalf = reverse(midnode.next);
+ //遍历两部分链表,判断值是否相等
+ let p1 = head;
+ let p2 = backhalf;
+ while (p2 != null) {
+ if (p1.val != p2.val) {
+ //若要还原,记得这里也要reverse
+ midnode.next = reverse(backhalf);
+ return false;
+ }
+ p1 = p1.next;
+ p2 = p2.next;
+ }
+ //还原链表并返回结果,这一步是需要注意的,我们不可以破坏初始结构,我们只是判断是否为回文,
+ //当然如果没有这一步也是可以AC,但是面试的时候题目要求可能会有这一条。
+ midnode.next = reverse(backhalf);
+ return true;
};
//找到中点
var searchmidnode = function (head) {
- let fast = head;
- let slow = head;
- while (fast.next != null && fast.next.next != null) {
- fast = fast.next.next;
- slow = slow.next;
- }
- return slow;
+ let fast = head;
+ let slow = head;
+ while (fast.next != null && fast.next.next != null) {
+ fast = fast.next.next;
+ slow = slow.next;
+ }
+ return slow;
};
//翻转链表
var reverse = function (slow) {
let low = null;
- let temp = null;
- while (slow != null) {
- temp = slow.next;
- slow.next = low;
- low = slow;
- slow = temp;
- }
- return low;
+ let temp = null;
+ while (slow != null) {
+ temp = slow.next;
+ slow.next = low;
+ low = slow;
+ slow = temp;
+ }
+ return low;
};
```
@@ -457,3 +481,53 @@ class Solution {
}
}
```
+
+Go Code:
+
+```go
+func isPalindrome(head *ListNode) bool {
+ if head == nil || head.Next == nil {
+ return true
+ }
+
+ midNode := searchMidNode(head)
+ backHalf := reverse(midNode.Next)
+
+ // 判断左右两边是否一样(回文)
+ p1, p2 := head, backHalf
+ for p2 != nil {
+ if p1.Val != p2.Val {
+ midNode.Next = reverse(backHalf)
+ return false
+ }
+ p1 = p1.Next
+ p2 = p2.Next
+ }
+ // 不破坏原来的数据
+ midNode.Next = reverse(backHalf)
+ return true
+}
+
+// searchMidNode 求中间的节点
+func searchMidNode(head *ListNode) *ListNode {
+ fast, slow := head, head
+ for fast.Next != nil && fast.Next.Next != nil {
+ fast = fast.Next.Next
+ slow = slow.Next
+ }
+ return slow
+}
+
+// reverse 反转链表
+func reverse(node *ListNode) *ListNode {
+ var pre *ListNode
+ for node != nil {
+ nxt := node.Next
+ node.Next = pre
+ pre = node
+ node = nxt
+ }
+ return pre
+}
+```
+
diff --git a/animation-simulation/链表篇/leetcode141环形链表.md b/animation-simulation/链表篇/leetcode141环形链表.md
index 63127e1..35868da 100644
--- a/animation-simulation/链表篇/leetcode141环形链表.md
+++ b/animation-simulation/链表篇/leetcode141环形链表.md
@@ -124,3 +124,22 @@ class Solution {
}
}
```
+
+
+Go Code:
+
+```go
+func hasCycle(head *ListNode) bool {
+ if head == nil { return false }
+ s, f := head, head
+ for f != nil && f.Next != nil {
+ s = s.Next
+ f = f.Next.Next
+ if s == f {
+ return true
+ }
+ }
+ return false
+}
+```
+
diff --git a/animation-simulation/链表篇/leetcode142环形链表2.md b/animation-simulation/链表篇/leetcode142环形链表2.md
index 7884457..215a5a4 100644
--- a/animation-simulation/链表篇/leetcode142环形链表2.md
+++ b/animation-simulation/链表篇/leetcode142环形链表2.md
@@ -297,3 +297,29 @@ class Solution {
}
}
```
+
+
+Go Code:
+
+```go
+func detectCycle(head *ListNode) *ListNode {
+ if head == nil { return nil }
+ s, f := head, head
+ for f != nil && f.Next != nil {
+ s = s.Next
+ f = f.Next.Next
+ // 快慢指针相遇
+ if f == s {
+ // 快指针从头开始一步一步走,也可以用一个新的指针
+ f = head
+ for f != s {
+ f = f.Next
+ s = s.Next
+ }
+ return f
+ }
+ }
+ return nil
+}
+```
+
diff --git a/animation-simulation/链表篇/leetcode147对链表进行插入排序.md b/animation-simulation/链表篇/leetcode147对链表进行插入排序.md
index c4d1d4e..1595d7a 100644
--- a/animation-simulation/链表篇/leetcode147对链表进行插入排序.md
+++ b/animation-simulation/链表篇/leetcode147对链表进行插入排序.md
@@ -257,3 +257,36 @@ class Solution {
}
}
```
+
+
+Go Code:
+
+```go
+func insertionSortList(head *ListNode) *ListNode {
+ if head == nil || head.Next == nil { return head }
+ root := &ListNode{
+ Next: head,
+ }
+ cur, nxt := head, head.Next
+ for nxt != nil {
+ // 有序的不需要换位置
+ if cur.Val <= nxt.Val {
+ cur = cur.Next
+ nxt = nxt.Next
+ continue
+ }
+ temp := root
+ for temp.Next.Val <= nxt.Val {
+ temp = temp.Next
+ }
+ // 此时找到合适的位置
+ cur.Next = nxt.Next
+ nxt.Next = temp.Next
+ temp.Next = nxt
+ // 继续向下
+ nxt = cur.Next
+ }
+ return root.Next
+}
+```
+
diff --git a/animation-simulation/链表篇/leetcode206反转链表.md b/animation-simulation/链表篇/leetcode206反转链表.md
index 7e27978..c2b4aff 100644
--- a/animation-simulation/链表篇/leetcode206反转链表.md
+++ b/animation-simulation/链表篇/leetcode206反转链表.md
@@ -164,6 +164,27 @@ class Solution {
}
```
+Go Code:
+
+```go
+func reverseList(head *ListNode) *ListNode {
+ if head == nil || head.Next == nil { return head }
+ cur := head
+ var pre *ListNode
+ for cur != nil {
+ nxt := cur.Next
+ cur.Next = pre
+ pre = cur
+ cur = nxt
+ if nxt == nil {
+ return pre
+ }
+ nxt = nxt.Next
+ }
+ return pre
+}
+```
+
上面的迭代写法是不是搞懂啦,现在还有一种递归写法,不是特别容易理解,刚开始刷题的同学,可以只看迭代解法。
**题目代码**
@@ -217,19 +238,19 @@ JS Code:
```javascript
var reverseList = function (head) {
- //结束条件
- if (!head || !head.next) {
- return head;
- }
- //保存最后一个节点
- let pro = reverseList(head.next);
- //将节点进行反转。我们可以这样理解 4.next.next = 4
- //4.next = 5
- //则 5.next = 4 则实现了反转
- head.next.next = head;
- //防止循环
- head.next = null;
- return pro;
+ //结束条件
+ if (!head || !head.next) {
+ return head;
+ }
+ //保存最后一个节点
+ let pro = reverseList(head.next);
+ //将节点进行反转。我们可以这样理解 4.next.next = 4
+ //4.next = 5
+ //则 5.next = 4 则实现了反转
+ head.next.next = head;
+ //防止循环
+ head.next = null;
+ return pro;
};
```
diff --git a/animation-simulation/链表篇/leetcode328奇偶链表.md b/animation-simulation/链表篇/leetcode328奇偶链表.md
index d43afac..4ab5b9d 100644
--- a/animation-simulation/链表篇/leetcode328奇偶链表.md
+++ b/animation-simulation/链表篇/leetcode328奇偶链表.md
@@ -2,7 +2,7 @@
>
> 感谢支持,该仓库会一直维护,希望对各位有一丢丢帮助。
>
-> 另外希望手机阅读的同学可以来我的 [**公众号:袁厨的算法小屋**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png) 两个平台同步,想要和题友一起刷题,互相监督的同学,可以在我的小屋点击[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)进入。
+> 另外希望手机阅读的同学可以来我的 [**公众号:袁厨的算法小屋**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png) 两个平台同步,想要和题友一起刷题,互相监督的同学,可以在我的小屋点击[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)进入。
### [328. 奇偶链表](https://leetcode-cn.com/problems/odd-even-linked-list/)
@@ -21,7 +21,7 @@
示例 2:
-> 输入: 2->1->3->5->6->4->7->NULL
+> 输入: 2->1->3->5->6->4->7->NULL
> 输出: 2->3->6->7->1->5->4->NULL
#### 题目解析
@@ -54,7 +54,7 @@ class Solution {
odd = odd.next;
even.next = odd.next;
even = even.next;
- }
+ }
//链接
odd.next = evenHead;
return head;
@@ -81,7 +81,7 @@ public:
odd = odd->next;
even->next = odd->next;
even = even->next;
- }
+ }
//链接
odd->next = evenHead;
return head;
@@ -98,15 +98,15 @@ var oddEvenList = function (head) {
even = head.next,
evenHead = even;
while (odd.next && even.next) {
- //将偶数位合在一起,奇数位合在一起
- odd.next = even.next;
- odd = odd.next;
- even.next = odd.next;
- even = even.next;
- }
- //链接
- odd.next = evenHead;
- return head;
+ //将偶数位合在一起,奇数位合在一起
+ odd.next = even.next;
+ odd = odd.next;
+ even.next = odd.next;
+ even = even.next;
+ }
+ //链接
+ odd.next = evenHead;
+ return head;
};
```
@@ -155,3 +155,23 @@ class Solution {
}
}
```
+
+Go Code:
+
+```go
+func oddEvenList(head *ListNode) *ListNode {
+ if head == nil || head.Next == nil {
+ return head
+ }
+ odd, even := head, head.Next
+ evenHead := even
+ for odd.Next != nil && even.Next != nil {
+ odd.Next = even.Next
+ odd = odd.Next
+ even.Next = odd.Next
+ even = even.Next
+ }
+ odd.Next = evenHead
+ return head
+}
+```
diff --git a/animation-simulation/链表篇/leetcode82删除排序链表中的重复元素II.md b/animation-simulation/链表篇/leetcode82删除排序链表中的重复元素II.md
index 1880959..0e42f1c 100644
--- a/animation-simulation/链表篇/leetcode82删除排序链表中的重复元素II.md
+++ b/animation-simulation/链表篇/leetcode82删除排序链表中的重复元素II.md
@@ -194,3 +194,32 @@ class Solution {
}
}
```
+
+
+Go Code:
+
+```go
+func deleteDuplicates(head *ListNode) *ListNode {
+ // 新建一个头结点,他的下一个节点才是开始
+ root := &ListNode{
+ Next: head,
+ }
+ pre, cur := root, head
+ for cur != nil && cur.Next != nil {
+ if cur.Val == cur.Next.Val {
+ // 相等的话,cur就一直向后移动
+ for cur != nil && cur.Next != nil && cur.Val == cur.Next.Val {
+ cur = cur.Next
+ }
+ // 循环后移动到了最后一个相同的节点。
+ cur = cur.Next
+ pre.Next = cur
+ } else {
+ cur = cur.Next
+ pre = pre.Next
+ }
+ }
+ return root.Next
+}
+```
+
diff --git a/animation-simulation/链表篇/leetcode86分隔链表.md b/animation-simulation/链表篇/leetcode86分隔链表.md
index da4890c..fdcac26 100644
--- a/animation-simulation/链表篇/leetcode86分隔链表.md
+++ b/animation-simulation/链表篇/leetcode86分隔链表.md
@@ -187,3 +187,31 @@ class Solution {
}
}
```
+
+
+Go Code:
+
+```go
+func partition(head *ListNode, x int) *ListNode {
+ big, small := &ListNode{}, &ListNode{}
+ headBig, headSmall := big, small
+ temp := head
+ for temp != nil {
+ // 分开存
+ if temp.Val < x {
+ small.Next = temp
+ small = small.Next
+ } else {
+ big.Next = temp
+ big = big.Next
+ }
+ temp = temp.Next
+ }
+ // 最后一个节点指向nil
+ big.Next = nil
+ // 存小数的链表和存大数的连起来
+ small.Next = headBig.Next
+ return headSmall.Next
+}
+```
+
diff --git a/animation-simulation/链表篇/leetcode92反转链表2.md b/animation-simulation/链表篇/leetcode92反转链表2.md
index f07f220..2a6caff 100644
--- a/animation-simulation/链表篇/leetcode92反转链表2.md
+++ b/animation-simulation/链表篇/leetcode92反转链表2.md
@@ -263,3 +263,48 @@ class Solution {
}
}
```
+
+
+GoCode:
+
+```go
+func reverseBetween(head *ListNode, left int, right int) *ListNode {
+ root := &ListNode{
+ Next: head,
+ }
+ temp := root
+ i := 0
+ // left的前一个节点
+ for ; i < left - 1; i++ {
+ temp = temp.Next
+ }
+ leftNode := temp
+ // right的后一个节点
+ for ; i < right; i++ {
+ temp = temp.Next
+ }
+ rightNode := temp.Next
+ // 切断链表
+ temp.Next = nil
+ newhead := leftNode.Next
+ leftNode.Next = nil
+
+ // 反转后将3段链表接上。
+ leftNode.Next = reverse(newhead)
+ newhead.Next = rightNode
+ return root.Next
+}
+
+func reverse(head *ListNode) *ListNode {
+ var pre *ListNode
+ cur := head
+ for cur != nil {
+ temp := cur
+ cur = cur.Next
+ temp.Next = pre
+ pre = temp
+ }
+ return pre
+}
+```
+
diff --git a/animation-simulation/链表篇/剑指Offer25合并两个排序的链表.md b/animation-simulation/链表篇/剑指Offer25合并两个排序的链表.md
index a58d2fb..5f51f72 100644
--- a/animation-simulation/链表篇/剑指Offer25合并两个排序的链表.md
+++ b/animation-simulation/链表篇/剑指Offer25合并两个排序的链表.md
@@ -146,3 +146,31 @@ class Solution {
}
}
```
+
+
+Go Code:
+
+```go
+func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
+ root := &ListNode{}
+ node := root
+ for l1 != nil && l2 != nil {
+ if l1.Val < l2.Val {
+ node.Next = l1
+ l1 = l1.Next
+ } else {
+ node.Next = l2
+ l2 = l2.Next
+ }
+ node = node.Next
+ }
+ // node接上l1或l2剩下的节点
+ if l1 != nil {
+ node.Next = l1
+ } else {
+ node.Next = l2
+ }
+ return root.Next
+}
+```
+
diff --git a/animation-simulation/链表篇/剑指Offer52两个链表的第一个公共节点.md b/animation-simulation/链表篇/剑指Offer52两个链表的第一个公共节点.md
index e95eb95..823f17e 100644
--- a/animation-simulation/链表篇/剑指Offer52两个链表的第一个公共节点.md
+++ b/animation-simulation/链表篇/剑指Offer52两个链表的第一个公共节点.md
@@ -265,6 +265,28 @@ class Solution {
}
```
+Go Code:
+
+```go
+func getIntersectionNode(headA, headB *ListNode) *ListNode {
+ tempA, tempB := headA, headB
+ for tempA != tempB {
+ // 如果不为空就指针下移,为空就跳到另一链表的头部
+ if tempA == nil {
+ tempA = headB
+ } else {
+ tempA = tempA.Next
+ }
+ if tempB == nil {
+ tempB = headA
+ } else {
+ tempB = tempB.Next
+ }
+ }
+ return tempA
+}
+```
+
好啦,链表的题目就结束啦,希望大家能有所收获,下周就要更新新的题型啦,继续坚持,肯定会有收获的。
diff --git a/animation-simulation/链表篇/剑指offer22倒数第k个节点.md b/animation-simulation/链表篇/剑指offer22倒数第k个节点.md
index 5a358c5..38e624e 100644
--- a/animation-simulation/链表篇/剑指offer22倒数第k个节点.md
+++ b/animation-simulation/链表篇/剑指offer22倒数第k个节点.md
@@ -163,3 +163,23 @@ class Solution {
}
}
```
+
+
+Go Code:
+
+```go
+func getKthFromEnd(head *ListNode, k int) *ListNode {
+ if head == nil { return head }
+ pro, after := head, head
+ //先移动绿指针到指定位置
+ for i := 0; i < k - 1; i++ {
+ pro = pro.Next
+ }
+ for pro.Next != nil {
+ pro = pro.Next
+ after = after.Next
+ }
+ return after
+}
+```
+
diff --git a/animation-simulation/链表篇/面试题 02.03. 链表中间节点.md b/animation-simulation/链表篇/面试题 02.03. 链表中间节点.md
index 9056f0d..c520fec 100644
--- a/animation-simulation/链表篇/面试题 02.03. 链表中间节点.md
+++ b/animation-simulation/链表篇/面试题 02.03. 链表中间节点.md
@@ -135,3 +135,19 @@ class Solution {
}
}
```
+
+
+Go Code:
+
+```go
+func middleNode(head *ListNode) *ListNode {
+ // 快慢指针
+ fast, slow := head, head
+ for fast != nil && fast.Next != nil {
+ fast = fast.Next.Next
+ slow = slow.Next
+ }
+ return slow
+}
+```
+
diff --git a/animation-simulation/链表篇/面试题 02.05. 链表求和.md b/animation-simulation/链表篇/面试题 02.05. 链表求和.md
index 1f09fa4..dc54242 100644
--- a/animation-simulation/链表篇/面试题 02.05. 链表求和.md
+++ b/animation-simulation/链表篇/面试题 02.05. 链表求和.md
@@ -267,3 +267,42 @@ class Solution {
}
}
```
+
+
+Go Code:
+
+```go
+func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
+ root := &ListNode{}
+ temp := root
+ // 用来保存进位值,初始化为0
+ mod := 0
+ for (l1 != nil || l2 != nil) {
+ l1num := 0
+ if l1 != nil { l1num = l1.Val }
+ l2num := 0
+ if l2 != nil { l2num = l2.Val }
+ // 将链表的值和进位值相加,得到为返回链表的值
+ sum := l1num + l2num + mod
+ // 更新进位值,例18/10=1,9/10=0
+ mod = sum / 10
+ // 新节点保存的值,18%8=2,则添加2
+ sum = sum % 10
+ newNode := &ListNode{
+ Val: sum,
+ }
+ temp.Next = newNode
+ temp = temp.Next
+ if l1 != nil { l1 = l1.Next }
+ if l2 != nil { l2 = l2.Next }
+ }
+ if mod != 0 {
+ newNode := &ListNode{
+ Val: mod,
+ }
+ temp.Next = newNode
+ }
+ return root.Next
+}
+```
+