1. 程式人生 > >每日一題--LeetCode 25 (k個一組翻轉連結串列)java

每日一題--LeetCode 25 (k個一組翻轉連結串列)java

題目描述:

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

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

示例 :

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

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

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

說明 :

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

解題思路:可以將連結串列分成n個長度為k的新連結串列,每次將新翻轉後連結串列newlist重新連線到原來的連結串列上,最後再將不用翻轉的連結串列連線到連結串列末尾即可,詳情如下圖所示:

程式碼如下(附有解析):

/**
 * 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) {
        int len=0;
        ListNode tmp=head;
        //計算連結串列長度
        while(tmp!=null){
            len++;
            tmp=tmp.next;
        }
        len/=k;
        //當沒有要反轉連結串列的時候直接返回
        if(len==0)
            return head;
        ListNode cur=head;
        ListNode tail=cur;
        for(int i=0;i<len;i++){
            //newlist表示分離出來的連結串列
            ListNode newlist=null;
            //newhead表示分離出來連結串列的頭
            ListNode newhead=cur;
            int count=k;
            //反轉分離出來的連結串列
            while(count>0){
                tmp=cur;
                cur=cur.next;
                tmp.next=newlist;
                newlist=tmp;
                count--;
            }
            //只有當第一次反轉連結串列時不用將首尾相連,因為只有頭,所以只需要將連結串列原本的頭
            //更新即可,在後面的連結串列反轉中,則需要將分離出來的連結串列與之前的連結串列首尾相連
            if(i==0){
                head=newlist;
            }else{
                tail.next=newlist;
                tail=newhead;
            }
        }
        //連結連結串列剩餘的部分
        while(cur!=null){
            tail.next=cur;
            tail=tail.next;
            cur=cur.next;
        }
        //返回頭節點
        return head;
    }
}