鍊錶的指標域中,除了有指向下乙個節點的鍊錶以外,還有乙個指向隨機節點的指標。
struct listnode
;
常規做法,空間換時間。
先常規的將拷貝的節點用next串起來,遍歷一遍原始鍊錶,然後尾插法即可。
在尾插的同時,建立乙個由原始節點指標p到拷貝節點指標c的乙個map。
再次遍歷原始指標,如果指標p指向節點的random域不為null,那麼通過m[p]->random=m[p->random]
來達到賦值random的目的:
class solution
tail->next = nullptr;
p = phead;
while (nullptr != p)
p = p->next;
}return newhead->next;
}};
相當聰明的做法,看了書才能知道,就是把clone的節點接到原節點的後面
例如:
l1->l2->l3
變成 l1->l1』->l2->l2』->l3->l3』->null
然後有p->next->random=p->random->next
最後再把這個鍊錶拆成兩個鍊錶即可。
class solution
p = phead;
while (nullptr != p)
p = p->next->next;
}randomlistnode * newhead = new randomlistnode(0);//新鍊錶的頭結點
randomlistnode *k = newhead;
randomlistnode* o = phead;//這裡還需要保證原鍊錶的形狀
p = phead->next;
while (nullptr != p)
return newhead->next;
}};
將二叉搜尋樹轉成雙向鍊錶:
原先指向左子樹的指標調整為指向雙向鍊錶中前乙個節點的的指標pre,原先指向右子樹的指標調整為指向雙向鍊錶後乙個節點的指標next.
由於二叉搜尋樹中序遍歷的序列是有序的,而題目要求雙向鍊錶也是有序的,因此,我們以中序的方式進行遞迴。
這裡,我們還需要乙個輔助的指標,指向當前已經排好的雙向鍊錶的最後乙個節點。
所以,遞迴的順序是,先排左子樹,再排當前節點,再排右子樹。
排好以後,list指標需要往回溯,找到雙向鍊錶的頭結點。
class solution
public:
treenode* convert(treenode* prootoftree)
return
list;
}};
把字串分成兩部分,一部分是字串的第乙個字元,一部分是第乙個字元後面所有的字元,將第乙個字元分別與後面所有的字元交換:
比如abc,a與b、c分別交換,得到序列bac和cba。
對於子串行,再遞迴地完成該操作即可。
不過牛客上面有個兩個要求:
1.要求字串出現重複字元,即可能有aac這樣的序列
2.要求字串是字典序的。
對於第2個要求,我們很容易實現,只要將第乙個字元後面所有的字元sort一下即可,對於第1個要求,如果出現重複字元,則不執行swap操作,這裡需要維護乙個visit容器。
class solution
sort(str.begin() + start, str.end());//保證字典序
unordered_set
visit;//保證重複不交換
for (int i = start; i < str.size(); ++i)}}
public:
vector
permutation(string str)
};
詳細參考:leetcode169—majorityelements
class solution
else
}//下面**排除沒有多數派情況
count = 0;
for (int i = 0; iif (numbers[i] == candidates)
count++;
}if (count <= (numbers.size() ) / 2)
return
0; return candidates;
}};
借助容器了。
能想象到,最小的k個數和最大的k個數可以用堆這種結構來儲存。這裡我用乙個優先順序佇列。事實上紅黑樹也是可以的,用乙個set也是可以的。
class solution
vector
v;v.reserve(q.size());
while (!q.empty())
reverse(v.begin(), v.end());
return v;
}};
class solution
}vector
v;v.reserve(s.size());
for (auto it = s.begin(); it != s.end(); ++it)
return v;
}};
第二種思路是用partition函式來解決問題,可以想見,快排的思路是比基準小的在左邊,比基準pivot大的再右邊,先回顧一下快排和partition函式。
int partition(vector
&v, int p, int r)
}swap(v[r], v[i+1]);
return i +1;
}void quicksort(vector
&v, int p, int r)
}
如果基於陣列的第k個數字來調整,使得比第k個數字小的在陣列左邊,比第k個數字大的都在右邊,這樣左邊的k個數字就是k個最小數字。基於這種思路的**如下:
int partition(vector
&v, int p, int r)
}swap(v[r], v[i+1]);
return i +1;
}class solution
else
}//end while
vector
res(input.begin(), input.begin() + k);
return res;
}};
牛客劍指offer刷題記錄(七)
演算法導論上應該有這樣的課後題。歸併的思路,假設f i,j 表示陣列i到j的逆序對數,那麼有 f i,j f i k f k 1,j s i j,k 其中s i,j,k 表示逆序對 p q p i k q k 1,j 由於歸併排序,我麼得到兩個有序的子陣列l,r 那麼當出現逆序對 l i r j 時...
牛客網劍指offer刷題記錄(更新ing)
1.二維陣列的查詢 class solution else else 索引 1 index new index 3.從尾到頭列印鍊錶 struct listnode class solution while array tmp.size 0 return array result 4.重建二叉樹 d...
劍指 offer 刷題記錄
任誰都躲不過找工作的問題,好希望能多準備一些時間,奈何時間不等人,每天刷幾道題,並且記錄下來吧 def replacespace s write code here num space 0 new s for i in range len s if i num space 1 for i in ra...