题目链接:Reverse Linked List II

Reverse a linked list from position m to n. Do it in-place and in one-pass.

For example:

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

return 1->4->3->2->5->NULL.

Note:

Given m, n satisfy the following condition:

1 ≤ m ≤ n ≤ length of list.

这道题的要求是将链表中m到n位置反转。

链表处理,先加一个空表头,便于处理。然后令l指针移动到m位置前面,令r移动到m位置,这样不断把r后面的节点插入到l后面,直到n位置。

假设m=2,n=4,链表为:
head -> 1 -> 2 -> 3 -> 4 -> 5 -> NULL

加头之后为:
h -> 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> NULL

令l指针移动到m位置前面,令r移动到m位置,即:
h -> 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> NULL
          ^    ^
          |    |
          l    r

r后面的节点插入到l后面:
ListNode *temp = l -> next:
h -> 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> NULL
          ^    ^
          |    |
          l  temp、r 

l -> next = r -> next:
          |-------->|
h -> 0 -> 1    2 -> 3 -> 4 -> 5 -> NULL
          ^    ^
          |    |
          l  temp、r

r -> next = r -> next -> next:
          |-------->|
h -> 0 -> 1    2    3 -> 4 -> 5 -> NULL
          ^    |-------->|
          |    ^
          l    |
             temp、r

l -> next -> next = temp:
          |-------->|
h -> 0 -> 1    2 <- 3    4 -> 5 -> NULL
          ^    |-------->|
          |    ^
          l    |
             temp、r

即:
h -> 0 -> 1 -> 3 -> 2 -> 4 -> 5 -> NULL
          ^         ^
          |         |
          l         r

进而继续把r后面节点插入到l后面,以此类推,进行循环。。。

时间复杂度:O(n)

空间复杂度:O(1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution
{
public:
    ListNode *reverseBetween(ListNode *head, int m, int n)
    {
        ListNode *h = new ListNode(0);
        h -> next = head;
        
        ListNode *l = h, *r;
        for(int i = 1; i < m; ++ i)
            l = l -> next;
        
        r = l -> next;
        for(int i = 1; i < n - m + 1; ++ i)
        {
            ListNode *temp = l -> next;
            l -> next = r -> next;
            r -> next = r -> next -> next;
            l -> next -> next = temp;
        }
        
        return h -> next;
    }
};