1. 程式人生 > >[leetcode]Reverse Nodes in k-Group 反轉以k個節點為一組的連結串列

[leetcode]Reverse Nodes in k-Group 反轉以k個節點為一組的連結串列

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

If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.

You may not alter the values in the nodes, only nodes itself may be changed.

Only constant memory is allowed.

For 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

這個題其實挺簡單,思路是:

既然K=2 就是2個一組反轉,反轉後的點又指向了之後的節點,那麼我們就知道了:

(1)首先得把連結串列的長度求出來 要是K=連結串列長度(len),那就是整個連結串列圈反轉,要是小於,那我們只反轉k個節點。

(2)反轉了K個,那len-k個怎麼辦,我們可以想到用遞迴來求解,把剩下的節點扔到遞迴裡,讓它們自己算

那麼遞迴的base case我們肯定要讓head不為空,並且長度大於K,否則就返回null

每次都算長度太坑爹,肯定是一開始算好,把len當引數,給子問題。那麼我們就可以再寫一個帶len(連結串列長度)的函式

(3)遞迴的細節

    那我們最後返回的頭應該是什麼,肯定是第一次以K為單位反轉的頭,例如k=2 1->2->3->4->5, 那麼返回2->1->.. 

    那麼反轉節點的末尾就是:子問題,長度為3的連結串列,依次類推

最後只剩下5一個點,傳進函式後根據base case直接返回這個點就行

public class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        
       return reverseK(head, k, getLength(head));
        
    }
    
    public ListNode reverseK(ListNode head, int k, int len){
        if(k==1 || k>len || head==null) return head;
        int i=2;
        ListNode next=head.next;
        ListNode pre=head;
        head.next=null;
        ListNode dummy=head;
        while(i<=k){
            head=next;
             next=next.next;
            head.next=pre;
            pre=head;
            head=next;
            i++;
        }
        dummy.next=reverseK(head, k, len-k);
        return pre;
        
    }
    
    public int getLength(ListNode head){
        int len=0;
        while(head!=null){
            len++;
            head=head.next;
        }
        return len;
    }
}