説明
リストは回文であるかどうかを判断するためにリストを作成します。
例1:
入力:1 - > 2
出力:偽
例2:
入力:1 - > 2 - > 2 - > 1
出力:真
高度:
あなたはこの問題を解決するためにO(n)の時間計算量とO(1)スペースの複雑さを使用することができますか?
解決
パリンドローム手段、例えば1-> 2-> 2-> 1回文鎖として; 1-> 2-> 3-> 2-> 1も。上記の時間と空間の複雑さを満たすために、我々はリストの下半期と比較して、チェーンの前半分を反転する必要があります。
ステップ:
1.中間ノードを見つけ。
2.ノードの前半分を回し、
ノードの後半と-3-オン比較。
最適化のポイント:
合成ステップ1、エッジフリップフロッ中間ノードを探しています。
コード
例:
1 2 3 4
遅い= 2速い= 3
遅い= 3速い= NULL事前= 2
1 2 3 4 5
遅い= 2速い= 3
予備= 2遅い= 3速い= 5
/ ** 片方向リンクについて*定義リスト。 *パブリッククラスListNode { * int型ヴァル; * ListNode次; * ListNode(int型X){X =ヴァル;} *} * / クラスのソリューション{ // 最適化の文言は、横断します同時に反転 パブリック ブールisPalindrome(ListNodeヘッド){ IF(ヘッド== NULL || head.next == nullが){ 返す trueに; } ListNode最終 = NULL ; ListNode予備 = ヘッド; ListNodeはSLOW =ヘッド。 ListNode速い = ヘッド。 一方、(!速い= ヌル!&& fast.next = NULL ){ プリ = 遅いです。 遅い = slow.next。 速い = fast.next.next。 pre.next = 最後。 最後 = 前; } ListNode rightStart。 もし(高速== NULL){ // 说明偶数节点 = rightStart 遅いです。 } 他{ rightStart= slow.next。 } ListNode leftStart = プレ。 ながら(!leftStart = nullを!&& rightStart = ヌル){ 場合(!leftStart.val = rightStart.val){ 返す 偽。 } leftStart = leftStart.next。 rightStart = rightStart.next。 } 場合(!leftStart = ヌル!|| rightStart = NULL ){ 戻り 偽。 } 戻り trueに; } //通常考え、ステップバイステップ
のパブリック ブールisPalindrome1(ListNodeヘッド){ IF(ヘッド== NULL || head.next == NULL ){ リターン trueに; } ListNode予備 = ヘッド; ListNode SLOW = ヘッド。 FAST ListNode = ヘッドと、 一方(!= FAST ヌル && fast.next!= NULL ){//中間ノードを見つける 事前 = SLOW、 SLOW = slow.next。 FAST = fast.next.next; } pre.next = NULL ; ListNode Rightstart; IF(FAST == NULL){ // ノードのDESCRIPTION偶数 Rightstart = SLOW; } そうでなければ{ Rightstart = slow.next; } ListNode leftStart = リザーバー(ヘッド); //リストの最初の半分を反転 しながら!(leftStart = nullを!&& Rightstart = ヌルの){// 1つの比較 IF(leftStart.val =!rightStart.val){ }返す 偽; } leftStart = leftStart.next。 rightStart = rightStart.next。 } 場合(!leftStart = ヌル!|| rightStart = NULL ){ 戻り 偽。 } を返す 真。 } //翻转链表 公共ListNodeのリザーバ(ListNodeヘッド){ 場合(ヘッド== NULL ){ 戻りヘッド。 ListNode前。 = nullを ListNode CUR = ヘッド。 次ListNode; 一方、(!CUR = NULL ){ 次 = cur.next。 cur.next = 前; 前 = CUR。 CUR = 次回。 } 戻りプレ。 } }