複雜鏈表的複製
題目描述
輸入一個複雜鏈表(每個節點中有節點值,以及兩個指針,一個指向下一個節點,另一個特殊指針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;
}
};