1. 程式人生 > >連結串列與遞迴/連結串列翻轉-LeetCode25-k個一組翻轉連結串列

連結串列與遞迴/連結串列翻轉-LeetCode25-k個一組翻轉連結串列

題目

給出一個連結串列,每 k 個節點一組進行翻轉,並返回翻轉後的連結串列。

k 是一個正整數,它的值小於或等於連結串列的長度。如果節點總數不是 k 的整數倍,那麼將最後剩餘節點保持原有順序。

示例 :

給定這個連結串列:1->2->3->4->5

當 k = 2 時,應當返回: 2->1->4->3->5

當 k = 3 時,應當返回: 3->2->1->4->5

說明 :

你的演算法只能使用常數的額外空間。
你不能只是單純的改變節點內部的值,而是需要實際的進行節點交換。

思路

遞迴,大致思路類似 

https://blog.csdn.net/qq_36025975/article/details/84585979

不同之處在於需要翻轉連結串列。

程式碼

/**
 * 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) {
        ListNode headcopy=head;
        // 計算連結串列長度
        int length=0;
        while(true){
            if(head==null){
                break;
            }
            length++;
            head=head.next;
            if(length>=k){
                break;
            }
        }
        head=headcopy;
        // 連結串列長度<k 什麼也不做
        if(length<k){
            return head;
        }
        
        if(k==1){
            return head;
        }
        // 連結串列長度>=k 將前k個結點為一組進行翻轉
        ListNode s=head;
        ListNode e=head;
        ListNode f=head.next;
        // k個結點中已經翻轉的結點數量
        int reversecount=1;
        while(true){
            if(reversecount==k-1){
                // 翻轉第k個結點
                e.next=reverseKGroup(f.next,k);
                f.next=s;
                s=f;
                break;
            }else{
                // 翻轉前<k個結點
                e.next=f.next;
                f.next=s;
                s=f;
                f=e.next;
                reversecount++;
            }
        }
        return s;
        
    }
}