zoukankan      html  css  js  c++  java
  • 第 n 个丑数

    自己想了两天都没思路啊啊啊啊啊我真是太笨了。看了他的 tag,说是用到了动态规划,于是特意看了算法导论里动态规划的部分。然而只是说了其思想,第一步构建合理的数据结构,第二部以递归的形式求解。可见水无常形,动态规划并不是单纯的公式就可以解决的。那么具体如何处理呢?

    第一是,什么时候会用到动态规划,就是这样一种情况:后面的结果来自于前面的结果,而前面的结果又已经被求解后存储。前者意味着它的递归结构,后者有种空间换时间的意味。

    明确这个就进入第二个问题,丑数是什么?

    除了 1 之外,由且只由 2 3 5 三种素因子构成的数即为丑数。既然素因子只能有 2 3 5,那么后面的丑数必然是通过前面的丑数乘以 2/3/5 得到的。

    后面的数由前面的求出,而前面的丑数被求出后又储存在数组中,这两点正是之前提到的递归和空间换时间。

    那么新的丑数可能是怎么构成的呢?三种:2 *a/ 3 * b/ 5 * c 因此设置三个标记,分别指示其中 a, b, c 的位置。

    其中,最小的数字成为新的丑数。而在其被选为新丑数之后,下一个新丑数必然要比这个数大(废话) 所以要将相应的标记后移,以确保下一个新丑数的三个选择均大于当前最大的丑数。

    有了以上说明之后,就可以很好理解一下算法了:

    int nthUglyNumber(int n) {
        if (n < 1){
            return 0;
        }
        
        vector<int> ugliness{1};
        
        auto index2 = 0;
        auto index3 = 0;
        auto index5 = 0;
    
        auto saveNewUglyIncreaseIt = [&]
        {
            auto const val2    = ugliness[index2] * 2;
            auto const val3    = ugliness[index3] * 3;
            auto const val5    = ugliness[index5] * 5;
            auto const newUgly = min(val2, min(val3, val5));
            
            if (newUgly == val2){
                ++index2;
            }
            if (newUgly == val3){
                ++index3;
            }
            if (newUgly == val5){
                ++index5;
            }
            ugliness.push_back(newUgly);
        };
        
        for (int i = 1; i != n; ++i){
            saveNewUglyIncreaseIt();
        }
        return ugliness.back();
    }
  • 相关阅读:
    hbase过滤器(1)
    公司jar包提交到集群的方法
    hbase Hfile处理原因
    oracle pl/sql远程连接过程
    mapreduce join操作
    HTML不熟悉方法总结
    Ajax详解
    getElementById和querySelector区别
    Session
    ES6模块化
  • 原文地址:https://www.cnblogs.com/wuOverflow/p/4768162.html
Copyright © 2011-2022 走看看