LeetCode中 翻转链表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=1,也就是说m和n一样的情况。然后是m=1的情况,m=1就意味着没有前一个节点,需要分两种情况考虑。
总结一下我的思路:
1,首先找到要反转的那部分节点,我是通过num叠加找到的,记录这部分节点前一个节点pre,将这部分节点开始节点记为p,记录这部分节点后一个节点q。
2,将p和q输入到reverse函数,也就是倒转函数,利用3节点法。
3,融合链表,分情况考虑,第一,pre == NULL的情况,这时直接将head = reverse返回节点;第二,pre !=NULL,那么pre->next = reverse返回节点。
这道题的难点在于边界情况很难想清楚,有点打脑袋。
代码如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/

class Solution {
public:
    ListNode* reverseBetween(ListNode* head, int m, int n) {
        int num = 1;
        ListNode* pre = NULL;
        ListNode* cur = head;
        ListNode* p;
        ListNode* q;
        if(head == NULL && head->next == NULL)
        {
            return head;
        }
        while(num != m)
        {
            pre = cur;
            cur = cur->next;
            num++;
        }

        p = cur;

        while(num != n)
        {
            cur = cur->next;
            num++;
        }

        cur = cur->next;
        q = cur; //q设置为下一个节点有好处,在反转时可以节约很多运算时间

        if(pre == NULL)
        {
            head = reverse(p , q);
            p->next = cur;
        }
        else
        {
           pre->next = reverse(p , q);
           p->next = cur;
        }
        return head;
    }

   ListNode* reverse(ListNode* head,ListNode* q) //翻转的思想很简单,就是3节点翻转思想,cur指向pre ,pre= cur,cur = next。另外不改变head有好处。
    {
        ListNode* pre = NULL;
        ListNode* cur = head;
        ListNode* next ;
        while(cur != q)
        {
            next = cur->next;
            cur->next = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }
};

你可能感兴趣的:(数据结构,leetcode,链表)