• leetcode刷题笔记一百四十八题 排序列表


    leetcode刷题笔记一百四十八题 排序列表

    源地址:148. 排序链表

    问题描述:

    在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。

    示例 1:

    输入: 4->2->1->3
    输出: 1->2->3->4
    示例 2:

    输入: -1->5->3->4->0
    输出: -1->0->3->4->5

    //最初的想法与很多人一致,使用快慢指针分割进行归并排序
    //但是由于使用了递归,时间复杂度为O(nlogn), 空间复杂度为O(logn)
    /**
     * Definition for singly-linked list.
     * class ListNode(var _x: Int = 0) {
     *   var next: ListNode = null
     *   var x: Int = _x
     * }
     */
    object Solution {
        def sortList(head: ListNode): ListNode = {
            if (head == null || head.next == null) return head
            var slow = head
            var fast = head.next
    
            while (fast != null && fast.next != null){
                fast = fast.next.next
                slow = slow.next
            }
    
            var mid = slow.next
            var start = head
            slow.next = null
    
            var left = sortList(head) 
            var right = sortList(mid)
    
            var h = ListNode(0)
            val res = h
            while (left != null && right != null){
                if (left.x < right.x){
                    h.next = left
                    left = left.next
                }
                else{
                    h.next = right
                    right = right.next
                }
                h = h.next
            }
            if (left != null) h.next = left
            else h.next = right
            return res.next
        }
    }
    
    //若要实现空间复杂度O(1),需要将递归改为迭代处理,使用intv标记当前当前作用范围,逐渐扩大,直至与链表长度一致
    import util.control.Breaks._ 
    object Solution {
        def sortList(head: ListNode): ListNode = {
            var h = head
            var length = 0
            var intv = 1
    
            //测量链表长度
            while (h != null){
                h = h.next
                length += 1
            }
    
            //构建辅助头结点
            val res = ListNode(0)
            res.next = head
    
            while (intv < length){
                breakable{
                    var pre = res
                    var cur = res.next
                    //基于intv 对链表进行归并
                //breakable{
                    while (cur != null){
                        //intln("yes")
                        var cur1 = cur
                        var i = intv
                        while (i > 0 && cur != null){
                            i -= 1
                            cur = cur.next
                        }
                        //第一段intv未满,第二段为空
                        if (i > 0) break()
                        
                        var cur2 = cur
                        i = intv
                        while (i > 0 && cur != null){
                            cur = cur.next
                            i -= 1
                        }
                        
                        var length1 = intv
                        var length2 = intv - i
                        while (length1 > 0 && length2 > 0){
                            if (cur1.x < cur2.x){
                                pre.next = cur1
                                cur1 = cur1.next
                                length1 -= 1
                            }
                            else{
                                pre.next = cur2
                                cur2 = cur2.next
                                length2 -= 1 
                            }
                            pre = pre.next
                        }
                        if (length1 > 0){
                            pre.next = cur1
                        }
                        else{
                            pre.next = cur2
                        }
                        //更新pre指针,连接同层链表
                        while (length1 > 0){
                            pre = pre.next
                            length1 -= 1 
                        }                    
                        while (length2 > 0){
                            pre = pre.next
                            length2 -= 1
                        }                    
                        pre.next = cur
                    }
                    
                } 
                intv *= 2
            }
            return res.next 
        }
    }
    
  • 相关阅读:
    linux学习之路第八天(linux文件权限详解)
    linux学习之路第八天(组管理和权限管理)
    python 多线程示例
    python scapy 网卡发包
    python scapy 网卡抓包
    python 返回数组的索引
    MPLS 网络中的 MTU
    mysql 导入导出sql文件
    linux 修改MTU值
    ovs 源mac, 目的src 互换
  • 原文地址:https://www.cnblogs.com/ganshuoos/p/13582996.html
Copyright © 2020-2023  润新知