1. 25. K 个一组翻转链表
https://leetcode-cn.com/problems/reverse-nodes-in-k-group/
https://leetcode-cn.com/problems/reverse-nodes-in-k-group/
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
/*
1. 方法1:使用切片,分为len(ListNode)/k 组,然后分组反转,存入切片中,最后将切片中节点首尾相连
执行用时 :8 ms , 内存消耗: 3.8 MB
*/
func reverseKGroup(head *ListNode, k int) *ListNode {
if head == nil || head.Next == nil {
return head
}
cur := head
var listLength int
for head != nil {
listLength++
head = head.Next
}
reverseGroupNum := (listLength) / k
if reverseGroupNum == 0 {
return cur
}
var stack = make([]*ListNode, k*reverseGroupNum)
for i := 0; i < reverseGroupNum; i++ {
for j := 0; j < k; j++ {
stack[(i+1)*k-j-1] = cur
cur = cur.Next
}
}
pre := new(ListNode)
pre.Next = stack[0]
for i := range stack {
if i == (len(stack) - 1) {
stack[i].Next = cur
break
}
stack[i].Next = stack[i+1]
}
return pre.Next
}
/*
方法2: 使用分组递归和栈
//4ms,4M
*/
func reverseKGroup(head *ListNode, k int) *ListNode {
if head == nil || head.Next == nil {
return head
}
var stack = make([]*ListNode, k)
i := k
node := head
for k > 0 {
stack[i-k] = node
if node !=nil {
node = node.Next
}else{
return head
}
k--
}
for k < i-1{
k++
stack[i-k].Next = stack[i-k-1]
}
stack[0].Next = reverseKGroup(node, k+1)
return stack[i-1]
}
/*
//尾插法
//8ms,3.8M
*/
func reverseKGroup(head *ListNode, k int) *ListNode {
if head == nil || head.Next == nil {
return head
}
var dummy = new(ListNode)
dummy.Next = head
pre, tail := dummy, dummy
tmp := pre
firstReverse := true
for{
count := k
for count>0 && tail != nil{
tail = tail.Next
count--
}
if tail == nil {
break
}
firstNode := pre.Next
for pre.Next != tail{
cur := pre.Next
pre.Next = cur.Next
cur.Next = tail.Next
tail.Next = cur
}
if firstReverse == true{
tmp.Next = tail
firstReverse = false
}
pre = firstNode
tail = firstNode
}
return tmp.Next
}
/*
//8ms,3.6M
*/
func reverseKGroup(head *ListNode, k int) *ListNode {
if head == nil || head.Next == nil {
return head
}
var dummy = new(ListNode)
dummy.Next = head
pre, tail := dummy, dummy
for{
count := k
for count>0 && tail != nil{
tail = tail.Next
count--
}
if tail == nil {
break
}
firstNode := pre.Next
for pre.Next != tail{
cur := pre.Next
pre.Next = cur.Next //第一次循环遍历结束后,因为dummy.Next=pre.Next=第一次K个反转后第一个元素
cur.Next = tail.Next
tail.Next = cur
}
pre = firstNode //改变了pre地址,不再是dummy地址
tail = firstNode
}
return dummy.Next
}