Topic : Give you the head node of a singly linked list, please judge whether the linked list is a palindrome linked list. If so, return true; otherwise, return false.

link : Leetcode - Primary Algorithm - Linked List - Palindrome Linked List .

Example 1:

在这里插入图片描述
Input: head = [1,2,2,1]
output: true

Example 2:

在这里插入图片描述
Input: head = [1,2]
output: false

tags : stack, recursion, linked list, double pointer

ideas :

  • Loop through the linked list, the fast pointer walks two nodes at a time, and the slow pointer walks one node at a time. When the fast pointer finishes traversing the linked list, the position where the slow pointer stops is the center point. (Because the fast pointer starts from the second node, there is no need to consider the parity situation)
  • When the center point is found, the node traversed by the slow pointer is truncated from the head to the center point, which is the first part of the linked list to be compared.
  • The reverse order is performed on all nodes from the center point to the end of the linked list. As the second part of the linked list to be compared.
  • Compares each node of two linked lists for equality, and if they are equal, it is a palindrome.

The main Go code of is as follows:

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func isPalindrome(head *ListNode) bool {
    if head == nil || head.Next == nil {
        return true
    }
    fast := head.Next // 快指针,从第二个开始,可以解决奇偶问题
    slow := head      // 慢指针
    
    // 因为快指针从第二个节点开始走,所以不需要考虑奇偶的情况。
    for fast != nil && fast.Next != nil {
        fast = fast.Next.Next // 快指针每次走两个节点
        slow = slow.Next      // 慢指针每次走一个节点
    }
    // 当快指针遍历完链表,慢指针停下的位置就是中心点
    cur := slow.Next // 保留后面还没有遍历的链表
    slow.Next = nil  // 将整个列表进行截断,保存为第一个链表

    p := reverseLink(cur) // 将后面的链表倒序

    // 比较两个链表
    for p != nil && head != nil {
        if p.Val != head.Val {
            return false
        }
        p = p.Next
        head = head.Next
    }
    return true
}

// reverseLink 将链表倒序
func reverseLink(listHead *ListNode) *ListNode {
    if listHead == nil && listHead.Next == nil {
        return listHead
    }

    p := listHead     // 遍历链表的指针
    var rst *ListNode // 保存最后结果链表的指针
    var q *ListNode   // 保存下一个节点的临时指针

    for p != nil {
        q = p.Next
        p.Next = rst
        rst = p
        p = q
    }
    return rst
}

submitted screenshot :
在这里插入图片描述

official answer:
After reading the official answer, I suddenly realized that the official method is too simple. It uses the double pointer method after copying the value into the array.
Steps: 1. Copy the linked list value to the array list. 2. Use the double pointer method to judge whether it is a palindrome.

func isPalindrome(head *ListNode) bool {
    vals := []int{}
    for ; head != nil; head = head.Next {
        vals = append(vals, head.Val)
    }
    n := len(vals)
    for i, v := range vals[:n/2] {
        if v != vals[n-1-i] {
            return false
        }
    }
    return true
}

土豆
17 声望5 粉丝