From 781e84ca9925ecd6eb89aa5be5cda280a4ec83f3 Mon Sep 17 00:00:00 2001 From: zouxinyao Date: Sun, 25 Jul 2021 23:20:13 +0800 Subject: [PATCH] =?UTF-8?q?=E9=93=BE=E8=A1=A8=E7=AF=87=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0Go=E8=AF=AD=E8=A8=80=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- animation-simulation/链表篇/234. 回文链表.md | 74 +++++++++++++++++++ .../链表篇/leetcode141环形链表.md | 18 +++++ .../链表篇/leetcode142环形链表2.md | 27 ++++++- .../链表篇/leetcode147对链表进行插入排序.md | 32 ++++++++ .../链表篇/leetcode206反转链表.md | 21 ++++++ .../链表篇/leetcode328奇偶链表.md | 23 +++++- .../leetcode82删除排序链表中的重复元素II.md | 28 +++++++ .../链表篇/leetcode86分隔链表.md | 27 +++++++ .../链表篇/leetcode92反转链表2.md | 46 +++++++++++- .../链表篇/剑指Offer25合并两个排序的链表.md | 27 +++++++ .../剑指Offer52两个链表的第一个公共节点.md | 22 ++++++ .../链表篇/剑指offer22倒数第k个节点.md | 19 +++++ .../链表篇/面试题 02.03. 链表中间节点.md | 15 ++++ .../链表篇/面试题 02.05. 链表求和.md | 38 ++++++++++ 14 files changed, 414 insertions(+), 3 deletions(-) diff --git a/animation-simulation/链表篇/234. 回文链表.md b/animation-simulation/链表篇/234. 回文链表.md index 8d77bc5..fa5b945 100644 --- a/animation-simulation/链表篇/234. 回文链表.md +++ b/animation-simulation/链表篇/234. 回文链表.md @@ -174,6 +174,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 +} +``` + 这个方法可以直接通过,但是这个方法需要辅助数组,那我们还有其他更好的方法吗? **双指针翻转链表法** @@ -458,3 +482,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 5ae5ada..fd62c56 100644 --- a/animation-simulation/链表篇/leetcode141环形链表.md +++ b/animation-simulation/链表篇/leetcode141环形链表.md @@ -125,3 +125,21 @@ 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 933eb40..706d4cf 100644 --- a/animation-simulation/链表篇/leetcode142环形链表2.md +++ b/animation-simulation/链表篇/leetcode142环形链表2.md @@ -298,4 +298,29 @@ class Solution { return nil } } -``` \ No newline at end of file +``` + +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 9bdd4e6..ddae9ef 100644 --- a/animation-simulation/链表篇/leetcode147对链表进行插入排序.md +++ b/animation-simulation/链表篇/leetcode147对链表进行插入排序.md @@ -263,3 +263,35 @@ 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 e9aa1c8..bc25c97 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 +} +``` + 上面的迭代写法是不是搞懂啦,现在还有一种递归写法,不是特别容易理解,刚开始刷题的同学,可以只看迭代解法。 diff --git a/animation-simulation/链表篇/leetcode328奇偶链表.md b/animation-simulation/链表篇/leetcode328奇偶链表.md index 6f7fc75..6dc27ef 100644 --- a/animation-simulation/链表篇/leetcode328奇偶链表.md +++ b/animation-simulation/链表篇/leetcode328奇偶链表.md @@ -151,4 +151,25 @@ class Solution { return head } } -``` \ No newline at end of file +``` + +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 e786c73..7b304a9 100644 --- a/animation-simulation/链表篇/leetcode82删除排序链表中的重复元素II.md +++ b/animation-simulation/链表篇/leetcode82删除排序链表中的重复元素II.md @@ -196,3 +196,31 @@ 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 b57511a..fe3b1eb 100644 --- a/animation-simulation/链表篇/leetcode86分隔链表.md +++ b/animation-simulation/链表篇/leetcode86分隔链表.md @@ -188,3 +188,30 @@ 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 136b6e0..a7b04fc 100644 --- a/animation-simulation/链表篇/leetcode92反转链表2.md +++ b/animation-simulation/链表篇/leetcode92反转链表2.md @@ -264,4 +264,48 @@ class Solution { return low } } -``` \ No newline at end of file +``` + +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 661b329..10ee995 100644 --- a/animation-simulation/链表篇/剑指Offer25合并两个排序的链表.md +++ b/animation-simulation/链表篇/剑指Offer25合并两个排序的链表.md @@ -147,3 +147,30 @@ 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 a2576eb..37f1296 100644 --- a/animation-simulation/链表篇/剑指Offer52两个链表的第一个公共节点.md +++ b/animation-simulation/链表篇/剑指Offer52两个链表的第一个公共节点.md @@ -274,6 +274,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 6d28871..ad1bf1c 100644 --- a/animation-simulation/链表篇/剑指offer22倒数第k个节点.md +++ b/animation-simulation/链表篇/剑指offer22倒数第k个节点.md @@ -161,3 +161,22 @@ 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 e22271a..c536389 100644 --- a/animation-simulation/链表篇/面试题 02.03. 链表中间节点.md +++ b/animation-simulation/链表篇/面试题 02.03. 链表中间节点.md @@ -135,3 +135,18 @@ 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 7ab8bb4..d5e4eba 100644 --- a/animation-simulation/链表篇/面试题 02.05. 链表求和.md +++ b/animation-simulation/链表篇/面试题 02.05. 链表求和.md @@ -269,3 +269,41 @@ 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 +} +``` +