小小程序媛  
得之坦然,失之淡然,顺其自然,争其必然

题目

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.

分析

题目给定一个链表,以及两个整数,代表链表中节点的序列号,要求,将序列号之间的子链表反转,重新链接返回。

利用栈先进后出的思想,将要求反转的节点存入栈中,然后依次弹出,重新链接即可。

需要注意的是,要准确记录反转子链表的前一个节点以及后一个节点,以便正确链接。

AC代码

class Solution {
public:
    ListNode* reverseBetween(ListNode* head, int m, int n) {
        if (head == NULL || m < 1 || n<1 || m >= n)
            return head;

        int len = 0;
        ListNode *p = head;
        //计算链表长度
        while (p)
        {
            len++;
            p = p->next;
        }
        //如果要反转的范围不符合要求则返回
        if (m > len || n > len)
            return head;

        //声明一个栈,用来保存要求反转的子序列所有节点
        stack<ListNode *> stk;

        if (m == 1)
        {
            //若从头节点反转,特殊处理
            ListNode *r = head;
            while (m <= n && r != NULL)
            {
                stk.push(r);
                r = r->next;
                ++m;
            }
            //新的头结点
            head = stk.top();
            stk.pop();
            //链接剩下节点
            ListNode *q = head;
            while (!stk.empty())
            {
                q->next = stk.top();
                q = q->next;
                stk.pop();
            }
            //链接尾节点
            q->next = r;
            return head;
        }
        else{
            ListNode *pre = head;
            //找到要反转的第一个节点的前驱并保存
            int i = 1;
            while (i < m - 1)
            {
                pre = pre->next;
                ++i;
            }

            //将所有反转节点入栈,并保存尾
            ListNode *r = pre->next;
            while (m <= n)
            {
                stk.push(r);
                r = r->next;
                ++m;
            }//while

            //链接
            while (!stk.empty())
            {
                pre->next = stk.top();
                pre = pre->next;
                stk.pop();
            }
            pre->next = r;
            return head;
        }
        return head;
    }
};

GitHub测试程序源码

posted on 2015-10-08 16:37  Coding菌  阅读(168)  评论(0编辑  收藏  举报