請判斷一個鏈表是否爲迴文鏈表。git
示例1:github
輸入: 1->2 輸出: false
示例2:golang
輸入: 1->2->2->1 輸出: true
進階:算法
你可否用 O(n) 時間複雜度和 O(1) 空間複雜度解決此題?數組
思路1數據結構
思路2app
// ListNode Definition for singly-linked list. type ListNode struct { Val int Next *ListNode } // 解法1 // 用數組存前面的一半節點的值 // 時間複雜度:O(N) // 空間複雜度:O(N) func isPalindrome(head *ListNode) bool { // 空鏈表,算迴文 if head == nil { return true } var data []int for cur := head; cur != nil; cur = cur.Next { data = append(data, cur.Val) } for i, j := 0, len(data)-1; i <= j; { if data[i] != data[j] { return false } i++ j-- } return true } // 解法2 // 找到鏈表中間節點,將前半部分轉置,再從中間向左右遍歷對比 // 時間複雜度:O(N) // 空間複雜度:O(1) func isPalindrome2(head *ListNode) bool { if head == nil || head.Next == nil { return true } isPalindrome := true //鏈表長度 length := 0 for cur := head; cur != nil; cur = cur.Next { length++ } //將前半部分反轉 step := length / 2 var prev *ListNode cur := head for i := 1; i <= step; i++ { cur.Next, prev, cur = prev, cur, cur.Next } mid := cur var left, right *ListNode = prev, nil if length%2 == 0 { //長度爲偶數 right = mid } else { right = mid.Next } //從中間向左右兩邊遍歷對比 for left != nil && right != nil { if left.Val != right.Val { //值不相等,不是迴文鏈表 isPalindrome = false break } left = left.Next right = right.Next } //將前半部分反轉的鏈表進行復原 cur = prev prev = mid for cur != nil { cur.Next, prev, cur = prev, cur, cur.Next } return isPalindrome }