判斷乙個鍊錶是否為回文序列

2022-09-22 06:00:09 字數 2865 閱讀 2052

給你乙個單鏈表的頭節點head,請你判斷該鍊錶是否為回文鍊錶。如果是,返回true;否則,返回false

示例 1:

輸入:head = [1,2,2,1]

輸出:true

示例 2:

輸入:head = [1,2]

輸出:false

高階:你能否用o(n)時間複雜度和o(1)空間複雜度解決此題?

這道題一看到,一般的想法就是使用棧來解決,棧的性質是先入後出,我們將所有的元素壓入棧中,從棧頂到棧底的元素順序和鍊錶的順序剛好相反,如果鍊錶為回文序列,那麼從棧頂元素開始到棧底和鍊錶從頭到尾的元素值是相同的

對上乙個方法的優化是僅僅將鍊錶的一半元素加入棧中,然後進行對比,可以節省一半的時間(使用雙指標來得到一般的元素)

高階解法就是不使用棧,直接將鍊錶的右邊元素反轉,然後直接和鍊錶左邊元素進行比較(因為此時左邊鍊錶和右邊鍊錶都指向中間節點,只需要依次進行比較就可以得到結果

解法:棧,棧+雙指標,鍊錶反轉

**:解法一:暴力解法

public boolean ispalindrome(listnode head) 

while(!stack.isempty() && head != null)else

}if(stack.isempty())else

}

解析:就是暴力解法,將鍊錶所有元素加入到棧中,然後從棧中彈出乙個乙個元素和鍊錶的值進行比較(只需要對棧的性質熟悉,很容易就可以做出來

解法一的優化:

public boolean ispalindrome(listnode head) 

// 使用雙指標找到中間節點

listnode cur = head;

listnode right = head;

while(cur.next != null && cur.next.next != null)

// 此時的right指向的是中間結點(如果長度是偶數對應的就是兩個中間節點的前乙個結點)

stackstack = new stack();

right = right.next;

while(right != null)

// 此時棧內存放的是鍊錶的右半邊結點,棧頂到棧底依次是鍊錶的尾部

while(!stack.isempty())

head = head.next;

}return true;

}

解析:相較暴力解法,這個方法的區別就是使用雙指標

高階:

public boolean ispalindrome(listnode head) 

// 使用雙指標找到中間節點

listnode cur = head;

listnode right = head;

while(cur.next != null && cur.next.next != null)

// 接下來將右邊的鍊錶反轉

cur = right.next;

// 這一步是為了後面進行比較

right.next = null;

listnode next = null;

while(cur != null)

// 此時的head和cur對應的分別為頭和尾,直接進行比較即可,right對應的是最後乙個結點

boolean flag = true;

cur = right;

next = head;

while(next != null && cur != null)

next = next.next;

cur = cur.next;

}// 需要將鍊錶恢復原狀,然後返回flag(題目如果沒要求也可以不恢復)

cur = right.next;

right.next = null;

while(cur != null)

return flag;

}

解析:這道題的思路首先建立兩個幾點,作為指標找到鍊錶的中間節點(快慢指標,乙個移動一格乙個移動兩個),當快指標移動到鍊錶的尾部的時候,慢指標剛好移動到鍊錶的中間位置,如果鍊錶長度為偶數,那麼慢指標的位置會是兩個中間節點的前乙個結點。找到了中間節點後,使用乙個while迴圈來將右邊的部分鍊錶反轉,想要實現反轉我們需要獲取當前結點以及當前節點的前乙個結點和後乙個結點,通過這些才能夠實現。(需要注意的是在迴圈之前,需要將中間節點的next設定為null,因為如果不設定為null,會導致後面進行比較時陷入無限迴圈)當後面的鍊錶被反轉後,此時左半部分和右半部分的鍊錶共同指向中間節點,我們此時的right存放著最右邊的結點(也可以說是右邊鍊錶的起點),此時我們從左右兩邊鍊錶的起點開始,依次進行比較,如果相同則比較下乙個元素,如果不同則將標誌設定為false,最後迴圈完成後,我們已經實現了對鍊錶的判斷,(但是這個時候的鍊錶結構是有問題的,如果需要我們可以將鍊錶恢復)

總結:對於回文序列的判斷,最簡單粗暴的就是使用棧,也可以使用陣列來實現,將頭和尾進行比較就可以,如果是字元穿或者數字的話,直接將其分割開來放在棧中或者陣列中就可以。

鍊錶 判斷乙個鍊錶是否為回文鍊錶

思路1 找到中間節點然後把後面的翻轉,需要斷開鍊錶 然後比較和頭節點開始的前段,最後要是後半段的游標可以走到最後說明是回文否則不是 思路2 整體翻轉比較 思路3 借助乙個棧存放前半段的元素,然後和後半段的比較 public boolean ispalindrome listnode head lis...

鍊錶 判斷乙個鍊錶是否為回文結構

題目 給定鍊錶的頭節點,判斷該鍊錶是否為會問結構 如果鍊錶的長度為n,時間複雜度達到o n 額外空間複雜度達到o 1 方法一 public class node public boolean ispalindromel node head while head null head head.next...

鍊錶 判斷乙個鍊錶是否為回文結構

方法1 利用棧 t o n s o n 將鍊錶壓入棧,利用棧的先進後出逆序出鍊錶對比原鍊錶各節點值 public static boolean ispalindome1 node head cur head while s.isempty return true 方法2 利用棧 t o n s o ...