原题网址:https://leetcode.com/problems/ugly-number-ii/
Write a program to find the n
-th ugly number.
Ugly numbers are positive numbers whose prime factors only include 2, 3, 5
. For example, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12
is the sequence of the first 10
ugly numbers.
Note that 1
is typically treated as an ugly number.
思路:动态规划。因数2、3、5可以分别乘以前面的数字,找出最小的一个作为下一个。
public class Solution {
public int nthUglyNumber(int n) {
if (n<=1) return 1;
int[] nums = new int[n];
nums[0] = 1;
int f2 = 0, f3 = 0, f5 = 0;
for(int i=1; i<n; i++) {
int m2 = nums[f2] * 2;
int m3 = nums[f3] * 3;
int m5 = nums[f5] * 5;
if (m2 <= m3 && m2 <= m5) {
nums[i] = m2;
f2 ++;
} else if (m3 <= m2 && m3 <= m5) {
nums[i] = m3;
f3 ++;
} else {
nums[i] = m5;
f5 ++;
}
if (nums[i] == nums[i-1]) i --;
}
return nums[n-1];
}
}
可以进一步优化得更简洁:
public class Solution {
public int nthUglyNumber(int n) {
if (n <= 1) return 1;
int[] nums = new int[n];
int size = 0;
nums[size++] = 1;
int p2 = 0, p3 = 0, p5 = 0;
for(int i=2; i<=n; i++) {
int m2 = nums[p2] * 2;
int m3 = nums[p3] * 3;
int m5 = nums[p5] * 5;
int m = m2;
if (m3 < m) m = m3;
if (m5 < m) m = m5;
nums[size++] = m;
if (m2 == m) p2 ++;
if (m3 == m) p3 ++;
if (m5 == m) p5 ++;
}
return nums[size-1];
}
}
另一种实现:
public class Solution {
public int nthUglyNumber(int n) {
if (n<=0) return 0;
int[] factor = {2, 3, 5};
int[] pos = new int[3];
int[] nums = new int[n];
nums[0] = 1;
for(int i=1; i<n; i++) {
int min = 0;
if (nums[pos[1]] * factor[1] < nums[pos[min]] * factor[min]) min = 1;
if (nums[pos[2]] * factor[2] < nums[pos[min]] * factor[min]) min = 2;
nums[i] = factor[min] * nums[pos[min]++];
if (nums[i] == nums[i-1]) i--;
}
return nums[n-1];
}
}