题目:回文链表
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
答案:
1.用快慢指针向后遍历,同时翻转链表的前半部分,然后与链表后半部分进行比较
快指针走到最后时,慢指针走到中间节点,边走边翻转链表前半部分。
class Solution {
public boolean isPalindrome(ListNode head) {
if(head == null || head.next == null) return true;
ListNode p = null, pre = null;
ListNode fast = head, slow = head;
while(fast != null && fast.next != null) {
p = slow;
slow = slow.next; //快慢遍历
fast = fast.next.next;
p.next = pre; //翻转
pre = p;
}
if(fast != null) { //奇数个节点时跳过中间节点
slow = slow.next;
}
while(p != null) {
if(p.val != slow.val) return false;
p = p.next;
slow = slow.next;
}
return true;
}
}
2.栈
首先遍历链表求出链表长度len,将链表前半部分入栈,然后出栈与链表后半部分进行比较。
class Solution {
public boolean isPalindrome(ListNode head) {
ListNode pHead = head;
Stack<Integer> stack = new Stack<>();
int len = 0;
while(pHead != null) { //计算链表长度
len++;
pHead = pHead.next;
}
pHead = head;
for(int i = 0; i < len/2; i++){ //链表前半部分入栈
stack.push(pHead.val);
pHead = pHead.next;
}
//前半部分和后半部分比较
if(len % 2 == 0){ //偶数个节点
for(int i = len/2; i < len; i++) {
if(stack.pop() != pHead.val)
return false;
pHead = pHead.next;
}
} else { //奇数个节点
pHead = pHead.next;
for(int i = len/2 + 1; i < len; i++) {
if(stack.pop() != pHead.val)
return false;
pHead = pHead.next;
}
}
return true;
}
}
来源:CSDN
作者:qq_34623223
链接:https://blog.csdn.net/qq_34623223/article/details/104542463