面试题 02.06. 回文链表

编写一个函数,检查输入的链表是否是回文的。

示例 1:

输入: 1->2 输出: false 示例 2:

输入: 1->2->2->1 输出: true

进阶: 你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/palindrome-linked-list-lcci 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解:
思路一:

代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 使用栈,加入前一半元素,再与后一半元素逐个对比
    // 时间复杂度 O(N) 遍历一遍链表元素
    // 空间复杂度 O(N) 使用了额外的栈存储控件
    public boolean isPalindrome1(ListNode head) {

        Stack<Integer> stack = new Stack<>();
        ListNode slow = head;
        ListNode fast = head;

        // 前一半入栈
        while (fast != null && fast.next != null){

            stack.push(slow.val);
            slow = slow.next;
            fast = fast.next.next;
        }

        // 说明节点总数是 单数
        if (fast != null) slow = slow.next;

        // 栈中元素和后一半元素对比
        // 不一致, return false
        // 全部一致, return true
        while (slow != null){
            if (stack.pop() != slow.val) return false;
            slow = slow.next;
        }

        return true;
    }
思路二:

代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
    // 前边相同,找到链表中间节点
    // 翻转中间节点
    // 依次比较头结点 和 中间节点
    // 有不一致的则 return false
    // 全部都一致,则 return true
    // 时间复杂度 : O(N) 遍历一整遍 链表
    // 空间复杂度 : O(1) 没有使用额外内存控件
    public boolean isPalindrome(ListNode head) {

        // 找到中间元素
        ListNode slow = head;
        ListNode fast = head;

        while (fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
        }

        // 说明节点总数是 单数
        if (fast != null) slow = slow.next;

        // 翻转slow
        ListNode newSlow = null;
        while (slow != null){
            ListNode tmp = slow.next;
            slow.next = newSlow;
            newSlow = slow;
            slow = tmp;
        }

        while (newSlow != null){

            if (head.val != newSlow.val) return false;

            head = head.next;
            newSlow = newSlow.next;
        }

        return true;
    }

第二种算法明显比前一种算法更优秀, 时间复杂度都是O(N) , 但是其空间复杂度优化至O(1). 在leetcode上提交代码后,也有所提现。

如图,分别是方法一,方法二执行用时以及内存消耗

屏幕快照 2020-05-14 下午5.50.12

屏幕快照 2020-05-14 下午5.43.39