给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。
示例 1:
输入:head = [1,2,2,1]
输出:true
示例 2:
输入:head = [1,2]
输出:false
1.将链表复制到数组中,然后利用下标和头尾两个指针来对比,看是否是回文。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
List<ListNode> array = new ArrayList<>();
ListNode currentNode = head;
while (currentNode != null) {//将链表元素复制到数组中
array.add(currentNode);
currentNode = currentNode.next;
}
int start = 0;//头指针
int end = array.size() - 1;//尾指针
while(start <= end){
if(array.get(start).val != array.get(end).val){//只要遇到值不相等的就说明不是回文
return false;
}
start++;
end--;
}
return true;
}
}
2.使用栈辅助空间。但是用栈还不如用数组。
class Solution {
public boolean isPalindrome(ListNode head) {
Deque<ListNode> stack = new LinkedList<>();
ListNode currentNode = head;
while (currentNode != null) {
stack.push(currentNode);
currentNode = currentNode.next;
}
while (head != null) {
if (head.val != stack.peek().val) {
return false;
}
stack.pop();
head = head.next;
}
return true;
}
}
3.向辅助空间o(1)进行优化。利用快慢指针找到链表的中间节点,将链表的后半部分反转(修改链表结构),然后将前半部分和后半部分进行比较。比较完成后我们应该将链表恢复原样。虽然不需要恢复也能通过测试用例,但是使用该函数的人通常不希望链表结构被更改。
class Solution {
public boolean isPalindrome(ListNode head) {
if (head == null) {
return true;
}
ListNode firstHalfEnd = middle(head);//中间节点,如果总数是奇数,中间的算前半部分
ListNode secondHalfStart = reverse(firstHalfEnd.next);//翻转后半部分链表
boolean flag = true;
while (secondHalfStart != null) {
if(secondHalfStart.val != head.val){
flag = false;
break;
}
head = head.next;
secondHalfStart = secondHalfStart.next;
}
//比较完后把链表重新翻转回原来的
firstHalfEnd.next = reverse(secondHalfStart);
return flag;
}
//利用快慢指针找到中间节点
public ListNode middle(ListNode node){
ListNode slow = node;
ListNode fast = node;
while (fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
//翻转链表
public ListNode reverse(ListNode node){
ListNode pre = null;
ListNode currentNode = node;
while (currentNode != null){
ListNode temp = currentNode.next;
currentNode.next = pre;
pre = currentNode;
currentNode = temp;
}
return pre;
}
}
题源:力扣