输入一个链表和逐段反转的长度,输出反转的结果。最后一段如果达不到给定长度,不反转。
示例:
输入链表“0->1->2->3->4->5->6->7”和长度 3,输出链表“2->1->0->5->4->3->6->7”。
思路:
从头开始逐段反转。
// Package main
package main
import "fmt"
type Node struct {
Val int
Next *Node
}
func reverseBySegment(head *Node, k int) *Node {
if head == nil {
return head
}
preTail := &Node{
Next: head,
} // 前部分链表的尾
var res, pre *Node
cur := head
cnt := 0
for cur != nil {
pre = cur
cur = cur.Next
cnt++
if cnt == k {
pre.Next = nil // 断开
newHead, newTail := reverse(preTail.Next) // 反转
preTail.Next = newHead
newTail.Next = cur // 连接
preTail = newTail
cnt = 0
if res == nil {
res = newHead
}
}
}
if res == nil {
res = head
}
return res
}
func reverse(head *Node) (newHead *Node, newTail *Node) {
var pre *Node
cur := head
for cur != nil {
tmp := cur.Next
cur.Next = pre
pre = cur
cur = tmp
}
return pre, head
}
func main() {
head := &Node{
Val: 0,
Next: &Node{
Val: 1,
Next: &Node{
Val: 2,
Next: &Node{
Val: 3,
Next: &Node{
Val: 4,
Next: &Node{
Val: 5,
Next: &Node{
Val: 6,
Next: &Node{
Val: 7,
Next: nil,
},
},
},
},
},
},
},
}
head = reverseBySegment(head, 3)
for node := head; node != nil; node = node.Next {
fmt.Printf("%v ", node.Val)
}
}
其实也可以用递归,比较简单,这里不再给出代码。