Skip to content

Commit 159547e

Browse files
committed
add leetcode 143
1 parent 636fb5a commit 159547e

File tree

4 files changed

+227
-0
lines changed

4 files changed

+227
-0
lines changed

src/0143.Reorder-List/ListNode.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package Solution
2+
3+
import (
4+
"fmt"
5+
"math/rand"
6+
)
7+
8+
type ListNode struct {
9+
Val int
10+
Next *ListNode
11+
}
12+
13+
// 比较结果
14+
func isEqual(l1 *ListNode, l2 *ListNode) bool {
15+
16+
for l1 != nil && l2 != nil {
17+
if l1.Val != l2.Val {
18+
return false
19+
}
20+
l1 = l1.Next
21+
l2 = l2.Next
22+
}
23+
if l1 == nil && l2 != nil {
24+
return false
25+
}
26+
if l1 != nil && l2 == nil {
27+
return false
28+
}
29+
return true
30+
}
31+
32+
func PrintList(head *ListNode) {
33+
for head != nil {
34+
fmt.Print(head.Val, "->")
35+
head = head.Next
36+
}
37+
fmt.Println()
38+
}
39+
40+
// 根据数组反序列化链表
41+
func UnmarshalListBySlice(nums []int) *ListNode {
42+
head := &ListNode{Val: -1, Next: nil}
43+
tmp := head
44+
for _, v := range nums {
45+
tmp.Next = &ListNode{Val: v, Next: nil}
46+
tmp = tmp.Next
47+
}
48+
return head.Next
49+
}
50+
51+
// 随机初始化链表
52+
func UnmarshalListByRand(max_num int, len int) *ListNode {
53+
head := &ListNode{Val: -1, Next: nil}
54+
tmp := head
55+
56+
for i := 0; i < len; i++ {
57+
tmp.Next = &ListNode{Val: rand.Intn(max_num), Next: nil}
58+
tmp = tmp.Next
59+
}
60+
return head.Next
61+
}

src/0143.Reorder-List/README.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# [143. Reorder List][title]
2+
3+
## Description
4+
Given a singly linked list L: L0→L1→…→Ln-1→Ln,
5+
reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…
6+
7+
You may not modify the values in the list's nodes, only nodes itself may be changed.
8+
9+
**Example 1:**
10+
```
11+
Given 1->2->3->4, reorder it to 1->4->2->3.
12+
```
13+
14+
**Example 2:**
15+
```
16+
Given 1->2->3->4->5, reorder it to 1->5->2->4->3.
17+
```
18+
19+
**Tags:** Linked List
20+
21+
## 题意
22+
> 给定一个单链表,对链表进行重新排序。
23+
24+
## 题解
25+
> 把链表分成两部分,对后半段链表进行逆序,然后再将两部分合并。
26+
27+
### 思路1
28+
1. 找到链表的中点,将链表拆分成前后两部分。
29+
1. 对后半段链表进行逆序操作。
30+
1. 将前半段链表和逆序后的后半段链表合并。
31+
32+
```go
33+
func reorderList(head *ListNode) {
34+
if nil == head || nil == head.Next {
35+
return
36+
}
37+
mid := findMid(head)
38+
first, second := head, reverseList(mid.Next)
39+
mid.Next = nil
40+
41+
newHead := new(ListNode)
42+
current := newHead
43+
for first != nil || second != nil {
44+
if first != nil {
45+
current.Next = &ListNode{first.Val, nil}
46+
current = current.Next
47+
first = first.Next
48+
}
49+
if second != nil {
50+
current.Next = &ListNode{second.Val, nil}
51+
current = current.Next
52+
second = second.Next
53+
}
54+
}
55+
head.Next = newHead.Next.Next
56+
}
57+
58+
func findMid(head *ListNode) *ListNode {
59+
slow, fast := head, head.Next
60+
for slow.Next != nil && fast.Next != nil && fast.Next.Next != nil {
61+
slow = slow.Next
62+
fast = fast.Next.Next
63+
}
64+
return slow
65+
}
66+
67+
func reverseList(head *ListNode) *ListNode {
68+
newHead := head
69+
for head.Next != nil {
70+
next := head.Next
71+
head.Next = next.Next
72+
next.Next = newHead
73+
newHead = next
74+
}
75+
return newHead
76+
}
77+
```
78+
79+
## 结语
80+
81+
如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 LeetCode 题解:[awesome-golang-leetcode][me]
82+
83+
[title]: https://leetcode.com/problems/reorder-list/
84+
[me]: https://github.com/kylesliu/awesome-golang-leetcode

src/0143.Reorder-List/Solution.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package Solution
2+
3+
func Solution(head *ListNode) {
4+
if nil == head || nil == head.Next {
5+
return
6+
}
7+
mid := findMid(head)
8+
first, second := head, reverseList(mid.Next)
9+
mid.Next = nil
10+
11+
newHead := new(ListNode)
12+
current := newHead
13+
for first != nil || second != nil {
14+
if first != nil {
15+
current.Next = &ListNode{first.Val, nil}
16+
current = current.Next
17+
first = first.Next
18+
}
19+
if second != nil {
20+
current.Next = &ListNode{second.Val, nil}
21+
current = current.Next
22+
second = second.Next
23+
}
24+
}
25+
head.Next = newHead.Next.Next
26+
}
27+
28+
func findMid(head *ListNode) *ListNode {
29+
slow, fast := head, head.Next
30+
for slow != nil && fast != nil && fast.Next != nil {
31+
slow = slow.Next
32+
fast = fast.Next.Next
33+
}
34+
return slow
35+
}
36+
37+
func reverseList(head *ListNode) *ListNode {
38+
newHead := head
39+
for head.Next != nil {
40+
next := head.Next
41+
head.Next = next.Next
42+
next.Next = newHead
43+
newHead = next
44+
}
45+
return newHead
46+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package Solution
2+
3+
import "testing"
4+
5+
func TestSolution(t *testing.T) {
6+
// 测试用例
7+
cases := []struct {
8+
name string
9+
inputs []int
10+
expect *ListNode
11+
} {
12+
{
13+
"TestCase 1",
14+
[]int{1,2,3,4},
15+
UnmarshalListBySlice([]int{1,4,2,3}),
16+
},
17+
{
18+
"TestCase 2",
19+
[]int{1,2,3,4,5},
20+
UnmarshalListBySlice([]int{1,5,2,4,3}),
21+
},
22+
}
23+
24+
// 开始测试
25+
for _, c := range cases {
26+
t.Run(c.name, func(t *testing.T) {
27+
linkedList := UnmarshalListBySlice(c.inputs)
28+
Solution(linkedList)
29+
if !isEqual(linkedList, c.expect) {
30+
PrintList(linkedList)
31+
PrintList(c.expect)
32+
t.Fatalf("expected: %v, but got: %v, with inputs: %v", c.expect, linkedList, c.inputs)
33+
}
34+
})
35+
}
36+
}

0 commit comments

Comments
 (0)