丑数

丑数Leetcode

问题描述:

给你一个整数 n ,请你找出并返回第 n 个 丑数 。
丑数 就是只包含质因数 2、3 和/或 5 的正整数。

答题思路:

(手动@端粒大佬)

三指针法:因为丑数只是因数只有2,3,5的数;所以先设置一个dp数组表示当前已经找出并排列好的丑数数组;再3个指针:i,j,k 表示 将当前已经排好的数组元素 分别乘2,3,5 所得的数组(实际上,因为所得的数字最终会加入唯一的排序数组,所以并不用真正将3个数组建立起来),因为排序后数组乘2,3,5得到的也是已经排序数组,接下来的目的就是从这3个虚拟数组中的头元素中取得最小那个值;(实际上并不会出现3个数组)所以关键就是如何用这3个指针进行选择,实际上排序并不是在加入排序数组后才整理排序,而是每次用老元素*2,*3,*5生成新元素的时候,选择最小的加入达到排序目的,这个时候指针移动就起到作用了,如下过程所示:


已经排好的数组,先放进第一个丑数1:[1]

排好数组*2 :[1]*2=2

排好数组*3 :[1]*3=3

排好数组*5 :[1]*5=5

选结果中最小的数加入数组,此时明显是2,新的排序数组为[1,2];


已经排好的数组:[1,2]------此时上次结果中,2,3,5只用到了2;但3明显是这次需要加入的数;既然2已经加入,再去对比2没意义了,那么就将 (2的指针) [1]转向下一位[2],对比 (下一个元素2 和3,5)的大小,取最小的加入;
排好数组*2 :[2]2=4
排好数组
3 :[1]3=3
排好数组
5 :[1]*5=5
选结果中最小的数加入数组,此时明显是2,新的排序数组为[1,2,3];


已经排好的数组:[1,2,3]------3已经加入,移动它的指针到排序数组下一位;
排好数组*2 :[2]2=4
排好数组
3 :[2]3=6
排好数组
5 :[1]*5=5
选结果中最小的数加入数组,此时明显是4,新的排序数组为[1,2,3,4];依次类推;可以看到,实际上,只需将指针进行分别移动就可以了;所以要做出3个指针;


维护3个值val2,val3,val5,表示将当前排列好数组 分别*2,*3,*5所得的结果数;

因为可能3组数出现重复现象,所以要判断是否重复后再加入


## 代码:
int min(int a, int b, int c)
{
    int temp;
    temp = a < b ? a : b;
    return temp < c ? temp : c;
}
int nthUglyNumber(int n){
    int *num = (int*)malloc(sizeof(int) * n);
    num[0] = 1;
    int p1 = 0; 
    int p2 = 0;
    int p3 = 0;
    int sum = 1;
    for (int i = 1; i < n; i++) {
        int temp = min(num[p1] * 2, num[p2] * 3, num[p3] * 5);
        num[i] = temp;
        if (temp == num[p1] * 2) {
            p1++;
        }
        if (temp == num[p2] * 3) {
            p2++;
        }
        if (temp == num[p3] * 5) {
            p3++;
        }
        sum = temp;
    }
    return sum;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值