分治算法+题目

分治算法+题目

  • 分治算法是什么
  • 题目:合并K个升序链表
  • 总结

分治算法是什么

问题分解后进行求解,相比于不分解直接求解,时间复杂度更低。符合这个特征的算法,我们才称之为「分治算法」。

题目:合并K个升序链表

题目
分治算法+题目_第1张图片
分治算法:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    //分治的思想 二分分治 时间复杂度是O(N*logN)
    public ListNode mergeKLists(ListNode[] lists) {
        int sz=lists.length;
        return merge(lists,0,sz-1);
    }
    //定义:合并lists[startIndex...endIndex]上的链表
    ListNode merge(ListNode[] lists,int startIndex,int endIndex){
        //没有链表
        if(startIndex>endIndex){
            return null;
        }
     
        //一条链表
        if(endIndex==startIndex){
            return lists[startIndex];
        }


        //分成两段 [startIndex,mid][mid+1,endIndex]
        int mid=(startIndex+endIndex)/2;

        //合并左边的
       ListNode left= merge(lists,startIndex,mid);

        //合并右边的
       ListNode right= merge(lists,mid+1,endIndex);

        //合并左右边的
       return mergeTwoLists(left,right);
    }
    ListNode mergeTwoLists(ListNode list1,ListNode list2){
         ListNode dummy=new ListNode(-1);
        ListNode cur=dummy;
        ListNode p1=list1;
        ListNode p2=list2;
        while(p1!=null && p2!=null){
            if(p1.val<p2.val){
                cur.next=p1;
                p1=p1.next;
            }else{
                cur.next=p2;
                p2=p2.next;
            }
            cur=cur.next;
        }
       while(p1!=null ){
            cur.next=p1;
            p1=p1.next;
            cur=cur.next;
       }
        while(p2!=null ){
            cur.next=p2;
            p2=p2.next;
            cur=cur.next;
       }
       cur.next=null;
        return dummy.next;
    }
}

优先级队列:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    //把所有的节点放入 优先级队列中 然后一个个取出
    public ListNode mergeKLists(ListNode[] lists) {
        // 优先级队列,最小堆
        PriorityQueue<ListNode> pq = new PriorityQueue<>(new Comparator<ListNode>() {
        	@Override
        	public int compare(ListNode o1, ListNode o2) {
        		// TODO Auto-generated method stub
        		return o1.val-o2.val;
        	}
		});
        //取出所有链表 将每个节点入队列
       for(ListNode list:lists) {
    	  ListNode cur=list;
    	  while(cur!=null) {
    		  pq.add(cur);
    		  cur=cur.next;
    	  }
       }
       //取出所有节点
       ListNode dummy=new ListNode(-1),cur=dummy;
       while(!pq.isEmpty()) {
    	    cur.next=pq.poll();
    	   cur=cur.next;
       }
       cur.next=null;
       return dummy.next;
    }
}

总结

分治算法+题目_第2张图片

把递归算法抽象成递归树,如果递归树节点的时间复杂度和树的深度相关,那么使用分治思想对问题进行二分,就可以使递归树尽可能平衡,进而优化总的时间复杂度

你可能感兴趣的:(算法,leetcode,java)