プログラミング練習:チェーンテーブル練習問題(上)
14130 ワード
(1)タイトル:2つのチェーンテーブルを入力し、最初の共通ノードを見つけます.
考え方:1)チェーンテーブル1の長さを算出する;2)チェーンテーブル2の長さを算出する.3)チェーンテーブル1とチェーンテーブル2の長さ差difを算出する.4)長鎖表はdifステップを先に進み,2つの鎖表が2つの鎖表のノードが初めて等しくなるまで2つの鎖表が一緒に歩くと,ポインタ位置が求められる.
コード実装:
(2)タイトル:チェーンテーブルで重複するノードを削除する
コード実装:
(3)タイトル:sort-list:Sort a linked list in O(n log n)time using constant space complexity.
考え方:(1)速慢指針法チェーンテーブルを中間からl 1,l 2の2つの部分(2)左右の2つの部分のチェーンテーブルをそれぞれ再帰的に並べ替える(3)2つのサブチェーンテーブルを統合する
コード実装:
(4)タイトル:Given a singly linked list L:L 0→L 1→...→L n-1→L n,reorder it to:L 0→L n→L 1→L n-1→L 2→L n-2→…You must dothis in-place without altering the nodes’values.For example, Given{1,2,3,4}, reorder it to{1,4,2,3}.
考え方:(1)速慢指針法で中間ノードを見つける(2)チェーンテーブルの後半を逆順にする(3)前半と逆順後の後半を合併する
コード実装:
(5)タイトル:Given a linked list and a value x,partition it such that all nodes than x come before nodes greater than or equal to x.You should preserve the original relative order of the nodes in each of the two partions.For example, Given1->4->3->2->5->2and x = 3, return1->2->2->4->3->5..
構想:(1)新しい2つのノードはそれぞれfastとslowで、それぞれ2つのヘッドノードを指します;(2)x値未満のノードはp 1に接続され、x値以上のノードはp 2にリンクされる.(3)最後に2つのチェーンテーブルを接続する.
コード実装:
考え方:1)チェーンテーブル1の長さを算出する;2)チェーンテーブル2の長さを算出する.3)チェーンテーブル1とチェーンテーブル2の長さ差difを算出する.4)長鎖表はdifステップを先に進み,2つの鎖表が2つの鎖表のノードが初めて等しくなるまで2つの鎖表が一緒に歩くと,ポインタ位置が求められる.
コード実装:
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
ListNode *p1=pHead1;
ListNode *p2=pHead2;
int len1=0,len2=0,dif=0;
while(p1!=NULL){
p1=p1->next;
len1++;
}
while(p2!=NULL){
p2=p2->next;
len2++;
}
if(len1>len2){
dif=len1-len2;
p1=pHead1;
p2=pHead2;
}
else{
dif=len2-len1;
p1=pHead2;
p2=pHead1;
}
for(int i=0;inext;
}
while(p1!=NULL && p2!=NULL){
if(p1==p2)
break;
p1=p1->next;
p2=p2->next;
}
return p1;
}
};
(2)タイトル:チェーンテーブルで重複するノードを削除する
コード実装:
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if (pHead==NULL)
return NULL;
if (pHead!=NULL && pHead->next==NULL)
return pHead;
ListNode* current;
if ( pHead->next->val==pHead->val){
current=pHead->next->next;
while (current != NULL && current->val==pHead->val)
current=current->next;
return deleteDuplication(current);
}
else {
current=pHead->next;
pHead->next=deleteDuplication(current);
return pHead;
}
}
};
(3)タイトル:sort-list:Sort a linked list in O(n log n)time using constant space complexity.
考え方:(1)速慢指針法チェーンテーブルを中間からl 1,l 2の2つの部分(2)左右の2つの部分のチェーンテーブルをそれぞれ再帰的に並べ替える(3)2つのサブチェーンテーブルを統合する
コード実装:
class Solution {
public:
ListNode *sortList(ListNode *head) {
if(head == NULL || head->next == NULL)
return head;
ListNode* p = head;
ListNode* q = head->next;
while(q && q->next)
{
p = p->next;
q = q->next->next;
}
ListNode* l1 = sortList(p->next);
p->next = NULL;
ListNode* l2 = sortList(head);
return Merge(l1,l2);
}
ListNode* Merge(ListNode* l1,ListNode* l2)
{
ListNode L(0);
ListNode* p = &L;
while(l1&&l2)
{
if(l1->val < l2->val)
{
p->next = l1;
l1=l1->next;
}
else
{
p->next = l2;
l2=l2->next;
}
p = p -> next;
}
if(l1 != NULL)
p->next = l1;
if(l2 != NULL)
p->next = l2;
return L.next;
}
};
(4)タイトル:Given a singly linked list L:L 0→L 1→...→L n-1→L n,reorder it to:L 0→L n→L 1→L n-1→L 2→L n-2→…You must dothis in-place without altering the nodes’values.For example, Given{1,2,3,4}, reorder it to{1,4,2,3}.
考え方:(1)速慢指針法で中間ノードを見つける(2)チェーンテーブルの後半を逆順にする(3)前半と逆順後の後半を合併する
コード実装:
class Solution {
public:
void reorderList(ListNode *head) {
if(head == NULL || head->next == NULL || head->next->next == NULL)
return;
//
ListNode* fast = head;
ListNode* low = head;
while(fast->next != NULL && fast->next->next != NULL)
{
fast = fast->next->next;
low = low->next;
}
// low
fast = low->next;
low->next = NULL;
while(fast != NULL){
ListNode* temp = fast->next;
fast->next = low->next;
low->next = fast;
fast = temp;
}
// low
ListNode* p = head;
ListNode* q = low->next;
while(p != NULL && q != NULL){
low->next = q->next;
q->next = p->next;
p->next = q;
p = q->next;
q = low->next;
}
}
};
(5)タイトル:Given a linked list and a value x,partition it such that all nodes than x come before nodes greater than or equal to x.You should preserve the original relative order of the nodes in each of the two partions.For example, Given1->4->3->2->5->2and x = 3, return1->2->2->4->3->5..
構想:(1)新しい2つのノードはそれぞれfastとslowで、それぞれ2つのヘッドノードを指します;(2)x値未満のノードはp 1に接続され、x値以上のノードはp 2にリンクされる.(3)最後に2つのチェーンテーブルを接続する.
コード実装:
class Solution {
public:
ListNode *partition(ListNode *head, int x) {
if(head == NULL)
return NULL;
ListNode* fast = new ListNode(0);
ListNode* slow = new ListNode(0);
ListNode* p1 = slow;
ListNode* p2 = fast;
ListNode *p = head;
while(p!=NULL)
{
if(p->val < x)
{
p1->next = p;
p1 = p1->next;
}
else
{
p2->next = p;
p2 = p2->next;
}
p = p->next;
}
p2->next = NULL;
p1->next = fast->next;
return slow->next;
}
};