首页 > 其他分享 >leetcode 23. 合并 K 个升序链表

leetcode 23. 合并 K 个升序链表

时间:2023-05-20 14:12:11浏览次数:51  
标签:head ListNode lists next 链表 aPtr 升序 return leetcode

题目链接:https://leetcode.cn/problems/merge-k-sorted-lists/

第一种写法,不断将未排序的链表插入到一个已经排序的链表中。
这样写的问题在于,当未排序的链表逐渐变的很大时,每插入一个新链表,都会来一次O(kn),总时间复杂度为O(k²n)
我们可以通过分治,快速的消灭未排序链表个数,这样可以达到O(kn logk)

非分治写法:

    ListNode* mergeKLists(vector<ListNode*>& lists) {
        if (lists.empty()) {
            return nullptr;
        }

        ListNode* head = nullptr;
        int i = 0;
        while (i < lists.size() && !lists[i]) { i++; }
        if (i >= lists.size()) { return nullptr; }

        head = lists[i++];
        for (; i < lists.size(); ++i) {
            ListNode* p = lists[i];
            ListNode* phead = head;
            while (p) {
                if (p->val <= head->val) {
                    ListNode* tmp = p->next;
                    p->next = head;
                    head = p;
                    phead = head;
                    p = tmp;
                    continue;
                }
                while (phead->next && p->val > phead->next->val) {
                    phead = phead->next;
                }
                ListNode* tmp = p->next;
                p->next = phead->next;
                phead->next = p;
                p = tmp;
            }
        }
        return head;
    }

分治写法:
注意这一句 return mergeTwoLists(merge(lists, l, mid), merge(lists, mid + 1, r));,有点绕

    ListNode* mergeTwoLists(ListNode *a, ListNode *b) {
        if ((!a) || (!b)) return a ? a : b;
        ListNode head, *tail = &head, *aPtr = a, *bPtr = b;
        while (aPtr && bPtr) {
            if (aPtr->val < bPtr->val) {
                tail->next = aPtr; 
                aPtr = aPtr->next;
            } else {
                tail->next = bPtr; 
                bPtr = bPtr->next;
            }
            tail = tail->next;
        }
        tail->next = (aPtr ? aPtr : bPtr);
        return head.next;
    }
    
    ListNode* merge(vector <ListNode*> &lists, int l, int r) {
        if (l == r) return lists[l];
        if (l > r) return nullptr;
        int mid = (l + r) >> 1;
        return mergeTwoLists(merge(lists, l, mid), merge(lists, mid + 1, r));
    }

    ListNode* mergeKLists(vector<ListNode*>& lists) {
        return merge(lists, 0, lists.size() - 1);
    }

标签:head,ListNode,lists,next,链表,aPtr,升序,return,leetcode
From: https://www.cnblogs.com/linukey/p/17417148.html

相关文章

  • #yyds干货盘点# LeetCode程序员面试金典:将有序数组转换为二叉搜索树
    题目:给你一个整数数组nums,其中元素已经按升序排列,请你将其转换为一棵高度平衡二叉搜索树。高度平衡二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过1」的二叉树。 示例1:输入:nums=[-10,-3,0,5,9]输出:[0,-3,9,-10,null,5]解释:[0,-10,5,null,-3,null,9]......
  • #yyds干货盘点# LeetCode程序员面试金典:最大间距
    1.简述:给定一个无序的数组 nums,返回数组在排序之后,相邻元素之间最大的差值。如果数组元素个数小于2,则返回0。您必须编写一个在「线性时间」内运行并使用「线性额外空间」的算法。 示例 1:输入:nums=[3,6,9,1]输出:3解释:排序后的数组是[1,3,6,9],其中相邻元素(3,6)......
  • LeetCode 105. 从前序与中序遍历序列构造二叉树
    题目链接:LeetCode105.从前序与中序遍历序列构造二叉树题意:给定两个整数数组 preorder和inorder ,其中 preorder是二叉树的先序遍历,inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。解题思路:模拟手动构建的过程,注意下标的变化。完整代码如下:/***Defini......
  • LeetCode 113. 路径总和 II
    题目链接:LeetCode113.路径总和II题意:给你二叉树的根节点root和一个整数目标和targetSum,找出所有从根节点到叶子节点路径总和等于给定目标和的路径。解题思路:与LeetCode112.路径总和相似,在遍历过程中,记录遍历过的每一个点即可。递归法递归代码:varres[][]intva......
  • LeetCode 513. 找树左下角的值
    题目链接:LeetCode513.找树左下角的值题意:给定一个二叉树的根节点root,请找出该二叉树的最底层最左边节点的值。解题思路:首先明确本题是要找最底层的最左边的节点,因此迭代法,可以采用层次遍历,res每次记录每一层的最左边的节点,当遍历结束时,res表示的就是最底层,最左边的节......
  • LeetCode/子数组的最小值之和
    给定一个整数数组arr,找到min(b)的总和,其中b的范围为arr的每个(连续)子数组。1.单调栈假如要遍历所有区间,哪怕可以直接获得最小值,时间复杂度也是O(n2)这里我们不逐个找对应区间,而是计算每个值对区间的贡献,可以将时间复杂度降到O(n)其实也就找遍历时当前值的左边界和右边界,在......
  • OD统一考试(B卷)寻找链表的中间结点
    华为OD机试【4大宝典】再次上新题!①Python解华为机试题:https://dream.blog.csdn.net/article/details/129221789②C++解华为机试题:https://dream.blog.csdn.net/article/details/129472919③Java解华为机试题:https://dream.blog.csdn.net/article/details/129652513④......
  • [LeetCode] 1079. Letter Tile Possibilities
    Youhave n  tiles,whereeachtilehasoneletter tiles[i] printedonit.Return thenumberofpossiblenon-emptysequencesofletters youcanmakeusingthelettersprintedonthose tiles.Example1:Input:tiles="AAB"Output:8Explanation:......
  • LeetCode/完成任务的最少工作时间段
    一个工作时间段可以连续工作sessiontime个小时给你任务列表task,task[i]表示第i项任务花费时间求完成全部工作所需最小时间段(可以按任意顺序完成任务)1.回溯法回溯时按任务下标推进,边界条件为任务下标等于任务长度同时要记录回溯几个状态,分别是当前任务下标、已用时间段、各......
  • 二刷Leetcode-Days06
    二叉树:/***迭代法实现中序前序后序遍历*@paramroot*@return*/publicList<Integer>preorderTraversalIterator(TreeNoderoot){List<Integer>result=newArrayList<>();if(root==null){ret......