精华内容
下载资源
问答
  • 合并 k 个已排序链表并将其作为一个已排序链表返回。分析并描述其复杂度。 [{1,2,3},{4,5,6,7}] {1,2,3,4,5,6,7} 解决方法一: 遍历链表数组,两两合并链表。其中合并两个有序链表也是一个算法题,点击此处...

    题目描述

    合并 k 个已排序的链表并将其作为一个已排序的链表返回。分析并描述其复杂度。

    [{1,2,3},{4,5,6,7}]

    {1,2,3,4,5,6,7}

    解决方法一

    遍历链表数组,两两合并链表。其中合并两个有序链表也是一个算法题,点击此处查看

    import java.util.*;
    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) {
     *         val = x;
     *         next = null;
     *     }
     * }
     */
    public class Solution {
        public ListNode mergeKLists(ArrayList<ListNode> lists) {
            if (lists.size() == 0) return null;
            if (lists.size() == 1) return lists.get(0);
            ListNode res = lists.get(0);
            for (int i = 1; i < lists.size(); i++) {
                res = mergeTwoLists(res, lists.get(i));
            }
            return res;
        }
        
        public ListNode mergeTwoLists(ListNode head1, ListNode head2) {
            if (head1 == null) return head2;
            if (head2 == null) return head1;
            
            if (head1.val < head2.val) {
                head1.next = mergeTwoLists(head1.next, head2);
                return head1;
            } else {
                head2.next = mergeTwoLists(head2.next, head1);
                return head2;
            }
        }
    }
    

    解决方法二

    使用优先队列,其本质也就是大小堆。以每个链表头节点大小为标准,小的优先放入队列。

    然后,由于cur是逐个节点遍历的,每次cur.next都被赋值为当前队列中队首元素最小的节点(也就是每次都会找到剩余链表中最小节点连接到cur后面)。于此同时,还需要将每一步寻找到最小节点的所在的链表的剩余节点,添加到队列中。

    在这里插入图片描述

    import java.util.*;
    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) {
     *         val = x;
     *         next = null;
     *     }
     * }
     */
    public class Solution {
        public ListNode mergeKLists(ArrayList<ListNode> lists) {
            if (lists == null || lists.size() == 0) return null;
            PriorityQueue<ListNode> queue = new PriorityQueue<ListNode>(lists.size(), new Comparator<ListNode>(){
                @Override
                public int compare(ListNode o1, ListNode o2) {
                    return o1.val < o2.val ? -1 : 1;
                }
            });
            
            for (ListNode node : lists) {
                if (node != null){
                    queue.add(node);
                }
            }
            
            ListNode res = new ListNode(-1);
            ListNode cur = res;
            
            while (! queue.isEmpty()) {
                cur.next = queue.poll();
                cur = cur.next;
                if (cur.next != null) {
                    queue.add(cur.next);
                }
            }
            return res.next;
        }
    }
    
    展开全文
  • } 归并排序,先递归划分,在两两合并 public ListNode mergeKLists(ArrayList<ListNode> lists) { if (lists.size() == 0) return null; return mergeSort(lists, 0, lists.size() - 1); } public ListNode ...

    牛客题目链接

    1. 题目考点

    1. 归并排序
    2. merge 函数三种形式
    3. PriorityQueue

    2. 考点解析

    1. 使用 ArrayList,排序再插入 (投机取巧,面试千万不可)
    public ListNode mergeKLists(ArrayList<ListNode> lists) {
        ArrayList<Integer> arr = new ArrayList<>();
        
        for (int i = 0 ; i < lists.size(); i++) {
            ListNode p = lists.get(i);
            while (p != null) {
                arr.add(p.val);
                p = p.next;
            }
        }
        
        arr.sort((a,b)-> a-b);
        
        ListNode dummy = new ListNode(0), r = dummy;
        for (int i = 0; i < arr.size(); i++) {
            ListNode node = new ListNode(arr.get(i));
            r.next = node;
            r = node;
        }
        r.next = null;
        
        return dummy.next;
        
    }
    
    1. 使用小顶堆 PriorityQueue,其实类似第一种方式 (面试可行)
    public ListNode mergeKLists(ArrayList<ListNode> lists) {
        if (lists == null || lists.size() == 0) return null;
        
        Queue<Integer> pq  = new PriorityQueue<>();
        for (ListNode node : lists) {
            while (node != null) {
                pq.offer(node.val);
                node = node.next;
            }
        }
        ListNode dummy = new ListNode(0);
        ListNode r = dummy;
        while (!pq.isEmpty()) {
            ListNode node = new ListNode(pq.poll());
            r.next = node;
            r = node;
        }
        return dummy.next;
    }
    
    1. 归并排序,先递归划分,在两两合并
    public ListNode mergeKLists(ArrayList<ListNode> lists) {
        if (lists.size() == 0) return null;
        return mergeSort(lists, 0, lists.size() - 1);
    }
    
    public ListNode mergeSort(ArrayList<ListNode> lists, int l, int r) {
        if (l == r) return lists.get(l);
        int mid = l + ((r - l) >> 2);
        ListNode l1 = mergeSort(lists, l, mid);
        ListNode l2 = mergeSort(lists, mid + 1, r);
        return merge(l1, l2);
    }
    // 合并方式有三种,此处采用第一种 while (true) 的方式
    public ListNode merge(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(0);
        ListNode r = dummy;
        while (true) {
            if (l1 == null) {
                r.next = l2;
                break;
            } else if (l2 == null) {
                r.next = l1;
                break;
            } else if (l1.val < l2.val) {
                r.next = l1;
                l1 = l1.next;
                r = r.next;
            } else {
                r.next = l2;
                l2 = l2.next;
                r = r.next;
            }
        }
        return dummy.next;
    }
    
    1. merge 函数采用一般方式
    public ListNode merge(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(0);
        ListNode r = dummy;
        while (l1 != null && l2 != null) {
            if (l1.val < l2.val) {
                r.next = l1;
                l1 = l1.next;
            } else {
                r.next = l2;
                l2 = l2.next;
            }
            r = r.next;
        }
        if (l1 !=  null) r.next = l1;
        if (l2 !=  null) r.next = l2;
        return dummy.next;
    }
    
    1. merge 函数采用递归方式(不容易想到,本质是修改链)
    public 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;
        }
    }
    
    展开全文
  • NC51_合并k个已排序链表 知识点:归并、最小堆 题目链接 题目描述 合并 k 个已排序链表并将其作为一个已排序链表返回。分析并描述其复杂度。 输入: [{1,2,3},{4,5,6,7}] 输出: {1,2,3,4,5,6,7} 解题思路 ...

    NC51_合并k个已排序的链表

    知识点:归并、最小堆
    题目链接

    题目描述

    合并 k 个已排序的链表并将其作为一个已排序的链表返回。分析并描述其复杂度。

    输入: [{1,2,3},{4,5,6,7}]
    输出: {1,2,3,4,5,6,7}

    解题思路

    1. 归并排序 注意返回值
    2. 最小堆,注意在合并的时候 需要把链表的下一个结点也放进去

    代码

    #include "cheader.h"
    struct ListNode {
        int val;
        ListNode *next;
        ListNode(int x) : val(x), next(NULL) {}
    };
    //1. 归并排序 时间 O(k*n*log_k) 空间 O(log_k)
    class Solution {
    public:
        ListNode *mergeKLists(vector<ListNode *> &lists) {
            return merge_sort(lists, 0, lists.size()-1);
        }
        ListNode* merge_sort(vector<ListNode*>& lists,int l,int r){
            if(l > r)
                return nullptr;
            else if(l == r)
                return lists[l];
            int mid = l + (r-l)/2;
            ListNode* n1 = merge_sort(lists, l, mid);
            ListNode* n2 = merge_sort(lists, mid+1, r);
            return merge(n1,n2);
        }
        ListNode* merge(ListNode* x,ListNode* y){
            ListNode *head = new ListNode(-1);
            ListNode *temp = head;
            while(x != nullptr && y != nullptr){
                if(x->val <= y->val){
                    temp->next = x;
                    x = x->next;
                }else{
                    temp->next = y;
                    y = y->next;
                }
                temp = temp->next;
            }
            if(x!=nullptr) temp->next = x;
            else if(y != nullptr) temp->next = y;
            return head->next;
        }
    };
    //2. 小根堆 时间O(k*n*log_n)  空间O(k)
    class Solution {
    public:
        struct compare{
            bool operator()(const ListNode* x,const ListNode* y){
                return x->val > y->val;
            }
        };
        ListNode *mergeKLists(vector<ListNode *> &lists){
            priority_queue<ListNode*,vector<ListNode*>,compare> q;
            for(ListNode* x : lists)
                if(x != nullptr)
                    q.push(x);
            if(q.empty())
                return nullptr;
            ListNode* head = new ListNode(-1);
            ListNode* tmp = head;
            while(!q.empty()){
                tmp->next = q.top();
                q.pop();
                tmp = tmp->next;
                if(tmp->next) //注意要放回去 把链表的后一个元素放入
                    q.push(tmp->next);
            }
            return head->next;
        }
    };
    
    
    
    

    今天也是爱zz的一天!

    展开全文
  • 合并\ kk个已排序链表并将其作为一个已排序链表返回。分析并描述其复杂度。 示例1 输入 [{1,2,3},{4,5,6,7}] 返回值 {1,2,3,4,5,6,7} 代码实现: /** * Definition for singly-linked list. * ...

     

    题目描述

    合并\ k k 个已排序的链表并将其作为一个已排序的链表返回。分析并描述其复杂度。 

    示例1

    输入

    [{1,2,3},{4,5,6,7}]

    返回值

    {1,2,3,4,5,6,7}

    代码实现
     

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) {
     *         val = x;
     *         next = null;
     *     }
     * }
     */
    import java.util.*;
    public class Solution {
        public ListNode mergeKLists(ArrayList<ListNode> lists) {
             //优先字符,从小到大
            //重写比较器
            //特殊样例:输入:[[-2,-1,-1,-1],[]]
            if(lists.size() == 0) {
                return null;
            }
            Queue<ListNode> queue = new PriorityQueue( new Comparator<ListNode>() {
                public int compare(ListNode listNode1, ListNode listNode2) {
                    return listNode1.val - listNode2.val;///重载优先级使其变为小根堆
                }
            });
            for(ListNode listNode : lists) {
                if(listNode == null) {
                    continue;
                }
                queue.add(listNode);
            }
            ListNode head = new ListNode(0);
            ListNode tmp = head;
            while(queue.size() > 0) {
               tmp.next = queue.poll();
               tmp = tmp.next;
               if(tmp.next != null) {
                   queue.add(tmp.next);
               }
            }
            return head.next;
    
        }
    }

     

    展开全文
  • 合并K个已排序链表

    2020-12-31 13:06:48
    合并 k 个已排序链表并将其作为一个已排序链表返回 [{1,2,3},{4,5,6,7}] // 入参 {1,2,3,4,5,6,7} // 返回 分治+递归 用二分法把列表进行中间拆分 融合每个小列表中的链表,反向 func mergeKLists( lists []...
  • 合并k个已排序链表 题目描述 假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。 给定两个这种链表,请生成代表两个整数相加值的结果链表。 例如:链表 1 为 9->3->7,链表 2 为 6...
  • 以字符串的形式读入两数字,编写一函数计算它们的和,以字符串形式返回。 (字符串长度不大于100000,保证字符串仅由’0’~'9’这10种字符组成) 输入描述: 输入两字符串格式数字 输出描述: 输出数字相加的...
  • 合并\ kk个已排序链表并将其作为一个已排序链表返回。分析并描述其复杂度。 示例1 输入 [{1,2,3},{4,5,6,7}] 返回值 {1,2,3,4,5,6,7} import java.util.ArrayList; public class MergeKLists { ...
  • class Solution: def mergeKLists(self , lists ): if len(lists)==0: return None res=[] for cur in lists: #将链表元素保存到列表res中 while cur!=None: res.append(cur.val) cur=cur.next
  • 【算法】合并k个已排序链表 https://www.nowcoder.com/questionTerminal/65cfde9e5b9b4cf2b6bafa5f3ef33fa6 这题的解法一、解法二与归并排序的自底向上、自顶向下的思想是一样的,可参照对比。 1.题目 ...
  • 算法题解:合并k个已排序的链表题目为了简化分析,我们设共有k个链表,每个链表的最大长度为n。题解1不断取出值最小的那个Node(因为每个list已经排序,所以这一步只需要找出最小的head Node),添加到已排序链表的...
  • 题目描述(题目难度,困难)合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。示例:输入:[1->4->5,1->3->4,2->6]输出: 1->1->2->3->4->4->5->6示例代码解法...
  • import java.util.ArrayList; import java.util.Comparator; import java.util.PriorityQueue;... * 合并k个已排序链表并将其作为一个已排序链表返回。分析并描述其复杂度。 * 示例1 * 输入: * [{1,2,3},{4,
  • 合并K个已排序链表

    2021-03-19 18:29:55
    两两进行排序 import java.util.*; /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ ...
  • [牛客题霸-研发] NC51-合并k个已排序链表题目描述示例思路算法过程解答 ----------------------------------------------本题链接---------------------------------------------- 题目描述 合并 k 个已排序的...
  • 合并 k 升序的链表并将结果作为一升序的链表返回其头节点。 示例1: 输入:[{1,2,3},{4,5,6,7}] 返回值:{1,2,3,4,5,6,7} 示例2 输入:[{1,2},{3,4,5},{6}] 输出:{1,2,3,4,5,6} /** * Definition for singly-...
  • 合并k个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。示例:输入:[1->4->5,1->3->4,2->6]输出: 1->1->2->3->4->4->5->6看到这道题,能想起来昨天我写的有一篇和...
  • 对于合并k个有序链表,可以先看一下合并两有序链表的思想,(点这里) 对于k个链表的合并,我们可以基于两有序链表的合并思想,先将两个链表合并为一个链表,再将得到的结果链表与第三个链表合并为一个链表,...
  • 合并k个已排序链表

    2021-10-07 21:39:14
    合并k个已排序链表 合并 k 个已排序链表并将其作为一个已排序链表返回。分析并描述其复杂度。 Input : [{1,2,3},{4,5,6,7}] Output : {1,2,3,4,5,6,7} /*合并 k 个已排序链表并将其作为一个已排序链表...
  • 合并k个已排序链表并将其作为一个已排序链表返回。分析并描述其复杂度。 示例1 输入: [{1,3,4},{2,5,6,7}] 返回值: {1,2,3,4,5,6,7} (题目来自牛客网) 用C++实现如下 /** * Definition for singly-linked ...
  • 一、题目要求:将K个有序链表合并为一有序链表二、实现方法:方法一:利用最小堆方法用一大小为K的最小堆(用优先队列+自定义降序实现)(优先队列就是大顶堆,队头元素最大,自定义为降序后,就变成小顶堆,队头...
  • 合并K个已排序链表并将其作为一个已排序链表返回。分析并描述其复杂度。 思路:把K个链表两两合并,然后继续两两合并,最后合并在一起 package main import . "nc_tools" /* * type ListNode struct{ * Val...
  • 请你将所有链表合并到一升序链表中,返回合并后的链表。示例 1:输入:lists = [[1,4,5],[1,3,4],[2,6]]输出:[1,1,2,3,4,4,5,6]解释:链表数组如下:[1->4->5,1->3->4,2->6]将它们合并到一有序...
  • 请你将所有链表合并到一升序链表中,返回合并后的链表。 Leetcode原题地址:https://leetcode-cn.com/problems/merge-k-sorted-lists/ 测试用例 示例1 输入:lists = [[1,4,5],[1,3,4],[2,6]] 输出:[1,1,2,3,4...
  • 合并K个升序链表 给你一个链表数组,每个链表都已经按升序排列。 请你将所有链表合并到一升序链表中,返回合并后的链表。 示例 1: 输入:lists = [[1,4,5],[1,3,4],[2,6]] 输出:[1,1,2,3,4,4,5,6] 解释:链表...
  • 23. 合并K个升序链表 描述 给你一个链表数组,每个链表都已经按升序排列。 请你将所有链表合并到一升序链表中,返回合并后的链表。 分析 有两种主流思路:小顶堆,分治。此处题解为堆的方法。 堆的思路:把所有的...
  • 23. 合并K个升序链表

    2021-01-19 01:51:21
    2.分治法:归并排序,写一切分函数,再写一merge函数,因为数组中存的是链表的头,而每一条链表又是有序的,所以当我们切分到一结点时,就当做切分完毕,只剩一条链表就是有序的(和只剩一元素就算是有序的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 30,102
精华内容 12,040
关键字:

合并k个已排序的链表