30.丑数

丑数

题目描述

把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。

这道题有两个版本,一个是简单版,这个版本思路非常简单,但是时间复杂度高,无法过关。

简单版代码如下:

class Solution {
public:
    int GetUglyNumber_Solution(int index) {
    	if ( index <= 0 )  return 0 ;

        int count = 0 ;
        int sumOfUgly = 0 ;
        while ( sumOfUgly <= index ) {
            count += 1 ;
            if ( isUgly( count ) ) {
                sumOfUgly++ ;
            }
        }
        return count ;
    }

    bool isUgly( int n ) {
        while ( n % 2 == 0 ) {
            n /= 2 ;
        }
        while ( n % 3 == 0 ) {
            n /= 3 ;
        }
        while ( n % 5 == 0 ) {
            n /= 5 ;
        }
        return n == 1 ? true : false ;
    }
};

复杂版就要用指针控制了,其实思路也不复杂,以空间换时间。

复杂版代码如下:

class Solution {
public:
    int GetUglyNumber_Solution(int index) {
		if ( index <= 0 ) return 0 ;

        int* arr = new int[index] ;
        arr[0] = 1 ;
        int* multi2 = arr ;
        int* multi3 = arr ;
        int* multi5 = arr ;
        int nextIndex = 1 ;

        while ( nextIndex < index ) {
            int min = MIN( (*multi2) * 2, (*multi3) * 3, (*multi5) * 5 ) ;
            arr[nextIndex] = min ;

            while ( *multi2 * 2 <= min ) multi2++ ;
            while ( *multi3 * 3 <= min ) multi3++ ;
            while ( *multi5 * 5 <= min ) multi5++ ;

            nextIndex++ ;
        }

        int result = arr[nextIndex - 1] ;
        if ( arr != NULL ) delete[] arr ;

        return result ;
    }

    int MIN( int n1, int n2, int n3 ) {
        int tmp = n1 < n2 ? n1 : n2 ;
        return tmp < n3 ? tmp : n3 ;
    }
};

有两个地方要注意:

1.

int result = arr[nextIndex - 1] ;

写成

int result = arr[nextIndex - 1] ;

是错误的,nextIndex要回退一个步长。

2.函数结束前delete指针时我一开始这样写的:

        if ( arr != NULL ) delete[] arr ;
        if ( multi2 != NULL ) delete multi2 ;
        if ( multi3 != NULL ) delete multi3 ;
        if ( multi5 != NULL ) delete multi5 ;

这四个指针指向的同一个内存空间

if ( arr != NULL ) delete[] arr ;

已经归还了内存,但是我还delete了multi2、multi3、multi5,导致同一块内存释放了三次,这无法通过编译。

时间: 2024-10-10 12:51:20

30.丑数的相关文章

Humble Numbers(丑数) 超详解!

给定一个素数集合 S = { p[1],p[2],...,p[k] },大于 1 且素因子都属于 S 的数我们成为丑数(Humble Numbers or Ugly Numbers),记第 n 大的丑数为 h[n]. 算法 1: 一种最容易想到的方法当然就是从 2 开始一个一个的判断一个数是否为丑数.这种方法的复杂度约为 O( k * h[n]),铁定超时(如果你这样做而没有超时,请跟 tenshi 联系) 算法 2: 看来只有一个一个地主动生成丑数了 : 我最早做这题的时候,用的是一种比较烂的

插入排序的优化【不靠谱地讲可以优化到O(nlogn)】 USACO 丑数

首先我们先介绍一下普通的插排,就是我们现在一般写的那种,效率是O(n^2)的. 普通的插排基于的思想就是找位置,然后插入进去,其他在它后面的元素全部后移,下面是普通插排的代码: 1 #include<iostream> 2 #include<fstream> 3 #include<stdio.h> 4 using namespace std; 5 int a[200000]; 6 int p[200000]; 7 8 int main(){ 9 ios::sync_wi

NYOJ1097 Ugly Numbers 【丑数】

Ugly Numbers 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描述 Ugly numbers are numbers whose only prime factors are 2, 3 or 5. The sequence 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, ... shows the first 11 ugly numbers. By convention, 1 is included. Now give you need

UVA136 求第1500个丑数

枚举大范围数据..暴力检查题目条件 #include <iostream> #include <cstdio> #include <vector> #include <algorithm> #include <map> using namespace std; vector<int> Prime; typedef long long ll; bool isPrime(ll x){ ll i; if(x==1) return false

笔试算法题(20):寻找丑数 &amp; 打印1到N位的所有的数

出题:将只包含2,3,5的因子的数称为丑数(Ugly Number),要求找到前面1500个丑数: 分析: 解法1:依次判断从1开始的每一个整数,2,3,5是因子则整数必须可以被他们其中的一个整除,如果不包含任何其他因子则最终的结果为1: 解法2:小丑数必然是某个大丑数的因子,也就是乘以2,3,或者5之后的值,所以可以利用已经找到的丑数来寻找下一个丑数,使用数组有序保存已经找到的丑 数,并且当前最大丑数值为M:用大于M/2的丑数乘以2得到M1,用大于M/3的丑数乘以3得到M2,用大于M/5的丑数

Save Princess(丑数)

Save Princess 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描述 Yesterday, the princess was kidnapped by a devil. The prince has to rescue our pretty princess. "OK, if you want to save the beautiful princess, you must answer my questions correctly."the dev

DP:Humble Numbers,丑数

描述A number whose only prime factors are 2,3,5 or 7 is called a humble number. The sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 24, 25, 27, ... shows the first 20 humble numbers.  Write a program to find and print the nth elemen

hdu1058丑数(优先队列、暴力打表)

hdu1058 题意:当一个数只有2.3.5.7这四种质因数时(也可以一种都没有或只有其中几种),这个数就是丑数,输出第 n 个丑数是多少: 其实并没有发现hdu把这道题放在 dp 专题里的意图,我的思路就是预处理出丑数数组,然后读入 n 就直接输出第 n 个丑数.我自己又一种想法,询问翔神之后又学到了另一种做法. 我自己的生成数组的方法是:数组的第一个元素定为1,然后用优先队列,首先将2,3,5,7放入优先队列,每次从队列中取出最小的一个数,将它放入数组中,然后分别将它乘上2,3,5,7后放入

剑指offer 34_丑数

丑数:只有2 3 5 这三个因子的数,求前(第)1500个.习惯上我们把1当作第一个丑数 例如 6, 8是丑数.14不是. #include <stdio.h> int Min(int x,int y, int z){ int min = (x <= y) ? x : y; return min = (z <= min) ? z : min; } int GetUglyNumber(int index){ if(index <= 0){ return 0; } int* ug