LeetCode234 回文链表

26 阅读1分钟

leetcode.cn/problems/pa…

image.png

解法一:暴力法

将值复制到数组中,后用双指针法判断数组是否回文

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func isPalindrome(head *ListNode) bool {
    vals := make([]int, 0)
    for head != nil{
        vals = append(vals, head.Val)
        head = head.Next
    }
    for i := 0; i<len(vals)/2; i++{
        if vals[i] != vals[len(vals)-1-i]{
            return false
        }
    }
    return true
}

还有一种思路是,新开一个链表,记录整个原链表的反转结果,然后就比较这两个链表是否一样

解法二:找到链表中点,反转后半部分,比较和前半部分是否相同

关于链表中点的定义: image.png

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func isPalindrome(head *ListNode) bool {
    if head.Next == nil{
        return true
    }
    // 找到原链表中点,用快慢指针
    slow, fast := head, head
    for fast != nil && fast.Next != nil{
        fast = fast.Next.Next
        slow = slow.Next
    }
    if fast != nil{ // 奇数长度
        slow = slow.Next
    }
    leftHalf := head
    rightHalf := reverseList(slow) // 反转右半部分链表
    for rightHalf != nil{
        if leftHalf.Val != rightHalf.Val{
            return false
        }
        leftHalf = leftHalf.Next
        rightHalf = rightHalf.Next
    }
    return true
}

func reverseList(head *ListNode) *ListNode{
    if head == nil || head.Next == nil{
        return head
    } 
    last := reverseList(head.Next)
    head.Next.Next = head
    head.Next = nil
    return last
}