题目
题解
定义pointers[]指针数组,下一个超级丑数=当前指针指向的超级丑数*对应的质因数,初始时均为1
- 状态定义:
dp[i] 表示 第 i-1 个超级丑数。 - 状态转移方程:
dp[i]=min(dp[pointer[j]] * primes[j]),j从0到m-1,其中m=primes.length。
对于每一个范围内的 j,如果dp[i]==dp[pointers[j]] * primes[j],pointers[j]++。 - 初始条件:
dp[1]=1,最小的超级丑数为1。 - 返回值:dp[n]。
btw,在数组中找最小数的代码为Arrays.stream(nums).min().getAsInt()
注意:存在整数超限的问题,需要添加特殊判断
class Solution {
public int nthSuperUglyNumber(int n, int[] primes) {
int m=primes.length;
int[] dp=new int[n];
dp[0]=1;
int[] pointers=new int[m];//相当于丑数中的a,b,c
int[] nums=new int[m];//相当于丑数中的n1,n2,n3
Arrays.fill(nums,1);
for(int i=1;i<n;i++){
//找最小
int minNum=Integer.MAX_VALUE;
for(int j=0;j<m;j++){
nums[j]=dp[pointers[j]] * primes[j];
if(nums[j]<0)
continue;
else//超出int的max范围
minNum=Math.min(minNum,nums[j]);
}
dp[i]=minNum;//相当于丑数中的min(n2,n3,n5)
for(int j=0;j<m;j++){
if(nums[j]==minNum){
pointers[j]++;
}
}
}
return dp[n-1];
}
}
时间复杂度: O ( n m ) O(nm) O(nm)
空间复杂度: O ( n + m ) O(n+m) O(n+m)