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
%mod(long 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