給定一個(gè)鏈表豪治,刪除鏈表中倒數(shù)第n個(gè)節(jié)點(diǎn),返回鏈表的頭節(jié)點(diǎn)扯罐。
樣例
給出鏈表1->2->3->4->5->null和 n = 2.
刪除倒數(shù)第二個(gè)節(jié)點(diǎn)之后负拟,這個(gè)鏈表將變成1->2->3->5->null.
**166. 鏈表倒數(shù)第n個(gè)節(jié)點(diǎn) **也是這個(gè)思路。
雙指針
從后往前刪除第n個(gè)節(jié)點(diǎn)歹河,如果是數(shù)組掩浙,那么可以從后往前找到第n個(gè)然后刪除就行了,雙向指針也可這么做秸歧,雙向鏈表的話(huà)也可以從后往前厨姚,但是單向鏈表要注意的是只能從前向后遍歷,一旦越過(guò)這個(gè)節(jié)點(diǎn)寥茫,就找不到了(除非從頭再來(lái))遣蚀。
單向鏈表經(jīng)常使用假節(jié)點(diǎn)來(lái)指向頭節(jié)點(diǎn),可以降低變成的復(fù)雜度。
我們用兩個(gè)指針芭梯,分別記作del和head险耀,其中del->next=head
然后把head向后移動(dòng)n個(gè)位置,這個(gè)時(shí)候del和head之間相差n+1個(gè)位置玖喘,然后再把兩根指針同時(shí)向后移動(dòng)甩牺,直到head指向空指針,這個(gè)時(shí)候del剛好指向要?jiǎng)h除節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)(這是必要的累奈,del不能指向要?jiǎng)h除的節(jié)點(diǎn)贬派,因?yàn)殒湵淼膭h除是必須前一個(gè)節(jié)點(diǎn)的),這個(gè)時(shí)候刪除這個(gè)節(jié)點(diǎn)就行了澎媒。
有些細(xì)節(jié)需要注意搞乏,畫(huà)個(gè)圖就很清楚了:
這個(gè)我是刪除倒數(shù)第2個(gè),就是個(gè)意思戒努。
ListNode * removeNthFromEnd(ListNode * head, int n) {
ListNode *first=new ListNode(0); //定義一個(gè)新假節(jié)點(diǎn)
first->next=head; //這個(gè)節(jié)點(diǎn)指向鏈表頭
ListNode *del=first; //一個(gè)指針指向這個(gè)假節(jié)點(diǎn)
for(int i=0;i<n;i++)
{
head=head->next; //先把head向后移動(dòng)n個(gè)位置请敦,這樣del和head相差n個(gè)位置
}
while(head!=NULL) //然后兩根指針同時(shí)移動(dòng)到最后,這樣del的下一個(gè)節(jié)點(diǎn)就是要?jiǎng)h除的了
{
head=head->next;
del=del->next;
}
del->next=del->next->next; //刪除節(jié)點(diǎn)
return first->next;
// write your code here
}