LeetCode 234. Palindrome Linked List

本文介绍四种链表回文检测方法:复制到数组+双指针、递归、后半反转及哈希方法,并提供JAVA与Python实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JAVA

① 复制到数组 + 双指针(4ms)【时间复杂度: O ( N ) O(N) O(N) 空间复杂度: O ( N ) O(N) O(N)

import java.util.ArrayList;
import java.util.List;

class Solution {
    public boolean isPalindrome(ListNode head) {
        List<Integer> ans = new ArrayList<Integer>();
        while (head != null) {
            ans.add(head.val);
            head = head.next;
        }
        int front = 0;
        int back = ans.size() - 1;
        while (front < back) {
            if (!ans.get(front).equals(ans.get(back)))
                return false;
            front++;
            back--;
        }
        return true;
    }
}

② 递归(2ms)【时间复杂度: O ( N ) O(N) O(N) 空间复杂度: O ( N ) O(N) O(N)

class Solution {
    private ListNode ans;

    public boolean check(ListNode head) {
        if (head != null) {
            if (!check(head.next)) {
                return false;
            }
            if (head.val != ans.val) {
                return false;
            }
            ans = ans.next;
        }
        return true;
    }

    public boolean isPalindrome(ListNode head) {
        ans = head;
        return check(head);
    }
}

③ 后半反转(1ms)【时间复杂度: O ( N ) O(N) O(N) 空间复杂度: O ( 1 ) O(1) O(1)

class Solution {
	// 反转链表
    public ListNode reverse(ListNode head) {
        ListNode ans = null;
        ListNode current = head;
        while (current != null) {
            ListNode tmp = current.next;
            current.next = ans;
            ans = current;
            current = tmp;
        }
        return ans;
    }

	// 找到中间的节点 (4 找 2 、5 找 3)
    public ListNode findhalf(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        while (fast.next != null && fast.next.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        return slow;
    }

    public boolean isPalindrome(ListNode head) {
        if (head == null)
            return true;

        ListNode half = findhalf(head);
        ListNode last = reverse(half.next);

		// 判断是否回文
        while (last != null) {			//注意是要用 last来判定
            if (head.val != last.val)
                return false;
            head = head.next;
            last = last.next;
        }
        return true;
    }
}

④ 哈希(1ms)【时间复杂度: O ( N ) O(N) O(N) 空间复杂度: O ( 1 ) O(1) O(1)

class Solution {
    public boolean isPalindrome(ListNode head) {
        long seed = (long) (1e9 + 7);
        long ans1 = 0, ans2 = 0, h = 1;
        while (head != null) {
            ans1 = (ans1 * seed + head.val);
            ans2 = (ans2 + head.val * h);
            h *= seed;
            head = head.next;
        }
        return ans1 == ans2;
    }
}

这次哈希要是用了 % m o d \%mod %modlong mod = (long) Math.pow(2, 31))会过不了,而且选的 s e e d seed seed 也比较迷,总而言之就是哈希较难掌握 (比较玄学)

Python

① 复制到数组 + 双指针(60ms)

class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        vals = []
        current_node = head
        while current_node is not None:
            vals.append(current_node.val)
            current_node = current_node.next
        return vals == vals[::-1]

② 递归(108ms)

class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        self.front_pointer = head

        def recursively_check(current_node=head):
            if current_node is not None:
                if not recursively_check(current_node.next):
                    return False
                if self.front_pointer.val != current_node.val:
                    return False
                self.front_pointer = self.front_pointer.next
            return True

        return recursively_check()

③ 后半反转(84ms)

class Solution:

    def isPalindrome(self, head: ListNode) -> bool:
        if head is None:
            return True

        # 找到前半部分链表的尾节点并反转后半部分链表
        first_half_end = self.end_of_first_half(head)
        second_half_start = self.reverse_list(first_half_end.next)

        # 判断是否回文
        result = True
        first_position = head
        second_position = second_half_start
        while result and second_position is not None:
            if first_position.val != second_position.val:
                result = False
            first_position = first_position.next
            second_position = second_position.next

        # 还原链表并返回结果
        first_half_end.next = self.reverse_list(second_half_start)
        return result    

    def end_of_first_half(self, head):
        fast = head
        slow = head
        while fast.next is not None and fast.next.next is not None:
            fast = fast.next.next
            slow = slow.next
        return slow

    def reverse_list(self, head):
        previous = None
        current = head
        while current is not None:
            next_node = current.next
            current.next = previous
            previous = current
            current = next_node
        return previous

④ 哈希(6124ms)😅

class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        hash1, hash2, seed, h = 0, 0, 1000000007, 1
        while head != None:
            hash1 = hash1*seed+head.val
            hash2 = hash2+head.val*h
            h *= seed
            head = head.next
        return hash1 == hash2

Python 似乎识别不出 1 e 9 + 7 1e9+7 1e9+7

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值