Ugly Number I II

题目263/4:Ugly Number I II

leetcode上题目263、题目264,同时是《offer》上面试题34。

1. 题目263:Ugly Number I

链接:https://leetcode.com/problems/ugly-number/
判断是否是丑数,代码如下:

class Solution {
public:
    bool isUgly(int num) {
        if (num <= 0)
            return false;
        while (num % 2 == 0)
            num /= 2;
        while (num % 3 == 0)
            num /= 3;
        while (num % 5 == 0)
            num /= 5;
        return num == 1;
    }
};

2. 题目264:Ugly Number II

链接:https://leetcode.com/problems/ugly-number-ii/
输出第n个丑数。
思路1:按顺序每个数都判断是否是丑数,这样结果是TLE。
代码1:

class Solution {
public:
    bool isUgly(int num) {
        while (num % 2 == 0)
            num /= 2;
        while (num % 3 == 0)
            num /= 3;
        while (num % 5 == 0)
            num /= 5;
        return num == 1;
    }
    int nthUglyNumber(int n) {
        int count, res, i;
        res = 1;
        count = 1;
        while (count < n) {
            ++ res;
            if (isUgly(res))
                ++ count;
        }
        return res;
    }
};

思路2:只生成丑数,其他数不做判断。
丑数也丑得很有特点,丑数都是前面的丑数与2、3、5的乘积。
假设我们现在已经有排序好的N个丑数,现在最大的丑数记为M,求下一个丑数。
求下一个丑数,将已经得到的丑每一个分别乘以2、3、5,乘以2得到第一个大于M的丑数M2,乘以3得到第一个大于M的丑数M3,乘以5得到第一个大于M的丑数M5,取M2、M3、M5这3个数中的最小值就是M之后的下一个丑数。
再分析,还要可以优化的,只需要记录位置,代码如下:

class Solution {
public:
    int NthUglyNumber(int n) {
        int pos2, pos3, pos5;
        vector<int> res(1, 1);
        pos2 = 0;
        pos3 = 0;
        pos5 = 0;
        while (res.size() < n) {
            int m2 = res[pos2] * 2;
            int m3 = res[pos3] * 3;
            int m5 = res[pos5] * 5;
            int mn = min(m2, min(m3, m5));
            if (mn == m2)
                ++ pos2;
            if (mn == m3)
                ++ pos3;
            if (mn == m5)
                ++ pos5;
            res.push_back(mn);
        }
        return res.back();
    }
};

lintcode也有对应的题目,需要多注意一点是,返回类型是long long类型的,如果求第n个丑数,n比较大时,int类型会溢出。

参考:http://www.cnblogs.com/grandyang/p/4743837.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值