LeetCode25:k个一组翻转链表(Golang实现)

目录

  • 题目描述
    • 示例
    • 说明
  • 分析
  • 代码
  • 运行结果

题目描述

给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表。

k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序。

示例

输入

输入链表: 1->2->3->4->5->6->7->8

输出

当k=2时,输出:2->1->4->3->6->5->8->7;
当k=3时,输出:3->2->1->6->5->4->7->8。

说明

  1. 算法只能使用常数的额外空间。
  2. 不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

分析

我们可以将链表中的每k个结点分为一组,然后将这个组(即一个子链表)进行翻转。翻转以后,当指向结点的指针继续向后移动时,递归地执行刚才的过程

代码

package main
import "fmt"

type ListNode struct {
	Val int
	Next *ListNode
}

func reverseKGroup(head *ListNode, k int) *ListNode {
	var pre, next *ListNode
	var cur, p *ListNode = head, head
	groupSize, index := 0, 0
	// 将链表的前k个结点组成一组
	for p != nil && groupSize < k {
		p = p.Next
		groupSize++
	}
	if groupSize == k {
	    // 翻转该k个结点组成的子链表
		for cur != nil && index < k {
			next = cur.Next
			cur.Next = pre
			pre = cur
			cur = next
			index++
		}
		// 继续递归地执行上述过程
		if next != nil {
		    // head指向子链表翻转后的尾节点
			head.Next = reverseKGroup(next, k)
		}
		// pre记录了为子链表翻转后的头结点
		return pre
	} else {
	    // 子链表长度不足k,不翻转
		return head
	}
}

func main() {
	a := []int{1, 2, 3, 4, 5, 6, 7, 8}
	l := &ListNode {a[0], nil}
	p := l
	for _, r := range a[1:] {
		node := &ListNode {r, nil}
		p.Next = node
		p = p.Next
	}
	k := 3
	res := reverseKGroup(l, k)
	for res != nil {
	    if res.Next != nil {
	        fmt.Printf("%d->", res.Val)
		} else {
		    fmt.Printf("%d", res.Val)
		}
		res = res.Next
	}
}

运行结果

k=2
LeetCode25:k个一组翻转链表(Golang实现)_第1张图片
k=3
LeetCode25:k个一组翻转链表(Golang实现)_第2张图片

你可能感兴趣的:(编程题)