☘前言☘
开更五月集训专题,由浅入深,深入浅出,飞向大厂!
🧑🏻作者简介:一个从工业设计改行学嵌入式的年轻人
✨联系方式:2201891280(QQ)
⏳全文大约阅读时间: 20min
全文目录
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;
}
};
注意的点
- 一定要删除节点,否则会内存泄漏。
- 一般来说会判断next或prev指针是否非空,非空才走,否则不走。这样会少很多来来回回的操作。慎记
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;
}
};
注意的点
- 最后记得还原第一个指针
- 记得要delete不要的内存
剑指 Offer II 028. 展平多级双向链表
解题思路
和上面那一题一样。不写了。
剑指 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;
}
};
注意的点
- 一开始要判空
- 头节点统一过程
- 最后要删除
写在最后
看起来今天比较难,但是如果考研的话这部分经常考到就还好。