回文链表
难度:
标签:
题目描述
Implement a function to check if a linked list is a palindrome.
Example 1:
Input: 1->2 Output: false
Example 2:
Input: 1->2->2->1 Output: true
Follow up:
Could you do it in O(n) time and O(1) space?
代码结果
运行时间: 92 ms, 内存: 24.7 MB
/*
* 问题描述:
* 给定一个链表,判断它是否是回文。
*
* 思路:
* 1. 将链表的值存储在一个List中。
* 2. 使用Stream流的方式反转List并检查是否与原List相同。
*/
import java.util.*;
import java.util.stream.*;
class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
public class Solution {
public boolean isPalindrome(ListNode head) {
List<Integer> list = new ArrayList<>();
// 将链表的值存储在List中
while (head != null) {
list.add(head.val);
head = head.next;
}
// 使用Stream流的方式反转List并检查是否与原List相同
List<Integer> reversedList = list.stream()
.collect(Collectors.collectingAndThen(Collectors.toList(), l -> {
Collections.reverse(l);
return l;
}));
return list.equals(reversedList);
}
}
解释
方法:
此题解采用了快慢指针方法来寻找链表的中点,然后反转链表的后半部分,并与前半部分进行比较以判断是否为回文链表。首先,使用两个指针f(快指针)和s(慢指针),快指针每次移动两步,慢指针每次移动一步,当快指针到达链表末端时,慢指针正好位于链表中间。如果链表长度为奇数,快指针会多出一步,此时需要将慢指针再向前移动一步,以确保后半部分较短。然后,反转从慢指针开始的链表的后半部分。最后,将原链表的头部和反转后的后半部分逐节点比较,若全部节点相等,则链表是回文的。反之,则不是回文链表。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
在算法中,为什么选择快慢指针法来找到链表的中点,而不是通过其他方法,例如遍历一次链表记录长度后再定位中点?
▷🦆
快指针移动两步,慢指针移动一步的策略是否适用于所有长度的链表,包括极端情况如只有一个或两个节点的链表?
▷🦆
在链表长度为奇数时,为何要将慢指针额外向前移动一步?这一步骤对算法的正确性有何影响?
▷🦆
反转链表的后半部分时,是否有可能导致原链表结构被破坏,从而影响到链表的其他操作或数据安全?
▷