【五月集训5.13】———双向链表

请添加图片描述

☘前言☘

开更五月集训专题,由浅入深,深入浅出,飞向大厂!

🧑🏻作者简介:一个从工业设计改行学嵌入式的年轻人
✨联系方式:2201891280(QQ)
全文大约阅读时间: 20min



1472. 设计浏览器历史记录

1472. 设计浏览器历史记录

解题思路

直接设计一个双向链表就好了,要注意边界条件和内存泄露的问题。

代码

struct node{
    string val;
    node * prev, *next;
};
class BrowserHistory {
    node *head, *now;
public:
    BrowserHistory(string homepage) {
        head = new node();//插入一个节点
        head->next = head->prev = NULL;
        head->val = homepage;
        now = head;
    }
    
    void visit(string url) {
        while(now->next){   //释放节点 防止内存泄漏
            node *tmp = now->next;
            now->next = now->next->next;
            delete tmp;
        }
        node *tmp = new node(); //插入节点
        tmp->prev = now;tmp->next = NULL;
        tmp->val = url;
        now->next = tmp;
        now = tmp;
    }
    
    string back(int steps) {
        for(;steps && now -> prev; --steps)	//直接走 如果到头了或者到位置都停止
            now = now->prev;
        return now->val;
    }
    
    string forward(int steps) {
        for(;steps && now -> next; --steps)	//直接走 如果到头了或者到位置都停止
            now = now->next;
        return now->val;
    }
};

注意的点

  1. 一定要删除节点,否则会内存泄漏。
  2. 一般来说会判断next或prev指针是否非空,非空才走,否则不走。这样会少很多来来回回的操作。慎记

430. 扁平化多级双向链表

430. 扁平化多级双向链表

解题思路

其实是一个典型的栈的思路,为了统一采用头节点处理一下。不然的话第一个节点就被跳过去了,不好。然后因为我是先修改下一步去哪里,所以prev节点就跟着走记录前一个就好了。

代码

class Solution {
    stack<Node*>   stk;
public:
    Node* flatten(Node* head) {
        Node *prehead = new Node();
        prehead->next = head;
        for(Node *p = prehead, *q = head;q || !stk.empty(); p = p->next ){
            if(q->child){
                if(q->next) stk.push(q->next);  //入栈记录
                q->next = q->child;q->child = NULL; //改变指针指向 清除child
            }else if(!q->next && !stk.empty()){  //下个空但是栈内有元素
                q->next = stk.top();
                stk.pop();  //取出元素挂链上
            }
            q->prev = p;    //修改前置指针
            q = q->next;
        }
        delete(prehead);
        if(head)    head->prev = NULL;  //修改第一个指针
        return  head;
    }
};

注意的点

  1. 最后记得还原第一个指针
  2. 记得要delete不要的内存

剑指 Offer II 028. 展平多级双向链表

剑指 Offer II 028. 展平多级双向链表

解题思路

和上面那一题一样。不写了。

剑指 Offer 36. 二叉搜索树与双向链表

剑指 Offer 36. 二叉搜索树与双向链表

解题思路

有几个知识点,其中有搜索树的中序遍历就是顺序方式,所以采用中序遍历,利用全局变量记录前一个点,最终找最后一个点连成循环。

代码

class Solution {
    Node *pre;
    void zhongxu(Node *root){
        if(root->left)  zhongxu(root->left);
        pre->right = root;
        root->left = pre;
        pre = root;
        if(root->right) zhongxu(root->right);
    }
public:
    Node* treeToDoublyList(Node* root) {
        if(!root)   return root;
        Node *prehead = new Node(); //头节点
        pre = prehead;      
        zhongxu(root);      //中序遍历
        Node *p = prehead->right;   //查找尾节点
        while(p ->right)    p = p->right;
        p->right = prehead->right;
        prehead->right->left = p;
        delete(prehead);
        
        return p->right;
    }
};

注意的点

  1. 一开始要判空
  2. 头节点统一过程
  3. 最后要删除

写在最后

看起来今天比较难,但是如果考研的话这部分经常考到就还好。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XingleiGao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值