leetcode journal《剑指offer》-链表(从尾到头打印链表/反转链表/复杂链表的复制)


题目1:从尾到头打印链表

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。

示例输入:

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

提示:

  • 0 <= 链表长度 <= 10000

题解:

​ 比较basic,就遍历链表,使用栈存一下数据再复制到vector里面返回好了。

代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> reversePrint(ListNode* head) {
        stack<int> my_stack;
        vector<int> res;
        ListNode* p=head;
        while(p!=NULL)
        {
            my_stack.push(p->val);
            p=p->next;
        }
        while(!my_stack.empty())
        {
            res.push_back(my_stack.top());
            my_stack.pop();
        }
        return res;
    }
};


题目2:反转链表

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

示例输入:

示例1:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULLxxxxxxxxxx 

提示:

  • 0 <= 节点个数 <= 5000

题解:

​ 比较basic,使用头插法,最后遍历完原来的链表之后得到的正好是反转链表的表头结点,可以直接返回。

代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(head==NULL)
        {
            return NULL;
        }
        ListNode *res,*p,*q;
        res=NULL;//res指向反转链表
        p=head;
        while(p!=NULL)
        {
            q=new ListNode;
            q->val=p->val;//q暂存当前的节点
            q->next=res;//q插在当前反转链表的表头结点前
            res=q;//更新表头结点
            p=p->next;
        }
        return res;
    }
};


题目3:复杂链表的复制

请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null

示例输入:

示例1:

https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2020/01/09/e1.png

输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
示例2:

在这里插入图片描述

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

在这里插入图片描述

输入:head = [[3,null],[3,0],[3,null]]
输出:[[3,null],[3,0],[3,null]]
示例4:
输入:head = []
输出:[]
解释:给定的链表为空(空指针),因此返回 null。

提示:

  • -10000 <= Node.val <= 10000
  • Node.random 为空(null)或指向链表中的节点。
  • 节点数目不超过 1000 。

题解:

​ 这三道题里面最不basic的题。如果选择深拷贝直接返回head有点缺德,这题选择了哈希表来做。

​ 首先考虑空链表的情况,直接返回NULL

​ 其次对于链表非空的情况,把对应节点存储到map里面去,同时复制一下这个节点存放在对应节点的表中。

​ 完成哈希表的构造后进行一次循环,从原链表的表头循环到表尾,对于链表中的每一项,都可以得到原结点的nextrandom项,而对于这两项指向的结点,我们可以找到他们对应在哈希表中新结点,因此只要把新结点的nextrandom连接起来即可。

整个算法的流程就是构造→复制→连接

代码:

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* next;
    Node* random;
    
    Node(int _val) {
        val = _val;
        next = NULL;
        random = NULL;
    }
};
*/
class Solution {
public:
    Node* copyRandomList(Node* head) {
        Node *p,*q,*t,*res;
        map<Node*,Node*> hash;
        p=head;
        while(p!=NULL)//构造哈希表
        {
            t=new Node(p->val);//复制原结点
            hash[p]=t;
            p=p->next;
        }
        p=head;
        while(p!=NULL)
        {
            hash[p]->next=hash[p->next];//新结点的next指向对应next结点的新结点
            hash[p]->random=hash[p->random];//新结点的random指向对应random结点的新结点
            p=p->next;
        }
        return hash[head];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值