题目
给你一个单链表的头节点 head
,请你判断该链表是否为回文链表。如果是,返回 true
;否则,返回 false
。
我的思路
先求链表的长度,设置一个栈,把链表的前半部分放进栈中,指针指向后半部分,依次弹出栈比较val值,如果相同则为回文链表。不过要注意链表长度为奇数还是偶数,并分开讨论。
/**
* 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) {
Deque<ListNode> stack=new LinkedList<ListNode>();
ListNode point=head;
ListNode res;
int len=0;
while(point!=null)
{
point=point.next;
len++;
}
if(len%2==0)
{
for(int i=0;i<len/2;i++)
{
stack.push(head);
head=head.next;
}
res=head;
for(int j=0;j<len/2;j++)
{
if(stack.peek().val==res.val)
{
res=res.next;
stack.pop();
}
else
{
return false;
}
}
return true;
}
else
{
for(int i=0;i<len/2;i++)
{
stack.push(head);
head=head.next;
}
res=head.next;
for(int j=0;j<len/2;j++)
{
if(stack.peek().val==res.val)
{
res=res.next;
stack.pop();
}
else
{
return false;
}
}
return true;
}
}
}
题解
一共为两个步骤:
复制链表值到数组列表中。
使用双指针法判断是否为回文。
第一步,我们需要遍历链表将值复制到数组列表中。我们用 currentNode 指向当前节点。每次迭代向数组添加 currentNode.val,并更新 currentNode = currentNode.next,当 currentNode = null 时停止循环。
执行第二步的最佳方法取决于你使用的语言。在 Python 中,很容易构造一个列表的反向副本,也很容易比较两个列表。而在其他语言中,就没有那么简单。因此最好使用双指针法来检查是否为回文。我们在起点放置一个指针,在结尾放置一个指针,每一次迭代判断两个指针指向的元素是否相同,若不同,返回 false;相同则将两个指针向内移动,并继续判断,直到两个指针相遇。
在编码的过程中,注意我们比较的是节点值的大小,而不是节点本身。正确的比较方式是:node_1.val == node_2.val,而 node_1 == node_2 是错误的。
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;
}
}