复杂链表的复制
题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
思路:
1、从头节点开始遍历,跟着->next方向建立所有的节点出来,同时用map<label, pisition>记录每个值在链表的什么位置(这里大胆假设每个节点的值都不一样,否则我也没招了,,)
2、此时有了链表雏形,接下来为每个节点链接random。也沿着老链表的->next遍历,根据每个节点->random的label锁定random节点的位置,为相应新节点建立random链接。
/*
struct RandomListNode {
int label;
struct RandomListNode *next, *random;
RandomListNode(int x) :
label(x), next(NULL), random(NULL) {
}
};
*/
class Solution {
public:
RandomListNode* Clone(RandomListNode* pHead)
{
if (pHead == nullptr)
return pHead;
// map<label, 位置>
map<int, int> imap;
int count = 0;
auto pin2 = pHead;
// 初始化
RandomListNode* head = new RandomListNode(pHead->label);
auto pin1 = head;
imap.insert(make_pair(pin2->label, count++));
while (pin2->next != nullptr){
// 插入点
auto temp = new RandomListNode(pin2->next->label);
pin1->next = temp;
pin1 = pin1->next;
pin2 = pin2->next;
// 记录值
imap.insert(make_pair(pin2->label, count++));
}
// 此时所有节点新建完成
pin1 = head;
pin2 = pHead;
while(pin2 != nullptr){
if (pin2->random != nullptr){
auto pin = head;
auto target = pin2->random->label;
auto n = imap.find(target)->second;
for (int i = n; i != 0; --i)
pin = pin->next;
// pin此时所指是pin2的random节点
pin1->random = pin;
}
pin1 = pin1->next;
pin2 = pin2->next;
}
return head;
}
};
二叉搜索树与双向链表
题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
//1. 深度遍历,按照从右边的子结点、该结点和左边的子结点依次加入栈中
// 这样就可以使得栈弹出的结点是从小到大这样的排列次序
//2. 从栈中依次弹出结点,该结点的左指针指向上一结点,右指针指向下一结点,
// 然后构成双向链表
void dfs(TreeNode* root,stack<TreeNode* > &s)
{
if(root->right!=NULL)
dfs(root->right,s);
s.push(root);
if(root->left!=NULL)
{
dfs(root->left,s);
}
}
TreeNode* Convert(TreeNode* pRootOfTree)
{
//检查是否为空
if(pRootOfTree==NULL)
return NULL;
stack<TreeNode* > s;
dfs(pRootOfTree,s);
//生成一个临时的头结点
TreeNode *head = new TreeNode(-1);
TreeNode *tmp = head;
//从栈中依次弹出结点,该结点的左指针指向上一结点,右指针指向下一结点
while(!s.empty())
{
TreeNode *t = s.top();
tmp->right = t;
t->left = tmp;
tmp = tmp->right;
s.pop();
}
//头结点向右移一个
head = head->right;
//头结点的做指针指向NULL
head->left = NULL;
return head;
}
};