剑指offer 24-反转链表 C++

8 篇文章 0 订阅

题目描述
输入一个链表,反转链表后,输出新链表的表头。

思路1:非递归解法——定义三个指针pre,cur,last,先保存当前指针cur的下一个指针last,再让cur指向上一个节点pre。

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        if(pHead==nullptr || pHead->next==nullptr)
            return pHead;
        ListNode* newHead = nullptr;  //存储反转后的链表头节点
        ListNode* cur=pHead;   //当前节点
        ListNode* pre=nullptr;  //上一个节点,此处设置为默认初始nullptr
        while(cur!=nullptr){
            ListNode* last = cur->next;  //断开节点前需保存当前节点的下一个节点
            if(last==nullptr)   //此时cur为尾节点
                newHead = cur;
            cur->next = pre;  //使当前节点指向上一个节点
            pre = cur;   //上一个节点向右
            cur = last;  //当前节点继续向右
        } 
        return newHead;
    }
};

//也可以写成如下形式
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        if(pHead==nullptr || pHead->next==nullptr)
            return pHead;
        ListNode* newHead = nullptr;
        ListNode* cur=pHead;
        ListNode* pre=nullptr;
        ListNode* last = nullptr;
        while(cur->next!=nullptr){
            last=cur->next;  
            cur->next = pre;   
            pre = cur;   
            cur = last;   
        }
        newHead = cur;
        last=cur->next;  
        cur->next = pre;   
        pre = cur;  
        cur = last;
        return newHead;
    }
};

思路2:递归解法——利用递归走到链表末端,再更新每一个node的next,而newHead不会发生改变,为该链表最后一个节点。

class Solution {
public:
    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;
    }
};

思路3:使用辅助栈

class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        if(pHead==nullptr)
            return nullptr;
        ListNode* tmp = pHead;
        while(tmp->next!=nullptr){   //注意:尾节点没有入栈!
            tmp=tmp->next;
        }
        ListNode* newHead = tmp;  //当tmp->next==nullptr时,说明此时tmp指向尾节点
        ListNode* node = newHead;
        while(!st.empty()){
            node->next = st.top();
            st.pop();
            node = node->next;
        }
        node->next = nullptr;   //注意最后让末节点指向空
        return newHead;
    }
private:
    stack<ListNode*> st;
};

//也可以写成如下
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        if(pHead==nullptr)
            return nullptr;
        ListNode* tmp = pHead;
        while(tmp!=nullptr){  //先全部入栈
            st.push(tmp);
            tmp=tmp->next;
        }
       // ListNode* newHead = new ListNode(st.size());
       // newHead = st.top();
        ListNode* newHead = st.top();   //再取栈顶元素
        st.pop();
        ListNode* node = newHead;
        while(!st.empty()){
            node->next = st.top();
            st.pop();
            node = node->next;
        }
        node->next = nullptr;   
        return newHead;
    }
private:
    stack<ListNode*> st;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值