每日一题(3)——K个一组翻转链表

本篇文章题目来源于leetcode

前言

哈喽,大家好,我是小雨,今天完成一个链表相关的困难题:K 个一组翻转链表。

Question

给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。

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

你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

示例 1:

输入:head = [1,2,3,4,5], k = 2
输出:[2,1,4,3,5]

提示:

  • 链表中的节点数目为 n
  • 1 <= k <= n <= 5000
  • 0 <= Node.val <= 1000

Solution

看到这道题,第一反应就是最直观的模拟法,首先编写一个翻转链表的辅助函数,随后不断的寻找需要翻转的区间,进行翻转。其中需要注意的是翻转区间的前半部分和后半部分的节点,都需要注意。同时为了返回正确的result节点,还设置了一个flag,用于标识是否是第一次翻转,如果是第一次翻转那么需要设置头节点,具体代码如下:

Code

type ListNode struct {
	Val  int
	Next *ListNode
}
func reverseKGroup(head *ListNode, k int) *ListNode {
	var result *ListNode
	var resultflag bool
	var reverse func(head *ListNode, tail *ListNode) *ListNode
	//只翻转head到tail的节点,前后节点并未处理
	reverse = func(head *ListNode, tail *ListNode) *ListNode {
		var pre *ListNode
		now := head
		for pre != tail {
			temp := now.Next
			now.Next = pre
			pre = now
            now = temp
		}
		return pre
	}

	tempnode := head
	var pre *ListNode
	var start *ListNode
	var end *ListNode

	for tempnode != nil {
		flag := true
		start, end = tempnode, tempnode
		for i := 0; i < k-1; i++ {
			end = end.Next
			if end == nil {
				flag = false
				break
			}
		}
		if !flag {
			if !resultflag {
				result = start
			}
            pre.Next = start
			return result
		} else {
			tempnode = end.Next
			node := reverse(start, end)
			if resultflag {
				pre.Next = node
				pre = start
			} else {
				result = node
				resultflag = true
				pre = start
			}

		}

	}

	return result

}

总结

做链表类题目,一定不要怕变量多!多定义几个变量,这样在编写逻辑的时候才不容易出错,比如在本题中,使用tempnode变量来标识目前进行到哪个节点了,用start和end变量来标识预翻转的区间,还使用了pre来标识上一个节点,其实里面的标识有些冗余,但是对代码可读性的增加是有目共睹的。

猜你喜欢

转载自blog.csdn.net/doreen211/article/details/129334774