題目:給定乙個單鏈表 l:l0→l1→…→l
n-1→ln ,
將其重新排列後變為: l0→l
n→l1→l
n-1→l2→l
n-2→…
你不能只是單純的改變節點內部的值,而是需要實際的進行節點交換。
示例 1:給定鍊錶 1->2->3->4, 重新排列為 1->4->2->3.
示例 2:給定鍊錶 1->2->3->4->5, 重新排列為 1->5->2->4->3.
思路1:將鍊錶的各個節點儲存在陣列中,由於陣列可以在任意位置訪問,所以只需要設定頭尾兩個指標進行遍歷即可。
c++實現如下:
/**
* definition for singly-linked list.
* struct listnode
* listnode(int x) : val(x), next(nullptr) {}
* listnode(int x, listnode *next) : val(x), next(next) {}
* };
*/class solution
vectornewlist;
while(head)
int i=0;
int j=newlist.size()-1;
while(inext=newlist[j];
i++;
if(i==j)
newlist[j]->next=newlist[i];
j--;
}newlist[i]->next=nullptr;
}};
思路2:
注意到目標鍊錶即為將原鍊錶的左半端和反轉後的右半端合併後的結果。
這樣我們的任務即可劃分為三步:
找到原鍊錶的中點(參考「876. 鍊錶的中間結點」)。
我們可以使用快慢指標來 o(n)o(n) 地找到鍊錶的中間節點。
將原鍊錶的右半端反轉(參考「206. 反轉鍊錶」)。
我們可以使用迭代法實現鍊錶的反轉。
將原鍊錶的兩端合併。
因為兩鍊錶長度相差不超過 11,因此直接合併即可。
c++實現如下:
/**
* definition for singly-linked list.
* struct listnode
* listnode(int x) : val(x), next(nullptr) {}
* listnode(int x, listnode *next) : val(x), next(next) {}
* };
*/class solution
listnode *fast=head;
listnode *slow=head;
//找到中間節點
while(fast->next)
else
slow=slow->next;
}//反轉中間節點之後的鍊錶
listnode *l2=reverlist(slow);
listnode *l1=head;
mergelist(l1, l2);
}listnode *reverlist(listnode *head)
listnode *cur=reverlist(head->next);
head->next->next=head;
head->next=null;
return cur;
}void mergelist(listnode* l1, listnode* l2)
}};
143 重排鍊錶
143.重排鍊錶 給定乙個單鏈表 l l0 l1 l n 1 ln 將其重新排列後變為 l0 l n l1 l n 1 l2 l n 2 你不能只是單純的改變節點內部的值,而是需要實際的進行節點交換。示例 1 給定鍊錶 1 2 3 4,重新排列為 1 4 2 3.示例 2 給定鍊錶 1 2 3 4 ...
143 重排鍊錶
題解 時間複雜度 o n 空間複雜度 o n definition for singly linked list.struct listnode listnode int x val x next nullptr listnode int x,listnode next val x next nex...
143 重排鍊錶
給定乙個單鏈表 l l0 l1 ln 1 ln 將其重新排列後變為 l0 ln l1 ln 1 l2 ln 2 你不能只是單純的改變節點內部的值,而是需要實際的進行節點交換。示例 1 給定鍊錶 1 2 3 4,重新排列為 1 4 2 3.暴力,使用stack逆序儲存後面要插入的數字 因為和遍歷的順序...