迴文連結串列
阿新 • • 發佈:2020-10-23
1.問題描述
請判斷一個連結串列是否為迴文連結串列。
示例 1:
輸入: 1->2
輸出: false
示例 2:
輸入: 1->2->2->1
輸出: true
進階:
你能否用O(n) 時間複雜度和 O(1) 空間複雜度解決此題?
2.求解
儲存到陣列中使用雙指標判斷
- 遍歷整個連結串列把所有的值儲存到list集合中
- 設定指標i,j分別從頭部和尾部對比是否相同
程式碼如下
/* *執執行用時:4 ms, 在所有 Java 提交中擊敗了28.12% 的使用者 * 記憶體消耗:42.2 MB, 在所有 Java 提交中擊敗了40.65% 的使用者 * */ public boolean isPalindrome(ListNode head) { if (head == null) { return true; } List<Integer> list = new ArrayList<>(); while (head != null) { list.add(head.val); head = head.next; } int i = 0, j = list.size() - 1; while (i < j) { if (!list.get(i).equals(list.get(j))) { return false; } i++; j--; } return true; }
- 當然在這裡用list陣列只是一種方法,也可以使用棧這一結構來進行比較
遞迴
遞迴比較難以理解,可以先借助下面這個例子理解,如何使用遞迴倒序列印一個連結串列
程式碼如下
public class Solution { int i = 0; void printNode(ListNode head){ if(head == null){ return; } printNode(head.next); i++; System.out.println("我是倒數第" + i + "個節點,我的值是:" + head.val); } }
- 在這段程式碼中,我們把自增的i換成我們需要比較的節點就可以求出題目的答案
程式碼如下
/* * 執行用時:3 ms, 在所有 Java 提交中擊敗了33.88% 的使用者 * 記憶體消耗:44.5 MB, 在所有 Java 提交中擊敗了5.00% 的使用者 * */ ListNode temp; public boolean isPalindrome2(ListNode head) { temp = head; return check(head); } public boolean check(ListNode head) { if (head == null) { return true; } boolean ans = (check(head.next) && head.val == temp.val); temp = temp.next; return ans; }
- 在方法外面定義全域性變數temp,這個temp相當於我們上文中的i
- 遞的過程先拿到連結串列的最後一個節點,然後開始歸的過程,用最後一個節點與temp比較,用倒數第二個節點與
temp.next
比較,以此類推
反轉連結串列後半部分
在方法1和方法2中我們無論如何都做不到O(1)的空間複雜度,要想滿足O(1)的空間複雜度,我們可以使用反轉後半部分連結串列來對比的方法
程式碼如下
/*
* 執行用時:1 ms, 在所有 Java 提交中擊敗了99.86% 的使用者
* 記憶體消耗:40.9 MB, 在所有 Java 提交中擊敗了96.45% 的使用者
* */
public boolean isPalindrome3(ListNode head) {
ListNode fast = head, slow = head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
if (fast != null) {
slow = slow.next;
}
slow = reverse(slow);
while (slow != null) {
if (slow.val != head.val) {
return false;
}
slow = slow.next;
head = head.next;
}
return true;
}
ListNode reverse(ListNode head) {
ListNode pre = null;
ListNode curr = head;
while (curr != null) {
ListNode temp = curr.next;
curr.next = pre;
pre = curr;
curr = temp;
}
return pre;
}
ps:如何使用遞迴反轉連結串列
劍指 Offer-反轉連結串列的3種方式