LintCode 4. 丑数 II

原题

第一步,万年不变的查错。如果给的n是小于1,那么这个就没什么意义了,return 0。

    public int nthUglyNumber(int n) {
        if (n < 1) {
            return 0;
        }
        ...
    }

这道题,找只含有质因数2,3,5的数。大体的做法就是从1开始,乘以2,3,5,找出最小的,再乘以2,3,5,和之前的比,找最小的。大致的code就是

public class Solution {
    /*
     * @param n: An integer
     * @return: the nth prime number as description.
     */
    public int nthUglyNumber(int n) {
        if (n < 1) {
            return 0;
        }
        List<Long> uglyNumbers = new ArrayList<>();
        uglyNumbers.add(1L);
        
        int twos = 0;
        int threes = 0;
        int fives = 0;

        for (int i = 1; i < n; i++) {
            Long last = uglyNumbers.get(uglyNumbers.size() - 1);
            while (uglyNumbers.get(twos) * 2 <= last) {
                twos++;
            }

            while (uglyNumbers.get(threes) * 3 <= last) {
                threes++;
            }

            while (uglyNumbers.get(fives) * 5 <= last) {
                fives++;
            }

            Long next = Math.min(uglyNumbers.get(twos) * 2, Math.min(uglyNumbers.get(threes) * 3, uglyNumbers.get(fives) * 5));
            uglyNumbers.add(next);
        }

        return uglyNumbers.get(uglyNumbers.size() - 1).intValue();
    }
}

解2

第一种方法比较没意思。我们可以想一下,从1开始,每一个数字都要乘以2,3,5,然后我们只去当前最小的,剩下的要跟以后乘出来的数字再排序,所以有木有一种data structure能即保留住这些乘出来又没有立即用到的数,又在我们需要的时候,很快的给我们下一个,即最小的数呢?MinHeap,or PriorityQueue。

public class Solution {
    /*
     * @param n: An integer
     * @return: the nth prime number as description.
     */
    public int nthUglyNumber(int n) {
        if (n < 1) {
            return 0;
        }
        
        Queue<Long> pq = new PriorityQueue<>();
        pq.add(1L);
        Set<Long> hash = new HashSet<>();
        int[] factors = new int[]{2, 3, 5};

        long num = 0;
        for (int i = 0; i < n; i++) {
            num = pq.poll();
            for (int j = 0; j < 3; j++) {
                long newNum = num * factors[j];
                if (!hash.contains(newNum)) {
                    pq.add(newNum);
                    hash.add(newNum);
                }
            }
        }

        return (int) num;
    }
}

code不难,就是需要一个HashSet来快速去重。

分析

时间复杂度

第一个解法,循环n次,每次3次计算2次对比,while循环的可以忽略,因为总共加起来也就能循环n次。这样的话,应该是O(n)。第二个解法,循环n次,每次poll的时候,PriorityQueue里面大概有3n的数,所以是O(log3n),3可以忽略,也就是O(logn),后面还要加3次。总共就是O(nlogn)。

空间复杂度

第一个解法,需要一个O(n)的list来放从1到n的数字。第二个需要一个O(n)的queue加O(n)的HashSet。

两种方法我更喜欢第二种,code更简便。但是第一种更效率。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 背景 一年多以前我在知乎上答了有关LeetCode的问题, 分享了一些自己做题目的经验。 张土汪:刷leetcod...
    土汪阅读 12,973评论 0 33
  • 题目 描述 设计一个算法,找出只含素因子2,3,5 的第 n 大的数。符合条件的数如:1, 2, 3, 4, 5,...
    悠扬前奏阅读 1,022评论 0 0
  • 现在我还是一个在二流大学学习音乐的学生,学习长笛专业。音乐的学习并不简单,接触过的人可能都会了解到,熟悉一门乐器,...
    Sylvia_钰阅读 841评论 0 2
  • 昨日千娇争明媚,今时薄雾锁轻寒。 犹记去年芳丛过,佳人窈窕微风暖。 昂首浓云天欲雨,低眉流水行潺潺。 纵有纷繁丛杂...
    潇雨水莲阅读 374评论 0 3
  • 2018年1月19日 星期六 天气晴 这个周六过的是即繁忙又紧张,把时间安排的满满的。周五晚上陪女儿学习睡的有点...
    太阳玥玥阅读 203评论 0 0

友情链接更多精彩内容