一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情。
Given the head
of a singly linked list, return true
if it is a palindrome.
Example 1:
Input: head = [1,2,2,1]
Output: true
Example 2:
Input: head = [1,2]
Output: false
Constraints:
- The number of nodes in the list is in the range
[1, 105]
. 0 <= Node.val <= 9
Follow up: Could you do it in O(n)
time and O(1)
space?
package com.linkedlist;
import java.util.ArrayList;
import java.util.List;
/**
* @Author you guess
* @Date 2022/4/4 21:43
* @Version 1.0
* @Desc 判断是否是回文链表
*/
public class Leetcode_234_PalindromeLinkedList {
/**
* 方法1
* T = O(n),S = O(n)
* <p>
* Runtime: 17 ms, faster than 33.68% of Java online submissions for Palindrome Linked List.
* Memory Usage: 107.5 MB, less than 17.29% of Java online submissions for Palindrome Linked List.
*/
boolean isPalindromeSolution1(ListNode head) {
//无节点 或 只有 1个节点
if (head == null || head.next == null) {
return true;
}
//List<ListNode> list = new ArrayList<>();
List<Integer> list = new ArrayList<>();
while (head != null) {
list.add(head.val);
head = head.next;
}
int front = 0;
int back = list.size() - 1;
while (front < back) {
if (list.get(front) != list.get(back)) {
return false;
}
front++;
back--;
}
return true;
}
/**
* 方法2
* T = O(n),S = O(1)
* 先找到中间的节点,然后把后一半链表反转,再从头、从中间往后比较
*
* @param head
* @return
*/
boolean isPalindrome(ListNode head) {
ListNode front = head;
ListNode half = this.findHalfNode(head);//找到中间节点
ListNode reverseFront = this.reverseLinkedList(half); // 后半部分反转后的头指针
while (reverseFront != null) {//reverseFront是先成为null,所以此处不必再写"front != null && "
if (front.val == reverseFront.val) {
front = front.next;
reverseFront = reverseFront.next;
} else {
return false;
}
}
return true;//reverseFront==null时,说明遍历到了结尾,front与reverseFront的值都相等,则返回true
}
/**
* 寻找中间节点
* 1 2 3 3 2 1 返回第2个 3
* 1 2 3 2 1 返回第2个 2
* <p>
* 共2个节点时,返回第2个节点
* 共1个节点时,返回null,到下一步reverseLinkedList反转时,也是返回null
*
* @param head
* @return
*/
ListNode findHalfNode(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
//节点总数为偶数,比如1 2 3 3 2 1
if (fast == null) return slow;
//节点总数为奇数,比如1 2 3 2 1
else return slow.next;
}
/**
* 反转链表
* 3 2 1 -> 1 2 3
* Runtime: 6 ms, faster than 73.89% of Java online submissions for Palindrome Linked List.
* Memory Usage: 97.4 MB, less than 57.01% of Java online submissions for Palindrome Linked List.
*
* @param head
* @return
*/
ListNode reverseLinkedList(ListNode head) {
//无节点 或 只有 1个节点
if (head == null || head.next == null) {
return head;
}
ListNode pre = null;
ListNode nextTemp = null;
ListNode cur = head;
while (cur != null) {
nextTemp = cur.next;
cur.next = pre;
pre = cur;
cur = nextTemp;
}
return pre;
}
public static void main(String[] args) {
/* ListNode node12 = new ListNode(1, null);
ListNode node22 = new ListNode(2, node12);
ListNode node32 = new ListNode(3, node22);
ListNode node42 = new ListNode(4, node32);
ListNode node41 = new ListNode(4, node42);
ListNode node31 = new ListNode(3, node41);
ListNode node21 = new ListNode(2, node31);
ListNode node11 = new ListNode(1, node21);*/
ListNode node12 = new ListNode(1, null);
ListNode node22 = new ListNode(2, node12);
ListNode node32 = new ListNode(3, node22);
ListNode node41 = new ListNode(4, node32);
ListNode node31 = new ListNode(3, node41);
ListNode node21 = new ListNode(2, node31);
ListNode node11 = new ListNode(1, node21);
Leetcode_234_PalindromeLinkedList main = new Leetcode_234_PalindromeLinkedList();
System.out.println(main.isPalindrome(node11));
}
}
返回中间节点:
end