剑指 Offer II 027. 回文链表
题目描述
给定一个链表的 头节点 head
**,**请判断其是否为回文链表。
如果一个链表是回文,那么链表节点序列从前往后看和从后往前看是相同的。
示例 1:
输入: head = [1,2,3,3,2,1]
输出: true
示例 2:
输入: head = [1,2]
输出: false
提示:
- 链表 L 的长度范围为
[1, 105]
0 <= node.val <= 9
**进阶:**能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
思路解析
1.切分链表,把链表切分成两段
2.翻转后面的链表
3.对比链表结点,如果有有不一样的就返回false
代码实现
/**
* 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) {
if(head==null||head.next==null) return true;
// 找到链表重点,分成两段
ListNode pre = findMid(head);
// 拆分
ListNode sec = pre.next;
pre.next = null;
// 翻转链表
sec = reverseList(sec);
while(head!=null&&sec!=null) {
if(head.val!=sec.val) return false;
head = head.next;
sec = sec.next;
}
return true;
}
public ListNode findMid(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while(fast.next!=null&&fast.next.next!=null){
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
public ListNode reverseList(ListNode head) {
if(head==null||head.next==null) return head;
ListNode pre = null;
ListNode curr = head;
ListNode next = head.next;
while(curr!=null) {
curr.next = pre;
pre = curr;
curr = next;
if(next!=null) {
next = next.next;
}
}
return pre;
}
}
欢迎大佬们关注小弟的博客https://blog.csdn.net/qq_41522089