チェーンテーブルがエコー構造であるかどうかを判断する(時間、空間の複雑さに要求がある)
3432 ワード
タイトル:チェーンテーブルについて、時間複雑度O(n)、余分な空間複雑度O(1)のアルゴリズムを設計し、それが回文構造であるかどうかを判断してください.
チェーンテーブルのヘッダポインタAを指定します.bool値を返します.これは、エコー構造であるかどうかを表します.チェーンテーブルの長さが900以下であることを保証します.
試験例:1->2->2->1
戻る:true
ポイント:1.返信構造を判断する方法
2. 時間、空間の複雑さを満たすアルゴリズムを設計する(難点)
知識点:1.高速ポインタを使用して中間ノードを見つけます.
2.チェーンテーブルを反転します.
構想1:空間O(n)全体のチェーンテーブルは両側を遍歴して、1つのスタックを開いて、第1回の遍歴はチェーンテーブルの中の各要素pushをスタックの中に入れて、このようにスタックの中の要素のpopの順序はチェーンテーブルの逆順序の出力です;2回目はpopスタックのデータを開始し、popごとに1つのデータをチェーンテーブルと比較し、同じように下に進むとfalseに戻ります.
この場合,時間的複雑度はO(n),空間的複雑度はO(n)である.
考え方2:空間O(1)
(1)クイックスローポインタ法を用いて,最初のステップにブロックポインタとスローポインタを設定し,クイックポインタは1回に2歩,スローポインタは1回に1歩(スロー)歩き,クイックポインタが次のステップにnullのときにスローポインタが半分歩いたことを説明し,中間ノードを見つけることができる.
(2)第2のステップで中間チェーンテーブルの後ろのポインタを反転し、
(3)第3部は,各要素が等しいか否かを比較し,等しい場合は回文数,そうでない場合は回文数である.(以下、易水さんはコード実装を示していますが、ここでは説明しません)
注意ここでは、要素の数が2の場合を含み、midとfastは2番目の要素を指します.
チェーンテーブルのヘッダポインタAを指定します.bool値を返します.これは、エコー構造であるかどうかを表します.チェーンテーブルの長さが900以下であることを保証します.
試験例:1->2->2->1
戻る:true
ポイント:1.返信構造を判断する方法
2. 時間、空間の複雑さを満たすアルゴリズムを設計する(難点)
知識点:1.高速ポインタを使用して中間ノードを見つけます.
2.チェーンテーブルを反転します.
構想1:空間O(n)全体のチェーンテーブルは両側を遍歴して、1つのスタックを開いて、第1回の遍歴はチェーンテーブルの中の各要素pushをスタックの中に入れて、このようにスタックの中の要素のpopの順序はチェーンテーブルの逆順序の出力です;2回目はpopスタックのデータを開始し、popごとに1つのデータをチェーンテーブルと比較し、同じように下に進むとfalseに戻ります.
この場合,時間的複雑度はO(n),空間的複雑度はO(n)である.
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
class PalindromeList {
public:
bool chkPalindrome(ListNode* A) {
if(A==NULL) return true;
ListNode* B;
stack s;
B=A;
while(B!=NULL)
{
s.push(B->val);
B=B->next;
}
while(A!=NULL && !s.empty())
{
if(A->val==s.top())
{
A=A->next;
s.pop();
}
else return false;
}
return true;
// write code here
}
};
考え方2:空間O(1)
(1)クイックスローポインタ法を用いて,最初のステップにブロックポインタとスローポインタを設定し,クイックポインタは1回に2歩,スローポインタは1回に1歩(スロー)歩き,クイックポインタが次のステップにnullのときにスローポインタが半分歩いたことを説明し,中間ノードを見つけることができる.
(2)第2のステップで中間チェーンテーブルの後ろのポインタを反転し、
(3)第3部は,各要素が等しいか否かを比較し,等しい場合は回文数,そうでない場合は回文数である.(以下、易水さんはコード実装を示していますが、ここでは説明しません)
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
class PalindromeList {
public:
bool chkPalindrome(ListNode* A) {
if(A==NULL) return true;
ListNode* mid;
ListNode* fast;
ListNode* temp;
mid=A;
fast=A;
while(fast->next!=NULL)
{
temp=mid; //temp mid
mid=mid->next;
fast=fast->next;
if(fast->next!=NULL)
fast=fast->next; // , ,mid , ,mid 。
}
if(mid==A) return true; // 1 , ;
ListNode* cur;
temp->next=NULL; //temp , temp
cur=mid->next;
mid->next=NULL;
while(cur!=NULL)
{
temp=cur->next; //mid,cur,temp 。
cur->next=mid;
mid=cur;
cur=temp;
}
while(A!=NULL && mid!=NULL)
{
if(A->val==mid->val)
{
A=A->next;
mid=mid->next;
}
else return false;
}
return true;
// write code here
}
};
注意ここでは、要素の数が2の場合を含み、midとfastは2番目の要素を指します.
while(fast->next!=NULL)
{
temp=mid; //temp mid
mid=mid->next;
fast=fast->next;
if(fast->next!=NULL)
fast=fast->next; // , ,mid , ,mid 。
}
は簡単には書けません.この場合、要素の個数が1と2の特殊な状況は無視されます.while(fast->next->next!=NULL)
{
mid=mid->next;
fast=fast->next->next;
}