zoukankan      html  css  js  c++  java
  • 148. Sort List

    题目:

    Sort a linked list in O(n log n) time using constant space complexity.

    链接: http://leetcode.com/problems/sort-list/

    题解:

    Sort List, 链表排序,一看到O(nlogn)就想到使用merge sort。 对于merge sort,还要研究一下bottom-up和top-down的区别,优劣点,如何继续优化等等,比如n较小时使用insertion sort, 了解Python的Tim-sort之类。也要研究一下链表的Quicksort,以及3-way Quicksort。 当时电面Amazon的时候写排序作死选择Quicksort,还尝试写了一个3-way Quicksort,由于理解不深同时当天也头昏脑胀没解释清楚,被面试官白大姐秒拒,如此浪费一年机会,甚是可惜。对于各种排序的stalability也要好好复习。熟能生巧,多练吧。另外,external sorting,B tree,A* tree,indexing,paging之类的也要复习。聊远了...

    这题使用Merge Sort的话,还是按照Divide-and-Conquer分治。 两个辅助方法是findMid找中点,以及merge合并。 merge的话完全可以使用"Merge Sorted List"的代码,找中点我们也使用过,所以可以直接写。

    Time Complexity - O(nlogn), Space Complexity - O(logn)。

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public ListNode sortList(ListNode head) {
            if(head == null || head.next == null)
                return head;
            ListNode mid = findMid(head);
            ListNode right = sortList(mid.next);
            mid.next = null;
            ListNode left = sortList(head);
            
            
            return merge(left, right);
        }
        
        private ListNode findMid(ListNode head) {        
            if(head == null || head.next == null)
                return head;
            ListNode fast = head, slow = head;
            
            while(fast.next != null && fast.next.next != null) {
                fast = fast.next.next;
                slow = slow.next;
            }
            
            return slow;
        }
        
        private ListNode merge(ListNode left, ListNode right) {
            ListNode dummy = new ListNode(-1);
            ListNode node = dummy;
            
            while(left != null && right != null) {
                if(left.val < right.val) {
                    node.next = left;
                    left = left.next;
                } else {
                    node.next = right;
                    right = right.next;
                }
                node = node.next;
            }
            
            if(left != null)
                node.next = left;
            else
                node.next = right;
                
            return dummy.next;
        }
    }

    到这里其实还没结束。仔细看题目要求constant space complexity。这样的话我们就不能使用递归了。

    二刷:

    O(1) space并不好写,此刷没有完成,也并没有尝试quicksort,很忧伤... 最后还是使用的merge sort recrusive的方法。 代码大都参考了Discuss区里zwangbo同学的。

    Java:

    Time Complexity - O(nlogn), Space Complexity - O(logn)。

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public ListNode sortList(ListNode head) {
            if (head == null || head.next == null) return head; 
            ListNode fast = head, slow = head, preMid = head;
            while (fast != null && fast.next != null) {
                preMid = slow;
                fast = fast.next.next;
                slow = slow.next;
            }
            preMid.next = null;
            return merge(sortList(head), sortList(slow));
        }
        
        private ListNode merge(ListNode l1, ListNode l2) {
            if (l1 == null) return l2;
            if (l2 == null) return l1;
            if (l1.val < l2.val) {
                l1.next = merge(l1.next, l2);
                return l1;
            } else {
                l2.next = merge(l1, l2.next);
                return l2;
            }
        }
    }

    三刷:

    依然是使用之前的方法,找中点,再递归进行mergesort。

    Java:

    Time Complexity - O(nlogn), Space Complexity - O(logn)。

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public ListNode sortList(ListNode head) {
            if (head == null || head.next == null) return head;
            ListNode fast = head, slow = head, prev = head;
            
            while (fast != null && fast.next != null) {
                prev = slow;
                fast = fast.next.next;
                slow = slow.next;
            }
            prev.next = null;
            return mergeTwoSortedList(sortList(head), sortList(slow));
        }
        
        private ListNode mergeTwoSortedList(ListNode l1, ListNode l2) {
            if (l1 == null) return l2;
            if (l2 == null) return l1;
            ListNode dummy = new ListNode(-1);
            ListNode curNode = dummy, p1 = l1, p2 = l2;
            
            while (p1 != null && p2 != null) {
                if (p1.val < p2.val) {
                    curNode.next = p1;
                    p1 = p1.next;
                } else {
                    curNode.next = p2;
                    p2 = p2.next;
                }
                curNode = curNode.next;
            }
            curNode.next = (p1 != null) ? p1 : p2;
            return dummy.next;
        } 
        
    }

    Reference:

    http://www.mathcs.emory.edu/~cheung/Courses/171/Syllabus/7-Sort/merge-sort5.html

    https://en.wikipedia.org/wiki/Merge_sort#Bottom-up_implementation

    https://leetcode.com/discuss/10264/my-o-n-log-n-time-o-1-space-solution

    https://leetcode.com/discuss/12014/my-iterative-merge-sort

    https://leetcode.com/discuss/15420/java-solution-with-strict-o-1-auxiliary-space-complexity

    https://leetcode.com/discuss/18210/i-think-my-java-solution-is-o-1-space

    https://leetcode.com/discuss/19119/java-merge-sort-solution-with-o-1-memory

    https://leetcode.com/discuss/24917/my-java-code-with-constant-space

    https://leetcode.com/discuss/28594/bottom-recurring-with-space-complextity-time-complextity

    https://leetcode.com/discuss/39867/java-solution-bottom-iterative-merge-with-detailed-comments

    https://leetcode.com/discuss/1709/have-pretty-mergesort-method-anyone-speed-reduce-memory-usage

    https://leetcode.com/discuss/92701/java-solution-using-merge-sort

    https://leetcode.com/discuss/44369/java-merge-sort-solution

    https://leetcode.com/discuss/29921/basically-seems-merge-sort-problem-really-easy-understand

    https://leetcode.com/discuss/81455/java-quick-sort-fast-beats-98%25-also-includes-merge-sort-code

    https://leetcode.com/discuss/81263/super-easy-understand-java-iterative-merge-sort-using-space

  • 相关阅读:
    访问 http://localhost:8081对 flink 集群和任务进行监控管理
    Flink之流处理WordCount
    Flink之批处理WordCount
    为什么说JAVA中runnable接口的run方法运行在子线程?
    Java中的字符输入输出流练习
    在JAVA中实现文件读写练习
    JAVA自定义异常使用方法
    三种二叉树遍历的非递归算法
    C编译错误:Main.c:4:5: error: variably modified ‘f’ at file scope int f[maxn];
    中序+先序构造二叉树,后序遍历
  • 原文地址:https://www.cnblogs.com/yrbbest/p/4489582.html
Copyright © 2011-2022 走看看