给你一个单链表的头节点 head
,请你判断该链表是否为回文链表。如果是,返回 true
;否则,返回 false
。
示例 1:
输入:head = [1,2,2,1] 输出:true
示例 2:
输入:head = [1,2] 输出:false
提示:
- 链表中节点数目在范围
[1, 105]
内 0 <= Node.val <= 9
进阶:你能否用 O(n)
时间复杂度和 O(1)
空间复杂度解决此题?
方法一:常规思路,将链表反转,将反转后的链表与原来的链表中的值想比较
class Solution {
public static boolean isPalindrome(ListNode head) {
ListNode newHead = copyList(head);
ListNode reverseNode = reverse(head);//反
//遍历节点
while(newHead != null){
if(newHead.val != reverseNode.val) return false;
newHead =newHead.next;
reverseNode = reverseNode.next;
}
return true;
}
//反转链表:从后往前递归
private static ListNode reverse(ListNode head){
if(head == null) return null;
//递归结束条件
if(head.next == null) return head;
ListNode last = reverse(head.next);
head.next.next = head;
head.next = null;
return last;
}
public static ListNode copyList(ListNode head) {
if (head == null) return null;
ListNode newHead = new ListNode(head.val); // 创建新链表的头节点
ListNode curr = head.next; // 用于遍历原始链表
ListNode newCurr = newHead; // 用于构建新链表
while (curr != null) {
newCurr.next = new ListNode(curr.val); // 复制当前节点并添加到新链表中
curr = curr.next; // 移动到原始链表的下一个节点
newCurr = newCurr.next; // 移动到新链表的下一个节点
}
return newHead; // 返回新链表的头节点
}
}
方法二:将值复制到数组中后用双指针法
class Solution {
public boolean isPalindrome(ListNode head) {
List<Integer> vals = new ArrayList<Integer>();
// 将链表的值复制到数组中
ListNode currentNode = head;
while (currentNode != null) {
vals.add(currentNode.val);
currentNode = currentNode.next;
}
// 使用双指针判断是否回文
int front = 0;
int back = vals.size() - 1;
while (front < back) {
if (!vals.get(front).equals(vals.get(back))) {
return false;
}
front++;
back--;
}
return true;
}
}
方法三:递归
class Solution {
private ListNode frontPointer;
private boolean recursivelyCheck(ListNode currentNode) {
if (currentNode != null) {
if (!recursivelyCheck(currentNode.next)) {
return false;
}
if (currentNode.val != frontPointer.val) {
return false;
}
frontPointer = frontPointer.next;
}
return true;
}
public boolean isPalindrome(ListNode head) {
frontPointer = head;
return recursivelyCheck(head);
}
}
方法四:快慢指针
class Solution {
public boolean isPalindrome(ListNode head) {
if (head == null) {
return true;
}
// 找到前半部分链表的尾节点并反转后半部分链表
ListNode firstHalfEnd = endOfFirstHalf(head);
ListNode secondHalfStart = reverseList(firstHalfEnd.next);
// 判断是否回文
ListNode p1 = head;
ListNode p2 = secondHalfStart;
boolean result = true;
while (result && p2 != null) {
if (p1.val != p2.val) {
result = false;
}
p1 = p1.next;
p2 = p2.next;
}
// 还原链表并返回结果
firstHalfEnd.next = reverseList(secondHalfStart);
return result;
}
private ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while (curr != null) {
ListNode nextTemp = curr.next;
curr.next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
private ListNode endOfFirstHalf(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while (fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
}
标签:head,ListNode,next,链表,234,return,null,Leetcode
From: https://blog.csdn.net/m0_74051652/article/details/141190107