数据结构习题–回文链表
给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false
要求:
时间复杂度为O(n)
空间复杂度为O(1)
方法:反转后半链表
分析
因为要求使用O(1)空间复杂度,否则我们可以直接反转链表在一个一个比较,而因为不能开拓这种空间来存储链表,所以这里我们采取把原来的链表的后半部分反转,再与原来的链表的前半部分进行比较
- 先找到链表的中点
- 判断该链表奇偶,对慢指针进行处理
- 一一比较
代码
package LinkList;public class PalindromeList {/*** 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; }* }*/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 fast = head;ListNode slow = head;// 这里采用的是反转后半部分链表的方法,当然也可以反转前面链表,大概流程差不多// 快指针每次移动两格,慢指针每次一格,当快指针跑到结尾时,慢指针恰好在中间while (fast != null && fast.next != null){fast = fast.next.next;slow = slow.next;}// 原来的链表分为奇数和偶数情况// 当是奇数情况时,最中间那个元素不用判断回文,而慢指针指向最中间那个元素,所以单独往后移动一格慢指针// 比如:12345 结束循环时,快指针在5,慢指针在3,而我们其实只需要反转45就行// 对于偶数链表: 1234,结束循环时,快指针在(1234null)中的null,慢指针在3.我们需要反转34// 所以当快指针不为null时,说明链表是奇数,需要处理慢指针if (fast != null){slow = slow.next;}// 反转后面链表slow = reverse(slow);// 快指针重新指向头结点fast = head;// 逐一比较每个结点while (slow != null){if (fast.val != slow.val){return false;}fast = fast.next;slow = slow.next;}return true;}public ListNode reverse(ListNode head) {ListNode nextNode = null;ListNode preNode = null;while (head != null){nextNode = head.next;head.next = preNode;preNode = head;head = nextNode;}return preNode;}}
}