算法系列:(三).归并算法之>>两个升序数组的二元归并,时间复杂度O(m+n)

方法1:(利用数组作为容器):

    特点:

        1/结果为数组,合并后依然可以通过下标快速访问;

        2/需要考虑重复元素导致的合并后结果数组实际长度变短问题;



//两个升序数组进行升序归并(二元归并)  时间复杂度O(m+n)
public class Test_AfterClass1 {
    public static void main(String[] args) {
        int[] arr1={1,3,5,6,7,9,10,11,35};//升序数组arr1
        int[] arr2={1,3,4,7,9,12,34};//升序数组arr2

        int a=arr1.length;//数组arr1长度
        int b=arr2.length;//数组arr2长度
        int[] arr = new int[a+b];//合并排序后的初始容器

        int i = 0;//arr1索引
        int j = 0;//arr2索引
        int k = 0;//arr索引
        int m=1;//记录重复元素个数

        //若两个数组均未到到最后一个元素.谁小放谁
        while(i<a && j<b) {
            if(arr1[i]<=arr2[j]) {
                arr[k++] = arr1[i++];
                //去重
                if(arr1[i-1]==arr2[j]) {
                    j++;//跳过重复元素下标
                    m++;//重复元素个数+1
                }
            }else arr[k++] = arr2[j++];
        }
        while(i==a && j<b) arr[k++] = arr2[j++];//若arr1到达最后一个元素,直接开始存arr2剩余元素
        while(j==b && i<a) arr[k++] = arr1[i++];//若arr2到达最后一个元素,直接开始存arr1剩余元素

        //将初始容器的有效值放入最终容器
        int[] arrLast = new int[a+b-m];//最终容器
        for (int i1 = 0; i1 < arrLast.length; i1++) { //循环放入
            arrLast[i1]=arr[i1];
        }

        int term=1;//换行标志
        //增强for循环遍历输出结果
        for (Integer integer : arrLast) {
            System.out.print(integer+" ");
            if(term++%50==0) System.out.println();//是否换行
        }
    }

}

 方法2:(利用LinkedHashSet集合作为容器)

    特点:

        1/结果为链式哈希集,可以利用其有序和无重复的特性实现去重;

        2/无法通过下标访问元素;

package teacherday4;

import java.util.LinkedHashSet;

//利用LinkedHashSet作为容器对两个升序数组进行升序归并(二元归并),可省略去重逻辑  时间复杂度O(m+n)
public class Test_AfterClass {
    public static void main(String[] args) {

        int[] arr1={1,3,5,6,7,9,10,11,35};//升序数组1
        int[] arr2={1,3,4,7,9,12,34,35,38};//升序数组2

        int j=0,k=0,m=arr1.length,n=arr2.length;//arr1索引  arr2索引  arr1长度  arr2长度
        LinkedHashSet<Integer> arrSet=new LinkedHashSet<>();//合并排序后的存放容器

        //若两个数组均未到到最后一个元素.谁小放谁
        while(j<m&&k<n){
            if(arr1[j]<=arr2[k]) arrSet.add(arr1[j++]);
            else arrSet.add(arr2[k++]);//此处重复元素无法放进链式哈希集
        }
        while(j==m&&k<n) arrSet.add(arr2[k++]);//若arr1到达最后一个元素,直接开始存arr2剩余元素
        while(j<m&&k==n) arrSet.add(arr1[j++]);//若arr2到达最后一个元素,直接开始存arr1剩余元素

        int term=1;//换行标志
        //增强for循环遍历输出结果
        for (Integer integer : arrSet) {
            System.out.print(integer+" ");
            if(term%50==0) System.out.println();//是否换行
        }
    }
}

 

总结:

     1/方法1比fang方法2多了去重代码,但是去重思维有点绕,但数组的下标查询较快;

     2/方法2不需要考虑去重,但无法直接通过下标访问结果元素;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章