首页 > 其他分享 >JZ6 从尾到头打印链表

JZ6 从尾到头打印链表

时间:2023-03-22 23:33:56浏览次数:40  
标签:pre head cur res 链表 vector 从尾 JZ6

   

链表是存储数据的一种方式,由于内存不是连续的,因此访问只能从表头访问表尾。本题需要从尾部到头打印链表,只能借助特殊的数据结构输出,但是访问顺序不会因此改变。

首先,可以借助递归是到达底层后才会往上回溯的特性来遍历链表。

class Solution {
public:
    void recursion(ListNode* head, vector<int> & res)//注意引用的传参方式
    {
        if(head == nullptr) return;//递归的终止条件
        recursion(head->next, res);//访问顺序是从头到尾
        res.push_back(head->val);//再填充到数组就是逆序
    }
    vector<int> printListFromTailToHead(ListNode* head) {
        vector<int> res;
        recursion(head, res);
        return res;
    }
};

另外,还有借助栈的后入先出的特性,也能够逆序输出链表。

class Solution {
public:
    vector<int> printListFromTailToHead(ListNode* head) {
        vector<int> res;
        stack<int> s;
        while(head != null){
            s.push(head->val);
            head = head -> next;
        }
        while(!s.empty()){
            res.push_back(s.top());
            s.pop();
        }
        return res;
    }
};

两者的时间复杂度都是O(n),空间复杂度都是O(n),因为递归栈也是占用空间的。需要注意,当链表非常长时,会导致函数调用的层级很深,从而有可能导致函数调用栈溢出。用栈基于循环实现的代码的鲁棒性要好一些。

下面是第三种解法:反转链表

vector<int> printListFromTailToHead(ListNode* head) {
        ListNode *pre, *tmp, *cur;
        pre = nullptr;
        cur = head;
        while(cur){
            tmp = cur -> next;
            cur->next = pre;
            pre = cur;
            cur = tmp;
        }

        vector<int> res;
        while(pre){
            res.push_back(pre->val);
            pre = pre->next;
        }
        return res;
    }

这个要是理解的话最好去牛客网的题解里找一下那个动图,只要理解了pre,cur和tmp三个指针的含义,其实就非常好理解了。

这个优化了空间,为O(1).

O

 

标签:pre,head,cur,res,链表,vector,从尾,JZ6
From: https://www.cnblogs.com/luxiayuai/p/17245900.html

相关文章

  • 论单向链表有序插入方案
    0.思考单向链表有序插入,插入点分为这样几个地方:当前链表为空,被插入节点是第一个节点被插入节点作为头结点被插入节点在中间被插入节点在尾部那么按照这样的步骤一......
  • 单链表OJ题解析1
    1.移除链表元素题目链接题目描述 解题思路这道题较好的解法是创建一个新链表,把不等于val的节点链接到一起,然后返回新链表的头结点structListNode*removeEle......
  • 链表操作-leetcode23-删除倒数第几个节点
    给你一个链表,删除链表的倒数第n个结点,并且返回链表的头结点。示例1:示例2:输入:head=[1],n=1输出:[]示例3:输入:head=[1,2],n=1输出:[1]提示:链表中结......
  • LeetCode|876. 链表的中间结点
    题目链接:876.链表的中间结点难度简单829收藏分享切换为英文接收动态反馈给你单链表的头结点head,请你找出并返回链表的中间结点。如果有两个中间结点,则返回第二个中......
  • c++链表记录
    ListNode*pre=NULL;//定义一个空节点ListNode*tmp;//定义一个空的临时节点,此时tmp==NULL ListNode*cur=head;//定义一个等于节点head的节点 ListNode*du......
  • 链表知识点
    链表知识点总结链表简介链表:是由一种一个或多个指针域和数据域组成的特殊数据结构链表类型单链表单链表中的指针域指向下一个节点双链表双链表中有两个指针域,一个......
  • 数据结构-->带头双向循环链表--->优化
    好了,各位老铁!!现在开始本期讨论话题:<--头删数据----头插数据-->直接上手代码:头文件“List.h”#include<stdio.h>#inculde<stdlib.h>//扩容函数malloc库#include<asse......
  • algrothm_reverse(algrothm+round)【反转链表】
    ......
  • 数据结构-->带头双向循环链表
    好了,小伙伴们!!本期我们开始“带头双向循环链表”!!很显然,这一次要涉及哨兵位了!!而在这之前,单向链表当中没有丝毫提及“哨兵位”的概念!!其实,这是因为,带哨兵位的单向链表在实际开发......
  • 合并链表-leetcode23-合并k个升序链表
    给你一个链表数组,每个链表都已经按升序排列。请你将所有链表合并到一个升序链表中,返回合并后的链表。示例1:输入:lists=[[1,4,5],[1,3,4],[2,6]]输出:[1,1,2,3,4,4,5,6......