判断回文链表

79 阅读1分钟

前言:

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;
    }

好啦,今天的算法分享到这里啦!