1. 程式人生 > >lintcode 36 Reverse Linked List II

lintcode 36 Reverse Linked List II

題目描述

Description
Reverse a linked list from position m to n.

  • Given m, n satisfy the following condition: 1 ≤ m ≤ n ≤ length of list.

Example
Given 1->2->3->4->5->NULL, m = 2 and n = 4, return 1->4->3->2->5->NULL.

Challenge
Reverse it in-place and in one-pass

思路

之前寫過連結串列翻轉,是翻轉整個連結串列的,當然這裡改了一部分,只不過只需要加幾步就行了。

  1. 找到開始翻轉的節點,然後開始斷開連結串列,形成兩個連結串列,一個是翻轉位置前面的連結串列,一個是翻轉位置開始的連結串列。
  2. 連結串列翻轉,不過這裡跟之前有點不同,我是採用,將每個節點依次斷開,插入到前面的連結串列的最後一個位置中。
  3. 找到翻轉後的最後節點,進行拼接。

感覺這個思路說著可能不好理解
在這裡插入圖片描述
連結串列:1->2->3->4->5->6->7->null m:3   n:6
得到的連結串列應該是:1->2->6->5->4->3->7->null
下面是步驟

  1. 1->2->null, 3->4->5->6->7->null
  2. 1->2->3->null, 4->5->6->7->null
  3. 1->2->4->3->null, 5->6->7->null
  4. 1->2->5->4->3->null, 6->7->null
  5. 1->2->6->5->4->3->null, 7->null
  6. 1->2->6->5->4->3->7->null

這樣比較容易理解了吧

程式碼

public ListNode reverseBetween(ListNode head, int m, int n) {
        // write your code here
        /*
        新建一個連結串列result,用連結串列next節點表示head初始頭結點,head再等於result,
        避免m = 1時不進行反轉。
        */
        ListNode result = new ListNode(0);
        result.next = head;
        head = result;
        /*
        找到第一個開始翻轉的節點
         */
        while (m > 1) {
            head = head.next;
            m--;
            n--;
        }
        ListNode start = head.next;
        ListNode temp;
        head.next = null;
        /*
        開始翻轉
         */
        while (n > 0) {
            temp = start;
            start = start.next;
            temp.next = head.next;
            head.next = temp;
            n--;
        }
        /*
        找到第一個連結串列最後一個節點,並進行連線
         */
        while (head.next != null) {
            head = head.next;
        }
        head.next = start;
        return result.next;
    }