[leetcode日記]25.K個一組翻轉鏈表

題目

給你一個鏈表,每 k 個節點一組進行翻轉,請你返回翻轉後的鏈表。

k 是一個正整數,它的值小於或等於鏈表的長度。

如果節點總數不是 k 的整數倍,那麼請將最後剩餘的節點保持原有順序。

示例:

給你這個鏈表:1->2->3->4->5

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

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

說明:

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

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/reverse-nodes-in-k-group
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。

分析

這道題目標記的難度是困難,但是我感覺是一道容易題。今天是第四天學習Java,於是我用我那三腳貓的Java進行了實現。

說一下思路,
步驟分解:

  • 鏈表分區爲已翻轉部分+待翻轉部分+未翻轉部分
  • 每次翻轉前,要確定翻轉鏈表的範圍,這個必須通過 k 此循環來確定
  • 需記錄翻轉鏈表前驅和後繼,方便翻轉完成後把已翻轉部分和未翻轉部分連接起來
  • 初始需要兩個變量 pre 和 end,pre 代表待翻轉鏈表的前驅,end 代表待翻轉鏈表的末尾
  • 經過k此循環,end 到達末尾,記錄待翻轉鏈表的後繼 next = end.next
  • 翻轉鏈表,然後將三部分鏈表連接起來,然後重置 pre 和 end 指針,然後進入下一次循環
  • 特殊情況,當翻轉部分長度不足 k 時,在定位 end 完成後,end==null,已經到達末尾,說明題目已完成,直接返回即可

時間複雜度爲 O(n*K)O(n∗K) 最好的情況爲 O(n)O(n) 最差的情況未 O(n^2)O(n ^2 )
空間複雜度爲 O(1)O(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) {
    ListNode dummy = new ListNode(0);
    dummy.next = head; 

    ListNode pre = dummy; 
    ListNode end = dummy; 

    while (end.next != null) {
        for (int i = 0; i < k && end != null; i++) end = end.next; 
        if (end == null) break; 
        ListNode start = pre.next; 
        ListNode next = end.next; 
        end.next = null; 
        pre.next = reverse(start); 
        start.next = next; 
        pre = start; 

        end = pre;
    }
    return dummy.next;
}

    private ListNode reverse(ListNode head) {
    ListNode pre = null;
    ListNode curr = head;
    while (curr != null) {
        ListNode next = curr.next;
        curr.next = pre;
        pre = curr;
        curr = next;
    }
    return pre;
    }
}

運行結果

在這裏插入圖片描述

效率是OK了,但是空間有些莫名其妙。
從官方題解複製了以下,內存排名並不能更好看。

感謝大家的點贊和評論。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章