丑数、丑数 II

丑数

感觉人都变丑了 - -||| 不能叫漂亮数码

这里写图片描述

简单版的很简单,不停的除二,除三,除五就行了。

class Solution {
public:
    /**
     * @param num an integer
     * @return true if num is an ugly number or false
     */
    bool isUgly(int num) {
        // Write your code here
        if(num <= 0) return false;
        while(num != 1){
            if(num%2 == 0) num = num/2;
            else break;
        }
        while(num != 1){
            if(num%3 == 0) num = num/3;
            else break;
        }
        while(num != 1){
            if(num%5 == 0) num = num/5;
            else break;
        }
        if(num == 1) return true;
        else return false;

    }
};

丑数II

这里写图片描述

找了半个小时规律也找不到。。。。标签有限队列就用优先队列做好了。。。

#include <functional>
class Solution {
public:
    /*
     * @param n an integer
     * @return the nth prime number as description.
     */
    int nthUglyNumber(int n) {
        // write your code here
        priority_queue<long long,vector<long long>,greater<long long>> que;
        que.push(1);
        int count = 0;
        long long current = -1;
        while(count < n){
            long long top = que.top();
            que.pop();
            if(top == current) continue;
            que.push(top*2);
            que.push(top*3);
            que.push(top*5);
            current = top;
            ++count;
        }
        return current;
    }    

};

重点来啦,一定要用long long,因为最后虽然结果不会溢出,但是计算过程中会溢出。比如 x×5 溢出了,变成了负数,放进堆里就是最小的啦,所以结果都变成了负数。
所以就想着,那我就把<0的数全部都不要了,只要大的就行了。如下:

if (top * 2 > 0) que.push(top * 2);
if (top * 3 > 0) que.push(top * 3); 
if (top * 5 > 0) que.push(top * 5);

也不行!!这不坑爹嘛。原来啊 比如有的数 * 5它竟然溢出了两次,又变成了正数了。如下:

这里写图片描述

我说怎么9704804总是出现。

方法二

所有丑数都是由之前的丑数 ×2 ×3 ×5 得到的。而且乘以2后,下次乘2的数就向后移啦

class Solution {
public:
    /*
     * @param n an integer
     * @return the nth prime number as description.
     */
    int nthUglyNumber(int n) {
        // write your code here
        int p2 = 0;
        int p3 = 0;
        int p5 = 0;
        vector<int> ugly;
        ugly.push_back(1);
        int count = 1;
        while(count < n){
            int ugly2 = ugly[p2]*2;
            int ugly3 = ugly[p3]*3;
            int ugly5 = ugly[p5]*5;
            if(ugly2 <= ugly3 && ugly2 <= ugly5){
                ++p2;
                if(ugly2 == ugly[count-1]) continue;
                ugly.push_back(ugly2);
            }else if(ugly3 <= ugly2 && ugly3 <= ugly5){
                ++p3;
                if(ugly3 == ugly[count-1]) continue;
                ugly.push_back(ugly3);
            }else{
                ++p5;
                if(ugly5 == ugly[count-1]) continue;
                ugly.push_back(ugly5);
            }
            cout<<"aaa:"<<ugly[count-1]<<endl;
            ++count;
        }
        return ugly[n-1];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值