From 391bc122543a74befce2cbcc8f1a86137e63071d Mon Sep 17 00:00:00 2001 From: YDZ Date: Mon, 11 Mar 2019 00:18:54 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20problem=20143?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../143.Reorder List/143. Reorder List.go | 66 +++++++++++++++++++ .../143. Reorder List_test.go | 56 ++++++++++++++++ Algorithms/143.Reorder List/README.md | 30 +++++++++ 3 files changed, 152 insertions(+) create mode 100644 Algorithms/143.Reorder List/143. Reorder List.go create mode 100644 Algorithms/143.Reorder List/143. Reorder List_test.go create mode 100644 Algorithms/143.Reorder List/README.md diff --git a/Algorithms/143.Reorder List/143. Reorder List.go b/Algorithms/143.Reorder List/143. Reorder List.go new file mode 100644 index 00000000..2fae72a9 --- /dev/null +++ b/Algorithms/143.Reorder List/143. Reorder List.go @@ -0,0 +1,66 @@ +package leetcode + +/** + * Definition for singly-linked list. + * type ListNode struct { + * Val int + * Next *ListNode + * } + */ +func reorderList(head *ListNode) *ListNode { + if head == nil || head.Next == nil { + return head + } + + // 寻找中间结点 + p1 := head + p2 := head + for p2.Next != nil && p2.Next.Next != nil { + p1 = p1.Next + p2 = p2.Next.Next + } + + // 反转链表后半部分 1->2->3->4->5->6 to 1->2->3->6->5->4 + preMiddle := p1 + preCurrent := p1.Next + for preCurrent.Next != nil { + current := preCurrent.Next + preCurrent.Next = current.Next + current.Next = preMiddle.Next + preMiddle.Next = current + } + + // 重新拼接链表 1->2->3->6->5->4 to 1->6->2->5->3->4 + p1 = head + p2 = preMiddle.Next + for p1 != preMiddle { + preMiddle.Next = p2.Next + p2.Next = p1.Next + p1.Next = p2 + p1 = p2.Next + p2 = preMiddle.Next + } + return head +} + +func reorderList_1(head *ListNode) *ListNode { + array := listToArray(head) + length := len(array) + if length == 0 { + return head + } + cur := head + last := head + for i := 0; i < len(array)/2; i++ { + tmp := &ListNode{Val: array[length-1-i], Next: cur.Next} + cur.Next = tmp + cur = tmp.Next + last = tmp + } + if length%2 == 0 { + last.Next = nil + } else { + cur.Next = nil + } + return head +} diff --git a/Algorithms/143.Reorder List/143. Reorder List_test.go b/Algorithms/143.Reorder List/143. Reorder List_test.go new file mode 100644 index 00000000..d9a8fb9a --- /dev/null +++ b/Algorithms/143.Reorder List/143. Reorder List_test.go @@ -0,0 +1,56 @@ +package leetcode + +import ( + "fmt" + "testing" +) + +type question143 struct { + para143 + ans143 +} + +// para 是参数 +// one 代表第一个参数 +type para143 struct { + one []int +} + +// ans 是答案 +// one 代表第一个答案 +type ans143 struct { + one []int +} + +func Test_Problem143(t *testing.T) { + + qs := []question143{ + + question143{ + para143{[]int{1, 2, 3, 4, 5}}, + ans143{[]int{1, 5, 2, 4, 3}}, + }, + question143{ + para143{[]int{1, 2, 3, 4}}, + ans143{[]int{1, 4, 2, 3}}, + }, + + question143{ + para143{[]int{1}}, + ans143{[]int{1}}, + }, + + question143{ + para143{[]int{}}, + ans143{[]int{}}, + }, + } + + fmt.Printf("------------------------Leetcode Problem 143------------------------\n") + + for _, q := range qs { + _, p := q.ans143, q.para143 + fmt.Printf("【input】:%v 【output】:%v\n", p, L2s(reorderList(S2l(p.one)))) + } + fmt.Printf("\n\n\n") +} diff --git a/Algorithms/143.Reorder List/README.md b/Algorithms/143.Reorder List/README.md new file mode 100644 index 00000000..592b4f9b --- /dev/null +++ b/Algorithms/143.Reorder List/README.md @@ -0,0 +1,30 @@ +# [143. Reorder List](https://leetcode.com/problems/reorder-list/) + +## 题目 + +Given a singly linked list L: L0→L1→…→Ln-1→Ln, +reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… + +You may not modify the values in the list's nodes, only nodes itself may be changed. + +Example 1: + +```c +Given 1->2->3->4, reorder it to 1->4->2->3. +``` + +Example 2: + +```c +Given 1->2->3->4->5, reorder it to 1->5->2->4->3. +``` + +## 题目大意 + +按照指定规则重新排序链表:第一个元素和最后一个元素排列在一起,接着第二个元素和倒数第二个元素排在一起,接着第三个元素和倒数第三个元素排在一起。 + +最近简单的方法是先把链表存储到数组里,然后找到链表中间的结点,按照规则拼接即可。这样时间复杂度是 O(n),空间复杂度是 O(n)。 + +更好的做法是结合之前几道题的操作:链表逆序,找中间结点。 + +先找到链表的中间结点,然后利用逆序区间的操作,如 [92 题](https://github.com/halfrost/LeetCode-Go/tree/master/Algorithms/92.Reverse%20Linked%20List%20II) 里的 reverseBetween() 操作,只不过这里的反转区间是从中点一直到末尾。最后利用 2 个指针,一个指向头结点,一个指向中间结点,开始拼接最终的结果。这种做法的时间复杂度是 O(n),空间复杂度是 O(1)。 \ No newline at end of file