剑指offer24:反转链表

题目:输入一个链表,反转链表后,输出新链表的表头.

思路一:链表反转,需将节点指向改变. 可以每次取下一个节点向之前的节点中插入,采用头插法实现.需要三个指针,分别指向反转链表的头节点,旧链表中下一个代插入节点,以及此节点的下一个节点的指针(防止断链).

ListNode* ReverseList(ListNode* pHead) {
        if(pHead==nullptr)
            return nullptr;
        ListNode* newHead =pHead;
        ListNode* p1 = pHead->next;
        ListNode* p2 = nullptr;
        newHead->next = nullptr;
        while(p1!=nullptr){
            p2 = p1->next;
            p1->next = newHead;
            newHead = p1;
            p1 = p2;
        }
        return newHead;
    }

思路二:上诉采用头插法,后面的节点变为前面的,有种栈的感觉,因此可以使用栈实现,但复杂度变大,作开拓思路用.

ListNode* ReverseList(ListNode* pHead) {
        if(pHead==nullptr)
            return nullptr;
        stack<ListNode*> st;
        ListNode* newHead =nullptr;
        ListNode* p1 = pHead;
        ListNode* p2 = newHead;
        while(p1!=nullptr){
            st.push(p1);
            p1 = p1->next;
        }
        while(!st.empty()){
            ListNode* tmp = st.top();
            tmp->next= nullptr; //断链
            st.pop();
            if(newHead==nullptr){
                newHead=tmp;
                p2 =newHead;
            }
            else{
                p2->next=tmp;
                p2=p2->next;
            }
        }
        return newHead;
    }

当使用栈可以实现时,就可以想到递归实现, 递归时需要将最后一个节点作为头节点返回. 对于其他节点的反转,是将其下一个节点指向的next指针指向它:

ListNode* ReverseList(ListNode* pHead) {
    if(pHead==nullptr || pHead->next==nullptr)
        return pHead;
    ListNode* newHead = ReverseList(pHead->next);
    pHead->next->next=pHead;
    pHead->next=nullptr;
    return newHead;
}

拓展:网易的一道面试题,给一个链表,指定反转从k至m的区间. 若k到m区间存在,对区间内的链表进行 反转后,需再将链表两端接上.

ListNode* ReverseList(ListNode* pHead) {
        if(pHead==nullptr)
            return nullptr;
        ListNode* newHead =pHead;
        ListNode* p1 = pHead->next;
        ListNode* p2 = nullptr;
        newHead->next = nullptr;
        while(p1!=nullptr){
            p2 = p1->next;
            p1->next = newHead;
            newHead = p1;
            p1 = p2;
        }
        return newHead;
    }

ListNode* ReversePatialList(ListNode* pHead, int k, int m){
    if(pHead==nullptr || k>=m)
        return nullptr;
    ListNode* p1=pHead;
    ListNode* p2=nullptr;
    ListNode* begin=nullptr;
    ListNode* end=pHead;
    for(int i=1;i<m;i++){
        if(i<k){
            if(i != k-1){
                p1 = p1->next;
                if(p1==nullptr)
                    return nullptr;
            }
            else{
                begin= p1->next;
            }
        }
        end = end->next;
        if(end==nullptr)
            return nullptr;
    }
    p2 = end->next;
    end->next=nullptr;
    ReverseList(begin);
    p1->next = end;
    begin->next=p2;
    return pHead;
}