[LeetCode] #234 回文链表
给你一个单链表的头节点 head
,请你判断该链表是否为回文链表。如果是,返回 true
;否则,返回 false
。
输入:head = [1,2,2,1]
输出:true
回文相关题目:
对于回文题目,通常使用反转法和双指针法
双指针法对于没有序号的链表需要先转换为有序号的数组
class Solution { public boolean isPalindrome(ListNode head) { List<Integer> list = new ArrayList<Integer>(); ListNode p1 = head; while (p1 != null) { list.add(p1.val); p1 = p1.next; } int left = 0; int right = list.size() - 1; while (left < right) { if (!list.get(left).equals(list.get(right))) return false; left++; right--; } return true; } }
反转法,需要反转链表 为了不使用额外的空间可以只反转后半部分
为此需要找到前半部分链表的尾节点、反转后半部分链表、判断是否回文、恢复链表、返回结果
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; } }
递归,使用辅助指针保留头节点。递归到尾节点,不断返回,不断往中间比较
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); } }
知识点:无
总结:无