1. 程式人生 > >25. k個一組翻轉鏈表

25. k個一組翻轉鏈表

初始化 group 翻轉 println sta print listnode static 它的

題目描述:

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

k 是一個正整數,它的值小於或等於鏈表的長度。如果節點總數不是 k 的整數倍,那麽將最後剩余節點保持原有順序。

示例 :

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

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

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

說明 :

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

代碼實例:

 public static class ListNode {
        int val;
        ListNode next;
        ListNode(int x) { val = x; }
    }
    /**
     * @Description:
     * @auther: DaleyZou
     * @date: 13:46 2018-8-8 
     * @param: head 鏈表的頭結點
     * @param: k k 個節點一組進行翻轉
     * @return: ListNode
     */
    public ListNode reverseKGroup(ListNode head, int k) {
        ListNode currentNode = head;
        if (currentNode == null || k < 0){
            return head;
        }
        int count = 0;
        while (currentNode != null && count < k){ // find the k+1 node
            currentNode = currentNode.next;
            count++;
        }
        if (count == k){ // if k+1 node is found
            currentNode = reverseKGroup(currentNode, k); // reverse list with k+1 node as head
            while (count-- > 0){ // reverse current k-group:
                ListNode temp = head.next;
                head.next = currentNode;
                currentNode = head;
                head = temp;
            }
            head = currentNode;
        }
        return head;
    }

理解:

上述代碼用到了遞歸,以 k 個節點為一組來實現遞歸的翻轉。對於使用遞歸,重要的就是理解遞歸中的一次過程。


下面我們就來看一下上述代碼中,一次遞歸都幹了些什麽。

下面代碼的作用:

我們有一個鏈表 1-> 2 -> 3 -> 4 -> 5 ,我們將實現鏈表前四個節點的翻轉,
也就是要得到的結果為: 4 -> 3 -> 2 -> 1 -> 5

代碼如下:

public ListNode reverse(ListNode head, int k){
        int count = 0;
        ListNode currentNode = head;
        while (currentNode != null && count < k){
            currentNode = currentNode.next;
            count++;
        }
        while (count-- > 0) {
            ListNode tmp = head.next;
            head.next = currentNode;
            currentNode = head;
            head = tmp;
            ListNode out = currentNode;
            while (out != null){
                System.out.print(out.val + " ");
                out = out.next;
            }
            System.out.println();
        }
        return currentNode;
    }
    public static void main(String[] args){
        LeetCode25 leetcode25 = new LeetCode25();
        
        // 初始化5個鏈表節點
        ListNode head = new ListNode(1);
        ListNode head1 = new ListNode(2);
        ListNode head2 = new ListNode(3);
        ListNode head3 = new ListNode(4);
        ListNode head4 = new ListNode(5);

        // 添加節點間的關聯關系
        head.next = head1;
        head1.next = head2;
        head2.next = head3;
        head3.next = head4;

        // 對前四個節點進行翻轉
        ListNode reverse = leetcode25.reverse(head, 4);
    }

代碼輸出結果如下:

1 5

2 1 5

3 2 1 5

4 3 2 1 5

畫一個圖理解一下:

技術分享圖片


我們實現了一個 k 組翻轉,那麽實現整個鏈表的 k 組翻轉就是加上遞歸啦!

25. k個一組翻轉鏈表