题目 ugly-number-ii
编写一个程序,找出第 n 个丑数。
丑数就是只包含质因数 2, 3, 5 的正整数。
Write a program to find the n-th ugly number.
Ugly numbers are positive numbers whose prime factors only include 2, 3, 5.
Example:
Input: n = 10
Output: 12
Explanation: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10 ugly numbers.
Note:
1 is typically treated as an ugly number.
n does not exceed 1690.
理解
方法1
时间复杂度:o(n3)
全部丑数都找出来
MAX最大的整数
i [1--MAX] i2
j[ i--MAX] j3
k[j--MAX] k*5
方法2 bfs 树的层次遍历
输出结果:
[1 ,2 ,3 ,5, 4,6,10,6,9,15,10,15, 25,8,12,20]
期望结果:
【 1, 2, 3, 4, 5, 6, 8, 9, 10, 12】
- 问题1:顺序不对
10=2*5
9=3×3
但是按照顺序 9,10
【 1, 2, 3, 4, 5, 6, 8, 9, 10, 12】
- 问题2 重复数据
6=2×3
6=3*2
解决办法:
需要2个结构队列完成遍历,
- 保证完成层次遍历
- priority_queue
- 判断是否重复元素:()
std::map :时间复杂度 log(n)
std::set : 时间复杂度 log(n),不能通过下标访问
unordered_map:时间复杂度理想情况下 o(1)
性能测试
long 2147483648~2147483647
long long的最大值:9223372036854775807
long long的最小值:-9223372036854775808
实现
我的实现c++
class Solution {
public:
int nthUglyNumber(int n)
{
priority_queue<long long,vector<long long>,greater<long long> > queue;
unordered_map<long long,bool> repeat;
queue.push(1);
repeat[1]=true;
int array[3]={2,3,5};
long long number=1;
int i=0;
while(!queue.empty()&&i++<n)
{
number=queue.top();
queue.pop();//按照从小到大顺序 greater
for(int i=0;i<3;i++)
{
long long temp=array[i]*number;
if(repeat[temp] ==false)
{
repeat[temp]=true;
queue.push(temp);
}
}
}
return number;
}
};
别人的实现 golang
func nthUglyNumber(n int) int {
var ugly []int
ugly = append(ugly, 1)
t2, t3, t5 := 0, 0, 0
for n > len(ugly) {
for ugly[t2]*2 <= ugly[len(ugly)-1] {
t2 += 1
}
for ugly[t3]*3 <= ugly[len(ugly)-1] {
t3 += 1
}
for ugly[t5]*5 <= ugly[len(ugly)-1] {
t5 += 1
}
ugly = append(ugly, min(ugly[t2]*2, ugly[t3]*3, ugly[t5]*5))
}
return ugly[n-1]
}
func min(a, b, c int) int{
if a <= b {
b = a
}
if b <= c {
return b
}
return c
}
4 类似题目
4.1 322. Coin Change
给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。
4.2 测试
输入: coins = [1, 2, 5], amount = 11
输出: 3
解释: 11 = 5 + 5 + 1
4.2 分析
