前言:
Hello, 大家好,我是Felix。今天来道简单的算法,如果判断一个链表是回文链表。
关于算法面试的一些技巧
今天是在刷左神算法的时候,刷到了这道题,然后他给出了一些面试的技巧,我认为也是非常受用的。这里分享给大家。
算法考试分为笔试和面试:
- 笔试 --- **不要追求各种复杂度,做出来就行**
- 面试 --- **一定要保证低的空间复杂度**
如何实现这道算法
如果不考虑空间复杂度,最好的方法就是用栈,把所有的元素压到栈里,然后弹出一个,比较一个。
看下代码:
public static boolean isPalindrome(ListNode head) {
ListNode node = head;
Stack<ListNode> stack = new Stack<>();
while (head != null) {
stack.push(head);
head = head.next;
}
// 弹栈比较
while (!stack.isEmpty()) {
if (node.val != stack.pop().val) {
return false;
}
node = node.next;
}
return true;
}
虽然实现了,但是还有优化的空间,因为我们其实没必要把所有的node都压到栈里,其实只需要一半压入即可。但是找中点又需要遍历整个链表。这个时候一定要想到快慢指针。
慢指针一次走一步,快指针每次两步,快指针到头时候,慢指针就到了中点,当然,链表的奇偶数不同会稍微有点变化。看代码。
public static boolean isPalindrome(ListNode head) {
ListNode node = head;
Stack<ListNode> stack = new Stack<>();
ListNode slow = head;
ListNode fast = head;
// 这行代码好好体会,可以用奇偶尝试一下
while (fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
while (slow != null) {
stack.push(slow);
slow = slow.next;
}
while (!stack.isEmpty()) {
if (node.val != stack.pop().val) {
return false;
}
node = node.next;
}
return true;
}
好啦,今天的算法分享到这里啦!