LeetCode合并问题汇总

本文汇总了LeetCode中的合并问题,包括数组合并、两个有序链表的合并、合并多个有序链表以及区间合并。详细介绍了每个问题的解决思路和代码实现,涉及排序和递归等技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       刷题包括笔试中经常会遇到合并问题,将LeetCode中常见的合并问题的代码总结如下,包括数组合并、链表合并、区间合并,涉及到排序,递归等常用操作:

 

1.关于数组合并:(LeetCode 88:merge-sorted-array)

       Given two sorted integer arrays A and B, merge B into A as one sorted array.

       Note:
           You may assume that A has enough space to hold additional elements from B. The number of elements initialized in A  and B are m and n respectively.

    题意:给定两个排序的整数数组A和B,将B合并为A作为一个排序的数组。

public class Solution {
    public void merge(int A[], int m, int B[], int n) {
        int index = m+n-1;
        int i = m-1;
        int j = n-1;
        while(index>=0 && j>=0 && i>=0){
            if(A[i]<=B[j])
                A[index--]=B[j--];
            else
                A[index--]=A[i--];
        }
        if(i<0){
           while(j>=0)
                A[index--]=B[j--];
       }
        if(j<0){
            while(i>=0)
               A[index--]=A[i--];
       }
    }
}

 

2.两个有序链表的合并:(LeetCode 21:merge-two-sorted-lists)

       Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.

     也是剑指offer的原题,使用递归来处理。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */

public class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
         if(l1 ==null && l2 == null)
             return null;
         if(l1==null)
             return l2;
         if(l2 == null)
             return l1;
         if(l1.val<l2.val){
             l1.next = mergeTwoLists(l1.next,l2);
             return l1;
         }else{
             l2.next =  mergeTwoLists(l1,l2.next);
             return l2;
         }
    }
}

 

3.合并多个有序链表:(LeetCode 23:merge-k-sorted-lists)

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

      多个有序链表,可以一次进行合并,调用上述两个有序链表的合并。基于两个排序链表的合并,每一轮复杂度o(n),n为总节点个数,T(n) = 2T(n/2) + o(n),迭代次数为k,因此复杂度为o(n*k)

/**
 * 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) {
        ListNode node = new ListNode(1);
        if(lists.size()<1)
            return null;
        node = lists.get(0);
        if(lists.size()==1)
            return node;
        for(int i =1;i<lists.size();i++){
            node = merge(node,lists.get(i));
        }
        return node;
    }
     public ListNode merge(ListNode n1, ListNode n2) {
         if(n1 ==null && n2 == null)
             return null;
         if(n1==null)
             return n2;
         if(n2 == null)
             return n1;
         if(n1.val<n2.val){
             n1.next = merge(n1.next,n2);
             return n1;
         }else{
             n2.next =  merge(n1,n2.next);
             return n2;
         }
     }
}

也可以使用归并方法,两两合并。

//归并排序算法的时间复杂度是o(nlogn)
import java.util.*;
public class Solution {
    public ListNode mergeKLists(ArrayList<ListNode> lists) {
       if(lists==null||lists.size()==0){
           return null;
       }
       return mergeKList(lists,0,lists.size()-1);
    }
    public ListNode mergeKList(ArrayList<ListNode> lists,int lo,int hi){
        if (hi<=lo) return lists.get(lo);
        int mid=lo+(hi-lo)/2;
        ListNode left = mergeKList(lists,lo,mid);
        ListNode right = mergeKList(lists,mid+1,hi);
        return merge(left,right);
    }
    public ListNode merge(ListNode left,ListNode right){
        ListNode h = new ListNode(-1);
        ListNode tmp=h;
        while(left!=null&&right!=null){
            if(left.val<right.val){
                tmp.next=left;
                left=left.next;
            }else{
                tmp.next=right;
                right=right.next;
            } tmp=tmp.next; }
        if(left!=null){
            
            tmp.next=left;
        }
        if(right!=null){
            tmp.next=right;
        }
        return h.next;
    }
}

 

4.区间合并:(LeetCode 56:merge-intervals)

      Given a collection of intervals, merge all overlapping intervals.

      For example,   Given[1,3],[2,6],[8,10],[15,18],      return[1,6],[8,10],[15,18].

     按照区间开始值进行升序排序,然后将第一个区间添加到list集合中,依次比较后续的区间值,如果不在范围内,新增,如果包含一部分,进行更新。

/**
 * Definition for an interval.
 * public class Interval {
 *     int start;
 *     int end;
 *     Interval() { start = 0; end = 0; }
 *     Interval(int s, int e) { start = s; end = e; }
 * }
 */
import java.util.*;
public class Solution {
    public ArrayList<Interval> merge(ArrayList<Interval> intervals) {
        ArrayList<Interval> list = new  ArrayList<Interval>();
        if(intervals.size()<1)
            return list;
        Collections.sort(intervals,new Comparator<Interval>(){
            public int compare(Interval o1,Interval o2){
                return o1.start-o2.start;
            }
        });
        list.add(intervals.get(0));
        for(int i =1;i<intervals.size();i++){
            if(list.get(list.size()-1).end>=intervals.get(i).start 
                 && list.get(list.size()-1).end<=intervals.get(i).end){
                list.get(list.size()-1).end = intervals.get(i).end;
            }else if(list.get(list.size()-1).end>=intervals.get(i).start 
                  && list.get(list.size()-1).end>=intervals.get(i).end){
                continue;
            }else{
                list.add(intervals.get(i));
            }
        }
        return list;
    }
}

 

5.区间插入后合并(LeetCode:insert-interval)

      Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary).  You may assume that the intervals were initially sorted according to their start times.

Example 1:
        Given intervals[1,3],[6,9], insert and merge[2,5]in as[1,5],[6,9].
        Given[1,2],[3,5],[6,7],[8,10],[12,16], insert and merge[4,9]in as[1,2],[3,10],[12,16].This is because the new interval[4,9]overlaps with[3,5],[6,7],[8,10].

        一边插入,一边更新,如果不满足插入条件,将原有的区间加入到结果中,如果已经与现有区间有重叠,将插入区间合并,并进行下一次的插入,直到满足插入区间的end值小于区间的开始值,结束比较,最后将原有集合中的值插入到结果中,返回结果。

/**
 * Definition for an interval.
 * public class Interval {
 *     int start;
 *     int end;
 *     Interval() { start = 0; end = 0; }
 *     Interval(int s, int e) { start = s; end = e; }
 * }
 */

import java.util.*;
public class Solution {
    public ArrayList<Interval> insert
                    (ArrayList<Interval> intervals, Interval newInterval) {
        ArrayList<Interval> result = new ArrayList<Interval>();
        if(intervals.size()==0){
            result.add(newInterval);
            return result;
        }
        boolean flag = false;
        int i =0;
        for(;i<intervals.size();i++){
            if(intervals.get(i).end < newInterval.start){
                result.add(intervals.get(i));
            }else if(intervals.get(i).start > newInterval.end){
                break;
            }else{
                newInterval.start = 
                        Math.min(intervals.get(i).start,newInterval.start);
                newInterval.end = 
                        Math.max(intervals.get(i).end,newInterval.end);
            }
        }
        result.add(newInterval);
        for(;i<intervals.size();i++){
             result.add(intervals.get(i));
        }
        return result;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值