學習數據結構的時候遇到一個經典的回文鏈表問題
- 對於一個鏈表,請設計一個時間復雜度為O(n),額外空間復雜度為O(1)的算法,判斷其是否為回文結構。
如果有鏈表反轉的基礎,實現鏈表回文判斷就簡單的多,如果對反轉鏈表不熟悉,可以參考這篇博客。
思路很簡單,先找到鏈表的中間Node,采用的快慢指針法。
- 慢指針一次走一步,快指針一次走兩步,當快指針觸底的時候,慢指針到達了重點,如果鏈表總數是偶數,則慢指針停在相對左邊的Node上。
- 找到中點后,對中點后面的鏈表進行反轉。
- 從頭尾開始向中間移步,每次比較是否相同。
/**
* @author axin
* @since 2019-09-29
*/
public class PalindromeList {
@Data
static class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
//第一步找到中點
//從中點開始將后續結點反轉
//兩遍開始next比較直到相遇
public static boolean isPalindrome(ListNode head) {
if(head==null||head.next==null) return true;
if(head.next.next==null){
return head.val == head.next.val;
}
ListNode one = head.next;
ListNode two = head.next.next;
while(two.next!=null&&two.next.next!=null){
one = one.next;
two = two.next.next;
}
//鏈表倒轉
ListNode pre = null;
ListNode temp = null;
while(one!=null){
temp = one.next;
one.next = pre;
pre=one;
one = temp;
}
ListNode tail = pre;
//頭尾比較
while(head!=null){
if(head.val!=tail.val) return false;
head = head.next;
tail = tail.next;
}
return true;
}
public static void main(String[] args) {
ListNode node7 = new ListNode(1);
ListNode node6 = new ListNode(2);
ListNode node5 = new ListNode(3);
ListNode node4 = new ListNode(4);
ListNode node3 = new ListNode(3);
ListNode node2 = new ListNode(2);
ListNode node1 = new ListNode(1);
node6.setNext(node7);
node5.setNext(node6);
node4.setNext(node5);
node3.setNext(node4);
node2.setNext(node3);
node1.setNext(node2);
System.out.println("===="+isPalindrome(node1));
}
}