1.从尾到头打印链表
题目描述:输入一个链表的头结点,从尾到头返回每个节点的值(用数组返回)。
示例1:
输入:head = [1,3,2]
输出:[2,3,1]
解题:创建一个空数组,对于链表的每个节点,回溯的将节点加入数组。
代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
vector<int> result;
vector<int> reversePrint(ListNode* head) {
if(head != null)
{
if(head->next != null)
{
reversePrint(head->next);
}
result.push_back(head->val);
}
return result;
}
2.复杂链表的复制
题目描述:
请实现 copyRandomList
函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next
指针指向下一个节点,还有一个 random
指针指向链表中的任意节点或者 null
。
示例1:
输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
示例2:
输入:head = [[3,null],[3,0],[3,null]
输出:[[3,null],[3,0],[3,null]
解题:和普通链表复制不同的是,复杂链表复制时,random指针指向的节点可能还未创建。因此用回溯的方法将复制与拷贝相互独立。
具体做法:使用哈希表记录当前节点的创建情况。遍历该链表的过程中,我们检查当前节点的后继节点和当前节点的随机指针指向的节点的创建情况。如果没有创建,那么递归的进行创建。回溯到当前层时,即可完成对当前节点指针的赋值。同时为了防止重复拷贝,还要检查当前节点是否已被拷贝过,如果已被拷贝过,那么可以直接取出节点。
代码:
/*
// 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:
unordered_map<Node*, Node*> cachedNode;
Node* copyRandomList(Node* head) {
if (head == nullptr) {
return nullptr;
}
if (!cachedNode.count(head)) {
Node* headNew = new Node(head->val);
cachedNode[head] = headNew;
headNew->next = copyRandomList(head->next);
headNew->random = copyRandomList(head->random);
}
return cachedNode[head];
}
};
简单记录ing……