LeetCode 234:回文链表
题目描述
给你一个单链表的头节点 head
,请你判断该链表是否为回文链表。如果是,返回 true
;否则,返回 false
示例 1:
输入:head = [1,2,2,1]
输出:true
示例 2:
输入:head = [1,2]
输出:false
解题思路
1.栈+双指针
大致思路:使用双指针定位中心元素并将链表前半部分入栈,挨个出栈并遍历后半部分做比较,如果不想等则为false;
class Solution {public boolean isPalindrome(ListNode head) {if (head == null || head.next == null) {return true;}// 使用快慢指针找到链表中点ListNode slow = head;ListNode fast = head;LinkedListStack<Integer> stack = new LinkedListStack<>();// 将前半部分入栈while (fast != null && fast.next != null) {stack.push(slow.val);slow = slow.next;fast = fast.next.next;}// 如果链表长度是奇数,跳过中间节点if (fast != null) {slow = slow.next;}// 比较后半部分和栈中元素while (slow != null) {if (stack.pop() != slow.val) {return false;}slow = slow.next;}return true;}
}public class LinkedListStack<T> {// 定义链表节点private static class Node<T> {T data;Node<T> next;Node(T data) {this.data = data;this.next = null;}}private Node<T> top; // 栈顶节点private int size; // 栈的大小public LinkedListStack() {top = null;size = 0;}// 入栈操作public void push(T item) {Node<T> newNode = new Node<>(item);newNode.next = top; // 新节点的next指向原来的栈顶top = newNode; // 更新栈顶为新节点size++;}// 出栈操作public T pop() {if (isEmpty()) {throw new IllegalStateException("Stack is empty");}T item = top.data; // 获取栈顶数据top = top.next; // 栈顶指向下一个节点size--;return item;}// 判断栈是否为空public boolean isEmpty() {return top == null;}
}
2.反转链表+双指针
class Solution {public boolean isPalindrome(ListNode head) {if (head == null || head.next == null) return true;// 1. 快慢指针找中点ListNode slow = head, fast = head;while (fast != null && fast.next != null) {slow = slow.next;fast = fast.next.next;}// 2. 反转后半部分ListNode reversedSecondHalf = reverse(slow);// 3. 比较前后两部分ListNode p1 = head, p2 = reversedSecondHalf;boolean isPalindrome = true;while (p2 != null) {if (p1.val != p2.val) {isPalindrome = false;break;}p1 = p1.next;p2 = p2.next;}return isPalindrome;}private ListNode reverse(ListNode head) {//prev指向反转后链表的最后一个 初始为null curr指向要反转的那个节点,从head开始ListNode prev = null, curr = head;while (curr != null) {//将反转的下一个节点先记录下来ListNode next = curr.next;//使用头插法curr.next = prev;//将当前反转的节点设置为反转后节点的最后一个prev = curr;//反转下一个节点curr = next;}return prev;}
}