Reverse Nodes in k-Group

Reverse Nodes in k-Group

题目

Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.

k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.

Example:

Given this linked list: 1->2->3->4->5
For k = 2, you should return: 2->1->4->3->5
For k = 3, you should return: 3->2->1->4->5

Note:

  • Only constant extra memory is allowed.
  • You may not alter the values in the list’s nodes, only nodes itself may be changed.

分析

Swap Nodes in Pairs和这道题的区别在于,前者的k是2,而这道题的k不确定,作为参数给出。
两道题都要求不能直接改变节点的值,只能改变其指针的指向。
虽然这道题前面说了,k是正整数且k的值小于等于链表的长度。但在实际的测试样例中,k的值有可能大于链表的长度。

这道题的思路也比较简单。就是每k个节点作为一组,然后reversek个节点。如果剩下的不足k个节点,则不进行reverse

在一个循环里面,首先判断有没有k个节点。如果没有,则终止循环;如果有,则对前k个节点进行reverse,然后进入下一轮循环。每一轮循环需要记录这k个节点reverse之后的head节点和tail节点,然后prev节点(即上一轮循环得到的链表的tail节点)的next指向这一轮循环的head节点。然后更新prev节点的值为tail

如何对长度为k个节点的链表进行reverse
方法还是比较简单的。遍历整个链表,对于某个节点node,将当前的tail节点的next指向node节点的next节点,将node节点的next指向当前的head节点,并且更新head节点的值为node节点。然后继续遍历下一个节点。
注意:tail节点的值一直不变,只是其next节点一直在变化。
如下所示:

假设链表为:1->2->3->4->5
刚开始时 head = tail = 1
然后遍历到下一个节点2,此时链表更新为:2->1->3->4->5,此时head = 2,tail = 1。
......
继续循环下去,知道最后链表更新为:5->4->3->2->1。此时head = 5,tail还是1。

代码如下

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
				if (k == 1 || head == null) return head;
        ListNode result = head;
        ListNode prev = null;
		ListNode tempHead = head;
		ListNode newHead = null;
		ListNode tempNode = tempHead;
		// 因为第一次prev是null,所以单独处理而不在循环中处理
		for (int i = 0; i < k; i++) {
			if (tempNode == null) {
				return result;
			} else {
				tempNode = tempNode.next;
			}
		}
		newHead = reverseKNodes(tempHead, k);
		result = newHead;
		prev = tempHead;
		tempHead = tempHead.next;
		
		// 剩下的循环
        while (true) {
    		tempNode = tempHead;
			// 判断剩下的时候有k个节点
			for (int i = 0; i < k; i++) {
				if (tempNode == null) {
					return result;
				} else {
					tempNode = tempNode.next;
				}
			}
			newHead = reverseKNodes(tempHead, k);
			prev.next = newHead;
			prev = tempHead;
			tempHead = tempHead.next;
		}
    }
	
	// 返回值为倒置之后的头节点,head仍然指向原本的头节点,即倒置后的尾节点
	private ListNode reverseKNodes(ListNode head, int k) {
		ListNode tempHead = head;
		ListNode tempTail = head;
		ListNode temp = null;
		for (int i = 1; i < k; i++) {
			// 交换节点
			temp = tempTail.next;
			tempTail.next = temp.next;
			temp.next = tempHead;
			tempHead = temp;
		}
		return tempHead;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值