给你一个单链表的头节点 head
,请你判断该链表是否为回文链表。如果是,返回 true
;否则,返回 false
。
提示:
- 链表中节点数目在范围
[1, 10^5]
内 0 <= Node.val <= 9
示例:
解:链表转数组,遍历链表,将节点存到数组中,建立头尾指针(left和right)同时相向遍历,如果arr[left++] != arr[right--]则不是回文链表。
/**
* 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> arr = new ArrayList<>();
ListNode node = head;
while(node != null){
arr.add(node);
node = node.next;
}
int left = 0, right = arr.size() - 1;
while(left < right){
if (arr.get(left++).val != arr.get(right--).val){
return false;
}
}
return true;
}
}
解:快慢指针 + 链表反转,使用 slow 和 fast 指针,同时指向头节点,但步长分别为 1 和 2 ,最终,slow指针会指向链表后半部分的起始节点,(注意:递归条件为fast != null 且 fast.next != null,奇数长度的链表,slow指针最后需要再往前走一步),反转后半部分的链表。最后对比前后链表即可。
思路:数据结构和算法
/**
* 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) {
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
if (fast != null)
slow = slow.next;
fast = head;
// 链表反转
ListNode pre = null, cur = slow;
while (cur != null) {
ListNode tmp = cur.next;
cur.next = pre;
pre = cur;
cur = tmp;
}
slow = pre;
// 开始比对
while (slow != null) {
if (slow.val != fast.val)
return false;
slow = slow.next;
fast = fast.next;
}
return true;
}
}