算法学习-多路归并(多指针)

笔者在刷题的过程中,多次看到多路归并的身影,因此尝试对此做个专题。多路归并就是将多个序列进行归并,产生的结果序列中有我们想要的结果,但是无脑归并势必会产生一些后果,比如多路中有重复等等,因此就是需要一些算法技巧来处理。

多路归并最经典的题目应该是“丑数”,因此我从这一题开始。

相关题目

264.丑数2

参考宫水三叶的题解,从优先队列找最小值,复杂度为O(NlogN),优化到了多路归并多指针移动找最小值,复杂度为O(N)。用dp[i]记录结果,本质上也是动态规划,每个序列的当前值是根据其目前在dp[i]指向的最小值dp[p]决定的(这和以前我们写的只有一个指针的动态规划不一样),然后当前的最小值dp[i]是所有序列指向最小值dp[p]的下一个的最小值。同时在移动比对minV==a或者minV==b或者minV=c过程中,不仅移动了每个序列的指针,也排除了多个序列中会重复选取一个值的可能。

class Solution {
    public int nthUglyNumber(int n) {
        int[] dp=new int[n+1];
        dp[1]=1;
        //定义三个指针
        int p1=1;
        int p2=1;
        int p3=1;
        for(int i=2;i<=n;i++){
            int a=2*dp[p1],b=3*dp[p2],c=5*dp[p3];
            int res=Math.min(a,Math.min(b,c));
            dp[i]=res;
            if(a==res) p1++;
            if(b==res) p2++;
            if(c==res) p3++;
        }
        return dp[n];
    }
}
第k个数

同丑数2

class Solution {
    public int getKthMagicNumber(int k) {
        long[]dp=new long[k+1];
        dp[1]=1;
        int dp1=1;
        int dp2=1;
        int dp3=1;
        for(int i=2;i<=k;i++){
            long a= 3L*dp[dp1],b=5L*dp[dp2],c=7L*dp[dp3];
            long res=Math.min(a,Math.min(b,c));
            dp[i]=res;
            if(a==res) dp1++;
            if(b==res) dp2++;
            if(c==res) dp3++;
        }   
        return (int)dp[k];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

互联网民工蒋大钊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值