算法题练习3-判定链表是否是回文串
判定链表是否是回文串
判定链表是否是回文串
题目
对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。
思路
1. 处理边界情况:如果链表为空(A == null)或只有一个节点(A.next == null),那么它天然满足回文结构,直接返回 true。
2. 快慢指针找中点:使用两个指针 slow 和 fast,其中 fast 每次走两步、slow 每次走一步,当 fast 走到末尾时,slow 正好指向链表的中间节点。
3. 反转后半部分链表:从 slow 所在位置开始,使用三指针法(当前节点 cur、前驱节点 pre、临时保存下一个节点 curNext)将链表的后半部分进行原地反转。
4. 比较前后两段是否相同:定义两个指针 left(从头节点 A 开始)和 right(从反转后的后半段头节点 pre 开始),依次比较对应节点的值是否相等。
5. 返回最终结果:如果所有对应节点的值都相等,则说明链表是回文结构,返回 `true`;如果中途发现有不相等的节点,则立即返回 false。
代码
public class PalindromeList {public boolean chkPalindrome(ListNode A) {if (A == null || A.next == null) {return true;}ListNode slow = A, fast = A;while (fast != null && fast.next != null) {slow = slow.next;fast = fast.next.next;}ListNode cur = slow,pre = null;while(cur != null) {ListNode curNext = cur.next;cur.next = pre;pre = cur;cur = curNext;}ListNode left = A,right = pre;while(right != null ) {if(left.val != right.val) return false;left = left.next;right = right.next;}return true;}
}
时间复杂度分析
-
快慢指针找中点(O(n)):
-
使用快慢指针
slow
和fast
,其中fast
每次移动两步,slow
每次移动一步。 -
当
fast
遍历到链表末尾时,slow
刚好到达链表的中间位置。 -
这个过程需要遍历整个链表一次,时间复杂度为 O(n)。
-
-
反转后半部分链表(O(n)):
-
从
slow
开始,反转链表的后半部分。 -
每个节点只被访问一次,因此时间复杂度为 O(n)。
-
-
比较前后两部分(O(n)):
-
将链表前半部分和反转后的后半部分逐个节点进行比较。
-
最多遍历一半的链表长度,因此时间复杂度为 O(n)。
-
总体时间复杂度
-
所有步骤的时间复杂度都是 O(n),因此总体时间复杂度为 O(n)。
空间复杂度分析
-
额外空间使用:
-
快慢指针、反转链表以及比较过程中使用的变量都是常数级别的额外空间。
-
没有使用任何额外的数据结构(如栈、数组等),也没有递归调用。
-
空间复杂度
-
因此,算法的空间复杂度为 O(1),即仅使用了常数级别的额外空间。
总结
分析项 | 复杂度 |
---|---|
时间复杂度 | O(n) |
空间复杂度 | O(1) |