Skip to content
本页目录

0025-K个一组翻转链表

https://leetcode.cn/problems/reverse-nodes-in-k-group

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

进阶:

  • 你可以设计一个只使用常数额外空间的算法来解决此问题吗?
  • 你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

示例 1:

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

示例 2:

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

示例 3:

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

示例 4:

输入:head = [1], k = 1
输出:[1]

提示:

列表中节点的数量在范围 sz 内
1 <= sz <= 5000
0 <= Node.val <= 1000
1 <= k <= sz

思路【TODO:需要强化】

  1. 定义 dummyHead
  2. 循环 k 次,如果能发现结尾,则进行翻转链表操作
  3. 继续下一组循环
  4. 注意翻转链表返回头和尾

参考代码

csharp
public class Solution {

	private ListNode[] ReverseListNode(ListNode head, ListNode tail){
		ListNode pre = tail.next;
		ListNode p = head;
		while(pre != tail){
			ListNode next = p.next;
			p.next = pre;
			pre = p;
			p = next;
		}
		return new ListNode[]{tail,head};
	}

    public ListNode ReverseKGroup(ListNode head, int k) {
    	ListNode dummyHead = new ListNode();
    	dummyHead.next = head;
    	ListNode pre = dummyHead;

    	while(head != null){
    		ListNode tail = pre;

	    	for(int i=0; i<k; i++){
	    		tail = tail.next;
	    		if(tail == null){
	    			return dummyHead.next;
	    		}
	    	}

	    	ListNode next = tail.next;
			ListNode[] result = ReverseListNode(head,tail);
			head = result[0];
			tail = result[1];
			//重新链接前后节点
			pre.next = head;
			tail.next = next;
			//下一组
			pre = tail;
			head = tail.next;
    	}

    	return dummyHead.next;
    }
}

复习:20220603

csharp
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     public int val;
 *     public ListNode next;
 *     public ListNode(int val=0, ListNode next=null) {
 *         this.val = val;
 *         this.next = next;
 *     }
 * }
 */
public class Solution {

    private void ReverseNode(ListNode head, ListNode tail, out ListNode newHead, out ListNode newTail){
        ListNode pre = null;
        ListNode cur = head;
        while(cur != tail){
            ListNode temp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = temp;
        }
        cur.next = pre;
        newHead = cur;
        newTail = head;
    }

    public ListNode ReverseKGroup(ListNode head, int k) {
        //子函数翻转链表,返回头尾
        ListNode dummy = new ListNode();
        dummy.next = head;
        ListNode pre = dummy;

        while(head != null){
            ListNode tail = pre;
            for(int i=0; i<k; i++){
                tail = tail.next;
                if(tail == null){
                    return dummy.next;
                }
            }
            ListNode next = tail.next;

            ListNode newHead, newTail;
            //Console.WriteLine("head {0}, tail {1}", head.val, tail.val);

            ReverseNode(head, tail, out newHead, out newTail);

            //输出新的头和尾
            //Console.WriteLine("new head {0}, new tail {1}", newHead.val, newTail.val);
            
            pre.next = newHead;
            newTail.next = next;

            pre = newTail;
            head = newTail.next;

        }

        return dummy.next;
    }
}

Released under the MIT License.