算法设计与分析: 4-2 最优合并问题

这篇博客探讨了如何解决最优合并问题,即给定多个已排序序列,通过2路合并算法找到合并顺序以最小化比较次数。文章介绍了问题描述,并提供了使用Java实现的算法,同时讨论了确定最差合并顺序以最大化比较次数的情况。输入输出格式和数据处理方法也进行了说明。

4-2 最优合并问题


问题描述

给定 k 个排好序的序列 s1,s2,...,sks1,s2,...,sk , 用 2 路合并算法将这 k 个序列合并成一个序列。
假设所采用的 2 路合并算法合并 2 个长度分别为 m 和 n 的序列需要 m+n-1次比较。试设计一个算法确定合并这个序列的最优合并顺序,使所需的总比较次数最少。
为了进行比较,还需要确定合并这个序列的最差合并顺序,使所需的总比较次数最多。

对于给定的 k 个待合并序列,编程计算最多比较次数和最少比较次数合并方案。

数据输入:
第一行有 1 个正整数 k,表示有 k 个待合并序列。接下来的 1 行中,有 k 个正整数,表示 k 个待合并序列的长度。


Java

import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Scanner;

public class ZuiYouHeBing {

    private static int n;
    private static int[] len;
    private static int[] max;

    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        PriorityQueue<Integer> minQueue;
        PriorityQueue<Integer> maxQueue;

        while (true){
            n = input.nextInt();

            len = new int[n+1];
            max = new int[n+1];
            minQueue = new PriorityQueue<>(n);//默认升序
            maxQueue = new PriorityQueue<>(n, Comparator.reverseOrder());//降序
//            strLen = new PriorityQueue<>(n, Comparator.naturalOrder());//升序
//            strLen = new PriorityQueue<>(n, Comparator.reverseOrder());//降序

//            strLen = new PriorityQueue<>(n, (o1, o2) -> o1.compareTo(o2));//升序
//            strLen = new PriorityQueue<>(n, (o1, o2) -> o2.compareTo(o1));//降序
//            strLen = new PriorityQueue<>(n, (o2, o1) -> o2.compareTo(o1));//升序
//            strLen = new PriorityQueue<>(n, (o2, o1) -> o1.compareTo(o2));//降序

//            strLen = new PriorityQueue<>(n, new Comparator<Integer>() {
//                @Override
//                public int compare(Integer o1, Integer o2) {
//                    return o1.compareTo(o2);//升序
//                }
//            });
//            strLen = new PriorityQueue<>(n, new Comparator<Integer>() {
//                @Override
//                public int compare(Integer o1, Integer o2) {
//                    return o2.compareTo(o1);//降序
//                }
//            });

//            strLen = new PriorityQueue<>(n, new Comparator<Integer>() {
//                @Override
//                public int compare(Integer o1, Integer o2) {
//                    return o1-o2;//升序
//                }
//            });
//            strLen = new PriorityQueue<>(n, new Comparator<Integer>() {
//                @Override
//                public int compare(Integer o1, Integer o2) {
//                    return o2-o1;//降序
//                }
//            });

            for(int i=1; i<=n; i++){
                len[i] = input.nextInt();
                minQueue.add(len[i]);
                maxQueue.add(len[i]);
            }

            int maxSumByArray = getMaxSumByArray();
            int maxSum = getSumByQueue(maxQueue);
            int minSum = getSumByQueue(minQueue);

            System.out.println("Get max by array: "+maxSumByArray);
            System.out.println("Get max by queue: "+maxSum);
            System.out.println("Get min by queue: "+minSum);
        }
    }

    private static int getMaxSumByArray(){
        Arrays.sort(len);
        int maxSum=0;
        max[n] = 0;
        for(int i=n; i>=1; i--)
            max[i-1] = max[i] +len[i];
        for(int i=0; i<=n-2; i++)
            maxSum += max[i];
        maxSum -= n-1;

        return maxSum;
    }

    private static int getSumByQueue(PriorityQueue<Integer> queue){
        int tempSum;
        int sum = 0;
        for(int i=1; i<=n-1; i++){
            tempSum = queue.poll() + queue.poll();
            sum += tempSum;
            queue.add(tempSum);
        }
        sum -= n-1;

        return sum;
    }
}

Input & Output

4
5 12 11 2
Get max by array: 78
Get max by queue: 78
Get min by queue: 52

Reference

王晓东《计算机算法设计与分析》(第3版)P129

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值