反转链表

反转链表

http://www.nowcoder.com/questionTerminal/75e878df47f24fdc9dc3e400ec6058ca

描述

这是一篇针对初学者的题解,共用2种方法解决。
知识点:单链表
难度:一星


题解

方法一:构造链表

如果此类型的题出现在笔试中,如果内存要求不高,可以采用如下方法:
可以先用一个vector将单链表的指针都存起来,然后再构造链表。
此方法简单易懂,代码好些。
###代码:

class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        if (!pHead) return nullptr;
        vector<ListNode*> v;
        while (pHead) {
            v.push_back(pHead);
            pHead = pHead->next;
        }
        reverse(v.begin(), v.end()); // 反转vector,也可以逆向遍历
        ListNode *head = v[0];
        ListNode *cur = head;
        for (int i=1; i<v.size(); ++i) { // 构造链表
            cur->next = v[i]; // 当前节点的下一个指针指向下一个节点
            cur = cur->next; // 当前节点后移
        }
        cur->next = nullptr; // 切记最后一个节点的下一个指针指向nullptr
        return head;
    }
};

时间复杂度:O(n)
空间复杂度:O(n), 用了一个vector来存单链表

方法二:正规解法

但是面试的时候,上一种解法当然不行。此题想考察的是:如何调整链表指针,来达到反转链表的目的。
初始化:3个指针
1)pre指针指向已经反转好的链表的最后一个节点,最开始没有反转,所以指向nullptr
2)cur指针指向待反转链表的第一个节点,最开始第一个节点待反转,所以指向head
3)nex指针指向待反转链表的第二个节点,目的是保存链表,因为cur改变指向后,后面的链表则失效了,所以需要保存
接下来,循环执行以下三个操作
1)nex = cur->next, 保存作用
2)cur->next = pre 未反转链表的第一个节点的下个指针指向已反转链表的最后一个节点
3)pre = cur, cur = nex; 指针后移,操作下一个未反转链表的第一个节点
循环条件,当然是cur != nullptr
循环结束后,cur当然为nullptr,所以返回pre,即为反转后的头结点
这里以1->2->3->4->5 举例:
图片说明
图片说明
图片说明
图片说明
中间都是重复步骤,省略了。。。


代码

class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        ListNode *pre = nullptr;
        ListNode *cur = pHead;
        ListNode *nex = nullptr; // 这里可以指向nullptr,循环里面要重新指向
        while (cur) {
            nex = cur->next;
            cur->next = pre;
            pre = cur;
            cur = nex;
        }
        return pre;
    }
};

时间复杂度:O(n), 遍历一次链表
空间复杂度:O(1)

全部评论
学到了
1
送花
回复
分享
发布于 2021-12-10 12:08
cur 指针并不需要吧,可以直接用 pHead
1
送花
回复
分享
发布于 2021-12-22 12:01
秋招专场
校招火热招聘中
官网直投
请问一下各位大佬,这个案例中是不是不需要考虑头结点?
1
送花
回复
分享
发布于 2021-12-23 09:30
官方可以出多个语言版本的解答方式吗
37
送花
回复
分享
发布于 2021-08-09 09:01
我觉得可以无限乡下递归,递归到next为空的时候,然后return,这样他就会从最后的node开始返回。然后将每一个node放入一个新的ListNode中
5
送花
回复
分享
发布于 2021-11-25 10:36
请问一下,入参pHead在函数调用结束后是不是指向了nullptr呀?这样是否导致毁坏了入参数据呢?
点赞
送花
回复
分享
发布于 2021-03-14 15:12
怎么运行都是报错啊SyntaxError: invalid syntax
点赞
送花
回复
分享
发布于 2021-12-05 21:47
太妙了
点赞
送花
回复
分享
发布于 2022-02-15 01:41
数字科技线 - 蚂蚁链 - 平台技术部 关于我们: 科技与才智相伴,青春与金融相遇, 蚂蚁集团,期待与你同行。 你也在追逐梦想吗? 2022年,蚂蚁集团区块链平台部校园招聘正式启动, 我们决心不辜负每一个有梦想的不凡青春,我们期待每一个不凡青春共同为世界带来微小而美好的改变。 你一定出类拔萃, 缺的只是展示的平台, 我们给你的不只是一份工作, 更是一片任你翱翔的天空, 没有更多华丽的词藻,只希望我们能坦诚相待。 招聘对象: 2022.11-2023.10毕业的应届毕业生 招聘流程: 简历投递->在线笔试及测评->面试->发送录用意向书 岗位类型: 技术类 :算法,JAVA/C++,前端,测试,数据,安全, 区块链研发等 非技术类:产品,运营,风险策略,数据分析,反洗钱, 体验设计等 工作地点: 杭州、上海、北京、成都、深圳、广州、重庆 联系邮箱: xuanhao.zx@antgroup.com 【社招岗位也有哟!】
点赞
送花
回复
分享
发布于 2022-02-28 10:18
递归解法,思路简单、代码少。 public class Solution { public ListNode ReverseList(ListNode head) { if (head == null) { return head; } ListNode next = head.next; if (next == null) { return head; } ListNode newHead = ReverseList(next); next.next = head; head.next = null; return newHead; } }
点赞
送花
回复
分享
发布于 2022-03-10 22:43
好详细的讲解,谢谢官方
点赞
送花
回复
分享
发布于 2022-04-05 17:08
麻了,钻了牛角尖,想着O(1)就想成只创建一个变量了。。。
点赞
送花
回复
分享
发布于 2022-04-18 17:23
struct ListNode* q = pHead; struct ListNode* p = NULL; pHead = NULL; while(q) { p = q; q = q->next; p->next = pHead; pHead = p; } return pHead;
点赞
送花
回复
分享
发布于 2023-01-06 11:35 浙江
cur->next=pre; pre=cur; 为什么不能直接cur->next=cur呢
点赞
送花
回复
分享
发布于 2023-03-06 14:58 江西

相关推荐

492 85 评论
分享
牛客网
牛客企业服务