超级丑数(Super Ugly Number)

Question:
Write a program to find the nth super ugly number.
Super ugly numbers are positive numbers whose all prime factors are in the given prime list primes of size k. For example, [1, 2, 4, 7, 8, 13, 14, 16, 19, 26, 28, 32] is the sequence of the first 12 super ugly numbers given primes = [2, 7, 13, 19] of size 4.
Note:
(1) 1 is a super ugly number for any given primes.
(2) The given numbers in primes are in ascending order.
(3) 0 < k ≤ 100, 0 < n ≤ 10^6, 0 < primes[i] < 1000.

简单地说,这个问题就是要找出第n个超级丑数。超级丑数确实比丑数更加讨厌,是丑数的升级版,可以简单地理解为是丑数的一般形式。给定一个维数为k的素数序列primes。超级丑数就是它的因子只能是primes中的若干个元素。丑数的因子只有2,3,5,所以将丑数推广到一般形式就是超级丑数了。在丑数II中的解决的算法推广一下,就可以用来解决这个问题了。算法如下:

Nth-Super-Ugly-Number(n, PRIMES)
1. if n <= 0 or PRIMES size <= 0 
2.     return -1
3. let PRIMES_LOCATION be the array with the same size as PRIMES
4. for i = 0 to PRIMES.size -1
5.     PRIME_LOCATION[i] = 0
6. let UGLY_NUM be the array with the size of n
7. UGLY_NUM[0] = 1
8. for i = 1 to n-1 
9.     min = UGLY_NUM[PRIMES_LOCATION[0]]*PRIMES[0]
10.     for j = 1 to PRIMES.size -1
11.         if UGLY_NUM[PRIMES_LOCATION[j]]*PRIMES[j]
12.             min = UGLY_NUM[PRIMES_LOCATION[j]]*PRIMES[j]
13.     UGLY_NUM[i] = min
14.     for j = 0 to PRIMES.size -1
15.         if min == UGLY_NUM[PRIMES_LOCATION[j]]*PRIMES[j]
16.             PRIMES_LOCATION[j] += 1
17. return UGLY_NUM[n-1]

算法大致的思路和丑数II的算法一致。只是第3行多了一个数组来存储素数所指的位置,如在丑数II中的U2,U3和U5的位置。第8~16行是找出第i个超级丑数。相应的Java语言实现和Swift语言实现如下。
Java语言实现:

public class Solution {

    public int nthSuperUglyNumber(int n, int[] primes) {

        if (n <= 0 || primes == null || primes.length == 0)
            return -1;

        int lengthOfPrime = primes.length;
        //to indicate the location in the uglyNum of each prime
        int[] primeLocation = new int[lengthOfPrime];
        for (int i = 0; i < lengthOfPrime; i++)
            // set all the location to indicate the first location
            primeLocation[i] = 0;
        int[] uglyNum = new int[n];
        uglyNum[0] = 1;

        for (int i = 1; i < n; i++) {

            int min = uglyNum[primeLocation[0]] * primes[0];
            for (int j = 1; j < lengthOfPrime; j++) {
                if (uglyNum[primeLocation[j]] * primes[j] < min) {
                    min = uglyNum[primeLocation[j]] * primes[j];
                }

            }
            for(int j = 0; j < lengthOfPrime; j ++){
                if(uglyNum[primeLocation[j]] * primes[j] == min){
                    primeLocation[j] += 1;
                }
            }

            uglyNum[i] = min;

        }

        System.out.println(Arrays.toString(uglyNum));

        return uglyNum[n - 1];
    }
}

Swift语言实现:


import Foundation

func nthSuperUglyNumber(n: Int, _ primes: [Int]) -> Int {

    if n <= 0 || primes.count == 0 {
        return -1
    }

    if n == 1{
        return 1
    }

    let primesSize = primes.count
    var primesLocation: [Int] = Array(count: primesSize, repeatedValue: 0)
    var uglyNums: [Int] = Array(count: n, repeatedValue: 0)
    uglyNums[0] = 1
    for i in 1..<n {

        var min = uglyNums[primesLocation[0]] * primes[0]

        for j in 1 ..< primesSize {

            if uglyNums[primesLocation[j]]*primes[j] < min {
                min = uglyNums[primesLocation[j]]*primes[j]
            }
        }

        for j in 0 ..< primesSize {
            if uglyNums[primesLocation[j]]*primes[j] == min {
                primesLocation[j] += 1
            }
        }

        uglyNums[i] = min

    }


    return uglyNums[n-1]
}

参考:
LeetCode 算法题

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
算法与数据结构它们分别涵盖了以下主要内容: 数据结构(Data Structures): 逻辑结构:描述数据元素之间的逻辑关系,如线性结构(如数组、链表)、树形结构(如二叉树、堆、B树)、图结构(有向图、无向图等)以及集合和队列等抽象数据类型。 存储结构(物理结构):描述数据在计算机中如何具体存储。例如,数组的连续存储,链表的动态分配节点,树和图的邻接矩阵或邻接表表示等。 基本操作:针对每种数据结构,定义了一系列基本的操作,包括但不限于插入、删除、查找、更新、遍历等,并分析这些操作的时间复杂度和空间复杂度。 算法算法设计:研究如何将解决问题的步骤形式化为一系列指令,使得计算机可以执行以求解问题。 算法特性:包括输入、输出、有穷性、确定性和可行性。即一个有效的算法必须能在有限步骤内结束,并且对于给定的输入产生唯一的确定输出。 算法分类:排序算法(如冒泡排序、快速排序、归并排序),查找算法(如顺序查找、二分查找、哈希查找),图论算法(如Dijkstra最短路径算法、Floyd-Warshall算法、Prim最小生成树算法),动态规划,贪心算法,回溯法,分支限界法等。 算法分析:通过数学方法分析算法的时间复杂度(运行时间随数据规模增长的速度)和空间复杂度(所需内存大小)来评估其效率。 学习算法与数据结构不仅有助于理解程序的内部工作原理,更能帮助开发人员编写出高效、稳定和易于维护的软件系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值