反转链表_多解

文章介绍了如何使用栈和递归两种方法来反转一个给定的单链表。在栈的方法中,首先将链表的值压入栈,然后逐个弹出并更新链表节点的值。在递归的解法中,通过不断改变节点的指向,直至找到终止条件(当前节点或下一节点为nullptr),最后返回最后一个节点。
摘要由CSDN通过智能技术生成

题目描述

来源:leetcode_hot100_206
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例 1:
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

示例 2:
输入:head = [1,2]
输出:[2,1]

示例 3:
输入:head = []
输出:[]

提示:
链表中节点的数目范围是 [0, 5000]
-5000 <= Node.val <= 5000

进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?

错误示范
思路:大体思路正确,见正解一处

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        stack<ListNode *> stp;
    	ListNode *p = head;
    	while (p != nullptr)
    	{
        	stp.push(p);
        	p = p->next;
    	}
    	p = head;
        while (!stp.empty())
    	{
        	p->val = stp.top()->val;
        	stp.pop();
        	p = p->next;
    	}
        return head;
    }
};

错误原因:解答错误,因为我第二个while时直接修改了链表中的值,而stack里存的仅仅是指针的备份而非值的备份

正解一(栈)

思路:利用栈将链表的值从头到尾装入栈中,再挨个弹出修改结点的值,利用栈的先进后出特性

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        stack<int> stval;
        ListNode* p=head;
        while(p!=nullptr){
            stval.push(p->val);
            p=p->next;
        }
        p=head;
        while(p!=nullptr){
            p->val=stval.top();
            stval.pop();
            p=p->next;
        }
        return head;
    }
};

正解二(递归)

思路:力扣精选题解里有图比较好理解,光看文字不好理解
终止条件是当前节点或下一节点为nullptr
改变节点指向 p->next->next=p

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* p=head;
        if(p==nullptr || p->next==nullptr){//由reverseList(p->next)遍历到最后一个结点时会返回cur=5
            return p;
        }
        //cur不管怎么递归返回永远指的是最后一个节点,例如[1,2,3,4,5]则cur指向的节点的val永远为5
        ListNode* cur=reverseList(p->next);//先从前向后遍历到最后一个节点
        //如果链表是 1->2->3->4->5,那么此时的cur就是指向5的指针
        //又因为这句cur(=5)=reverseList(p->next)这里的p为指向4的指针
        p->next->next=p;//p->next就是5的结点 这样p->next->next(就是5结点的next)就变4了
        p->next=nullptr;//防止链表循环,此时4->5的指针应设置为4->空
        return cur;//cur一直保持指向最后一个结点直到结束
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值