力扣学习笔记——234. 回文链表
解题思路
反转后半部分链表

实现代码
反转后半部分链表
class Solution {
public boolean isPalindrome(ListNode head) {
ListNode fast = head, slow = head;
// 遍历到链表中点后一位
while (fast != null && fast.next != null) { // 利用快慢指针的特性,当快指针遍历完后,慢指针刚好是链表中点后一位
fast = fast.next.next;
slow = slow.next;
}
if (fast != null) slow = slow.next; // fast != null 说明链表长度是奇数,此时slow在中点,需要往后移动一位
// 反转slow
slow = reverse(slow);
// 将快指针重置到head
fast = head;
// 对比fast和slow
while(slow != null) {
if (fast.val != slow.val) return false;
fast = fast.next;
slow = slow.next;
}
return true;
}
public ListNode reverse(ListNode head) {
Stack<ListNode> stack = new Stack<>();
while (head != null) {
stack.push(head);
head = head.next;
}
if (stack.isEmpty()) return null;
ListNode node = stack.pop();
ListNode dummy = node; // 作为反转后的头部
while (!stack.isEmpty()) {
ListNode temp = null;
temp = stack.pop();
node.next = temp;
node = node.next;
}
node.next = null; // 最后需要将 node.next 至空 不然会造成环
return dummy;
}
}
反转链表可以进一步优化:
让链表进行原地反转

public ListNode reverse(ListNode head) {
ListNode newHead = null;
while (head != null) {
// 保存下一个节点
ListNode temp = head.next;
// 让每次访问的链表头部作为新链表的头部
head.next = newHead;
// 更新新链表
newHead = head;
// 重新赋值,继续访问
head = temp;
}
return newHead;
}
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 zxb
评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果

