添加 problem 86

This commit is contained in:
YDZ
2019-03-09 13:30:40 +08:00
parent cffa85d6fe
commit 33e4de689b
3 changed files with 205 additions and 0 deletions

View File

@ -0,0 +1,105 @@
package leetcode
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func partition(head *ListNode, x int) *ListNode {
beforeHead := &ListNode{Val: 0, Next: nil}
before := beforeHead
afterHead := &ListNode{Val: 0, Next: nil}
after := afterHead
for head != nil {
if head.Val < x {
before.Next = head
before = before.Next
} else {
after.Next = head
after = after.Next
}
head = head.Next
}
after.Next = nil
before.Next = afterHead.Next
return beforeHead.Next
}
type DoublyListNode struct {
Val int
Prev *DoublyListNode
Next *DoublyListNode
}
func partition_(head *ListNode, x int) *ListNode {
if head == nil || head.Next == nil {
return head
}
DLNHead := genDoublyListNode(head)
cur := DLNHead
for cur != nil {
if cur.Val < x {
tmp := &DoublyListNode{Val: cur.Val, Prev: nil, Next: nil}
compareNode := cur
for compareNode.Prev != nil {
if compareNode.Val >= x && compareNode.Prev.Val < x {
break
}
compareNode = compareNode.Prev
}
if compareNode == DLNHead {
if compareNode.Val < x {
cur = cur.Next
continue
} else {
tmp.Next = DLNHead
DLNHead.Prev = tmp
DLNHead = tmp
}
} else {
tmp.Next = compareNode
tmp.Prev = compareNode.Prev
compareNode.Prev.Next = tmp
compareNode.Prev = tmp
}
deleteNode := cur
if cur.Prev != nil {
deleteNode.Prev.Next = deleteNode.Next
}
if cur.Next != nil {
deleteNode.Next.Prev = deleteNode.Prev
}
}
cur = cur.Next
}
return genListNode(DLNHead)
}
func genDoublyListNode(head *ListNode) *DoublyListNode {
cur := head.Next
DLNHead := &DoublyListNode{Val: head.Val, Prev: nil, Next: nil}
curDLN := DLNHead
for cur != nil {
tmp := &DoublyListNode{Val: cur.Val, Prev: curDLN, Next: nil}
curDLN.Next = tmp
curDLN = tmp
cur = cur.Next
}
return DLNHead
}
func genListNode(head *DoublyListNode) *ListNode {
cur := head.Next
LNHead := &ListNode{Val: head.Val, Next: nil}
curLN := LNHead
for cur != nil {
tmp := &ListNode{Val: cur.Val, Next: nil}
curLN.Next = tmp
curLN = tmp
cur = cur.Next
}
return LNHead
}

View File

@ -0,0 +1,73 @@
package leetcode
import (
"fmt"
"testing"
)
type question86 struct {
para86
ans86
}
// para 是参数
// one 代表第一个参数
type para86 struct {
one []int
x int
}
// ans 是答案
// one 代表第一个答案
type ans86 struct {
one []int
}
func Test_Problem86(t *testing.T) {
qs := []question86{
question86{
para86{[]int{1, 4, 3, 2, 5, 2}, 3},
ans86{[]int{1, 2, 2, 4, 3, 5}},
},
question86{
para86{[]int{1, 1, 2, 2, 3, 3, 3}, 2},
ans86{[]int{1, 1, 2, 2, 3, 3, 3}},
},
question86{
para86{[]int{1, 4, 3, 2, 5, 2}, 0},
ans86{[]int{1, 4, 3, 2, 5, 2}},
},
question86{
para86{[]int{4, 3, 2, 5, 2}, 3},
ans86{[]int{2, 2, 4, 3, 5}},
},
question86{
para86{[]int{1, 1, 1, 1, 1, 1}, 1},
ans86{[]int{1, 1, 1, 1, 1, 1}},
},
question86{
para86{[]int{3, 1}, 2},
ans86{[]int{1, 3}},
},
question86{
para86{[]int{1, 2}, 3},
ans86{[]int{1, 2}},
},
}
fmt.Printf("------------------------Leetcode Problem 86------------------------\n")
for _, q := range qs {
_, p := q.ans86, q.para86
fmt.Printf("【input】:%v 【output】:%v\n", p, L2s(partition(S2l(p.one), p.x)))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,27 @@
# [86. Partition List](https://leetcode.com/problems/partition-list/)
## 题目
Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.
You should preserve the original relative order of the nodes in each of the two partitions.
Example:
```
Input: head = 1->4->3->2->5->2, x = 3
Output: 1->2->2->4->3->5
```
## 题目大意
给定一个数 x比 x 大或等于的数字都要排列在比 x 小的数字后面,并且相对位置不能发生变化。由于相对位置不能发生变化,所以不能用类似冒泡排序的思想。
这道题最简单的做法是构造双向链表,不过时间复杂度是 O(n^2)。
(以下描述定义,大于等于 x 的都属于比 x 大)
更优的方法是新构造 2 个链表,一个链表专门存储比 x 小的结点,另一个专门存储比 x 大的结点。在原链表头部开始扫描一边,依次把这两类点归类到 2 个新建链表中,有点入栈的意思。由于是从头开始扫描的原链表,所以原链表中的原有顺序会依旧被保存下来。最后 2 个新链表里面会存储好各自的结果,把这两个链表,比 x 小的链表拼接到 比 x 大的链表的前面,就能得到最后的答案了。