每天一道leetcode234-迴文鏈表
- 2019 年 10 月 4 日
- 筆記
題目
leetcode234-迴文鏈表中文鏈接: https://leetcode-cn.com/problems/palindrome-linked-list/ 英文鏈表: https://leetcode.com/problems/palindrome-linked-list/ 難度:easy 分類:鏈表
題目詳述
請判斷一個鏈表是否為迴文鏈表。
示例 1:
輸入: 1->2 輸出: false 示例 2:
輸入: 1->2->2->1 輸出: true
題目詳解
距離AC只差一個測試用例的錯誤思路
- 之前應該有看過關於迴文鏈表的一種解法,就是對於鏈表的每個元素依次乘以1,2,3,4…求得一個和sum1;
- 然後就是把這個鏈表反轉,反轉鏈表正好昨天做過哈,每天一道leetcode206-反轉鏈表,直接把程式碼拿來用,得到反轉後的鏈表;
- 然後對於這個反轉後的鏈表,依次遍歷然後對於每個元素依次乘以1,2,3,4…求得一個和sum2;
- 然後比較這個兩個sum值,如果相等,那麼就是迴文鏈表
程式碼
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public boolean isPalindrome(ListNode head) { int sum1 = 0; if(head == null || head.next == null) return true; int count = 1; ListNode temp = head; while(temp != null) { sum1 += count * temp.val; count += 1; temp = temp.next; } int sum2 = 0; count = 1; head = reverseList(head); temp = head; while(temp != null) { sum2 += count * temp.val; count += 1; temp = temp.next; } if(sum1 == sum2) return true; return false; } public ListNode reverseList(ListNode head) { if(head == null || head.next == null) return head; ListNode pre = head; ListNode pNode = head.next; ListNode next = head; //首先處理前兩個節點; pre.next = null; while(pNode != null) { next = pNode.next; pNode.next = pre; pre = pNode; pNode = next; } return pre; } }
結果,差一個用例沒過,說明這種方法還是有點問題~~~~

正確的思路
- 由於題目說了時間複雜度是O(n),空間複雜度是O(1),所以不能使用新的空間;
- 思路還是反轉鏈表,不過不是反轉整個鏈表,反轉的是後半部分的鏈表;
- 後半部分的鏈表反轉完畢,然後一個從頭開始遍歷,一個從尾巴開始遍歷,依次比較節點的值是不是一樣,一樣就繼續往下,不一樣直接就返回false.
程式碼
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public boolean isPalindrome(ListNode head) { if(head == null || head.next == null) return true; int length = 0; ListNode temp = head; while(temp != null) { length++; temp = temp.next; } int halfLength = length / 2; temp = head; for(int i=0;i<halfLength;i++) temp = temp.next; ListNode pre = temp; ListNode pNode = temp.next; ListNode next = pNode; while(pNode != null) { next = pNode.next; pNode.next = pre; pre = pNode; pNode = next; } for(int i=0;i<halfLength;i++) { if(head.val != pre.val) return false; head = head.next; pre = pre.next; } return true; } }
程式碼講解
- 15到20行,遍歷鏈表,求鏈表長度的一半的值
- 22-23行,找到鏈表的中間節點
- 24-33行反轉鏈表
- 34-40行一個從頭,一個從尾巴,依次比較值是否相等,不相等就返回false
- 最後就是返回true