判断链表是否回文(空间复杂度为O(1)):
用到的有:快慢指针,链表翻转
代码
:
public static boolean isPalindrome3(Node head) {
if (head == null || head.next == null) {
return true;
}
Node n1 = head;
Node n2 = head;
while (n2.next != null && n2.next.next != null) { // find mid node
n1 = n1.next; // n1 -> mid
n2 = n2.next.next; // n2 -> end
}
n2 = n1.next; // n2 -> right part first node
n1.next = null; // mid.next -> null
Node n3 = null;
while (n2 != null) { // right part convert
n3 = n2.next; // n3 -> save next node
n2.next = n1; // next of right node convert
n1 = n2; // n1 move
n2 = n3; // n2 move
}
n3 = n1; // n3 -> save last node
n2 = head;// n2 -> left first node
boolean res = true;
while (n1 != null && n2 != null) { // check palindrome
if (n1.value != n2.value) {
res = false;
break;
}
n1 = n1.next; // left to mid
n2 = n2.next; // right to mid
}
n1 = n3.next;
n3.next = null;
while (n1 != null) { // recover list
n2 = n1.next;
n1.next = n3;
n3 = n1
;
n1 = n2;
}
return res;
}
标注
:
-
n1,n2的赋值(此处两个都指向head)影响着遍历完之后,指向中间位置的指针,具体指向中间位置的左边,右边,还是正中间?(根据具体需要选择值)
while循环,是拿快指针去判断,保证跑的快的都没事,那慢的肯定也没事
Node n1 = head; Node n2 = head; while (n2.next != null && n2.next.next != null) { // find mid node n1 = n1.next; // n1 -> mid n2 = n2.next.next; // n2 -> end }
-
翻转链表的时候,搞清当前节点、父节点,仔细点就行
最后判断完回文,最好把链表还原,做成黑箱
n2 = n1.next; // n2 -> right part first node n1.next = null; // mid.next -> null Node n3 = null; while (n2 != null) { // right part convert n3 = n2.next; // n3 -> save next node n2.next = n1; // next of right node convert n1 = n2; // n1 move n2 = n3; // n2 move }
-
笔试时候,把完成功能放在第一位,注重时间复杂度,借助下数据结构,解决问题就好。
面试时候,注重空间复杂度(一般会比借助数据结构的复杂),呈现分析问题的能力及coding能力
对应的,在练习的时候,也比对学习。
-
冲!