zoukankan      html  css  js  c++  java
  • LeetCode -- Merge K Sorted Lists

    Question:

    Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

    Analysis:

    合并k个排好序的链表,返回最终一个总的排序列表。分析并描述他的复杂度。limited

    思路一:我的思路是,设置一个头结点,然后申请一个数组,记录该位置的这组链表是否全部放入新的链表中。不再使用额外的空间,直接用原来的节点。测试了所有情况,都通过了,不过好可惜,time limit exceeded..可能因为我的方法,遍历n次,每次从里面选出最小的一个,所以导致时间复杂度为O(n2).

    代码:

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    public class Solution {
        private ListNode tail;
        
        
        public ListNode mergeKLists(ListNode[] lists) {
            if(lists.length == 0)
                return null;
            if(lists.length == 1)
                return lists[0];
            
            int l = 0;
            for(int i=0; i<lists.length; i++) {
                if(lists[i] == null)
                    l++;
            }
            if(l == lists.length)
                return null;
            
           boolean[] mark = new boolean[lists.length]; //初始化时false
            
            ListNode h = new ListNode(-1);
            tail = h;
            int flag = 0;
            
            while(flag < lists.length) {
                int min = Integer.MAX_VALUE;
                int mint = -1;
                for(int i=0; i<lists.length; i++) {
                    if(lists[i] == null)
                        continue;
                    if(lists[i].val < min && mark[i] == false && lists[i] != null) {
                        min = lists[i].val;
                        mint = i;
                    }
                }
                if(mint == -1)
                    return h.next;
                //找到了本轮循环的最小值
                tail.next = lists[mint];
                if(lists[mint].next != null) {
                    tail = lists[mint];
                    lists[mint] = lists[mint].next;
                    tail.next = null;
                } else {
                    mark[mint] = true;
                    tail = lists[mint];
                    flag++;
                }
                
            }
            return h.next;
        }
    }

    思路二:使用归并排序(Merge Sort)算法。是一个比较经典的O(nlogn)的排序算法。思路是先分成两个子任务,然后递归求子任务,最后回溯回来。这个题目也是这样,先把k个list分成两半,然后继续划分,知道剩下两个list就合并起来,合并时会用到Merge Two Sorted Lists这道题.

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    public class Solution {
            //用归并排序的方法
        public ListNode mergeKLists(ListNode[] lists) {
            if(lists.length == 0)
                return null;
            if(lists.length == 1)
                return lists[0];
            
            int l = 0;
            for(int i=0; i<lists.length; i++) {
                if(lists[i] == null)
                    l++;
            }
            if(l == lists.length)
                return null;
            
            return deal(lists, 0, lists.length - 1);         
        }
        
        
        private ListNode deal(ListNode[] lists, int i, int j) { //重点!!掌握这种思路
            // TODO Auto-generated method stub
            if(i < j) {
                int m = (i + j) / 2;
                return mergeTwoLists(deal(lists, i, m), deal(lists, m+1, j)); 
            }
            return lists[i];
        }
    
        public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
            ListNode p1 = l1;
            ListNode p2 = l2;
            
            if(l1 == null && l2 == null)
                return null;
            if(l1 == null && l2 != null)
                return l2;
            if(l1 != null && l2 == null)
                return l1;
            
            ListNode fakeHead = new ListNode(0);
            ListNode p = fakeHead;
            
            while (p1 != null && p2 != null){
                if (p1.val <= p2.val) {
                    p.next = p1;
                    p1 = p1.next;
                    p = p.next;
                } else {
                    p.next = p2;
                    p2 = p2.next;
                    p = p.next;
                }
            }
            
            if(p1 != null)
                p.next = p1;
            if(p2 != null)
                p.next = p2;
            return fakeHead.next;
        }
    }

    总结:遇到这种把n个排好序的东西混合成一个时,要立马想到归并排序。递归+回溯的方法!!

  • 相关阅读:
    本周学习小结(04/11
    学习笔记之知识图谱 (Knowledge Graph)
    本周学习小结(28/10
    本周学习小结(21/10
    条件分页 代替离线查询
    Apache POI 一键上传(导入excel文件到数据库)
    easyui 菜单按钮&提示框
    Jquery ztree树插件
    Jquery ztree树插件2
    ui
  • 原文地址:https://www.cnblogs.com/little-YTMM/p/4803488.html
Copyright © 2011-2022 走看看