美文网首页ARTS
ARTS 第2周(20190401~20190407)

ARTS 第2周(20190401~20190407)

作者: 柳年思水 | 来源:发表于2019-04-07 23:33 被阅读0次

    ARTS 是什么?

    1. Algorithm:Palindrome Linked List

    本次练习的题目是:234. Palindrome Linked List,这个题目很简单就是,判断一个链表是否是回文链表。

    这个问题的核心是确定中间节点,然后再一次对比两边的链表,看其是否满足条件。

    确定中间的节点,这里的思路就是快慢指针,遍历的时候一个指针每次挑一步,另一个每次跳两步,这样当快指针走完的时候,慢指针就在中间附件(要考虑到奇偶性,好的方法就是画图举例)。

    解法 1:用 list 存储

    有了上面的想法之后,另一个要考虑的问题就是,在第一次遍历的时候,如果把前半部分的数据或结点存储下来,而且需要坐下倒序,这样才能跟后半部分的结点比较,一开始的想法是使用一个 List 存储,其实现如下:

        /**
         * time: O(n), space: O(n), and use list
         *
         * @param head
         * @return
         */
        public static boolean isPalindrome1(ListNode head) {
            boolean ans = true;
            if (head == null) {
                return ans;
            }
            ListNode slowNode = head;
            ListNode quickNode = head;
            if (quickNode.next != null) {
                List<Integer> tmp = new ArrayList<Integer>();
                while (quickNode.next != null && quickNode.next.next != null) {
                    tmp.add(slowNode.val);
                    slowNode = slowNode.next;
                    quickNode = quickNode.next.next;
                }
                // even number
                if (quickNode.next != null) {
                    tmp.add(slowNode.val);
                }
                for (int i = tmp.size() - 1; i >= 0; i--) {
                    slowNode = slowNode.next;
                    if (tmp.get(i) != slowNode.val) {
                        ans = false;
                        break;
                    }
                }
            }
            return ans;
        }
    

    时间复杂度为 O(n)(这里并没有考虑 list 插入操作的复杂度),空间复杂度也是 O(n)

    解法 2:原来的链表做修改

    代码提交后,发现这个解法并不是很好的解法,性能排名比较靠后,就看了性能比较好的解法,它的做法是:直接在原来的链表上做修改,改变其指针指向,然后对比前后链表,这样的空间复杂度变为了 O(1)(缺点就是改变了原始链表),其实现如下:

        /**
         * time: O(n), space: O(1), and use ListNode
         * but do some change to original ListNode
         *
         * @param head
         * @return
         */
        public static boolean isPalindrome2(ListNode head) {
            boolean ans = true;
            if (head == null || head.next == null) {
                return ans;
            }
            ListNode slowNode = head;
            ListNode quickNode = head.next;
            ListNode tmpNode;
            ListNode preNode = null;
            while (quickNode.next != null && quickNode.next.next != null) {
                tmpNode = slowNode;
                slowNode = slowNode.next;
                quickNode = quickNode.next.next;
                tmpNode.next = preNode;
                preNode = tmpNode;
            }
            tmpNode = slowNode;
            slowNode = slowNode.next;
            tmpNode.next = preNode;
            // odd number
            if (quickNode.next != null) {
                slowNode = slowNode.next;
            }
            while (slowNode != null) {
                if (slowNode.val != tmpNode.val) {
                    ans = false;
                    break;
                }
                slowNode = slowNode.next;
                tmpNode = tmpNode.next;
            }
            return ans;
        }
    

    对比这两种解法,性能差异的地方主要是:

    1. 空间复杂度不一样;
    2. 解法 1 使用了 list,如果链表非常长,list 需要不断进行扩容和迁移数据的操作,如果考虑到链表的插入消耗,其时间复杂度可能为 O(n^2),性能不可控。

    2. Review

    花了两周时间,把《Streaming Systems》第一章的内容看完了,对应的输出如下:第一章 Streaming 101(本周的是 Data Processing Patterns 部分)。

    3. Tip

    极客时间课程的一个学习总结:《数据结构与算法之美》之数组与链表

    4. Share

    这篇文章还在整理,先拖两天,尽快补齐。

    相关文章

      网友评论

        本文标题:ARTS 第2周(20190401~20190407)

        本文链接:https://www.haomeiwen.com/subject/sfgdiqtx.html