📌  相关文章
📜  可被给定数组中所有数字整除的最大 K 位数字(1)

📅  最后修改于: 2023-12-03 15:22:57.104000             🧑  作者: Mango

可被给定数组中所有数字整除的最大 K 位数字

题目描述

给定一个正整数数组 nums 和一个正整数 k ,找出由最大的 k 个数组成的数,满足该数可被 nums 中所有数字整除。

示例

输入: nums = [1,2,3,4,5,6], k = 3 输出: "12"

输入: nums = [3,7,2,1,2,3,4,6,7,1,8,9,2], k = 5 输出: "8748"

思路
  1. 首先需要了解一个结论: 一个数能被给定数组中所有数字整除,当且仅当该数是给定数组中所有数字的最小公倍数的倍数。
  2. 因此,首先需要求出给定数组的最小公倍数。求最小公倍数可以通过两个数的乘积除以它们的最大公约数来计算。同理,可通过一个数组中所有数字的乘积除以它们的最大公约数来计算这个数组的最小公倍数。
  3. 然后,将给定数组按照从大到小的顺序排序,选取前 k 个数字组成字符串 res,判断该字符串是否能被数组的最小公倍数整除。如果能,直接返回 res,否则将前 k 个数字重新排序,尝试不同的组合,直到找到一个能被数组的最小公倍数整除的字符串为止。
  4. 注意事项:
    • 由于数组中可能有重复数字,因此在计算最小公倍数时需要去重。
    • 在判断字符串能否被最小公倍数整除时,可通过循环遍历数组的每个元素,计算出该元素与 res 的最大公约数,然后判断该最大公约数是否等于该元素(即 res 中该元素的个数不超过数组中该元素的个数)
代码实现
from math import gcd
from itertools import combinations
from typing import List

def largestMultiple(nums: List[int], k: int) -> str:
    # 计算数组最小公倍数
    lcm = nums[0]
    for num in nums[1:]:
        lcm = lcm * num // gcd(lcm, num)

    # 排序并选取前 k 个数字
    nums.sort(reverse=True)
    res = ''.join(str(num) for num in nums[:k])

    # 判断res是否能被数组的最小公倍数整除
    while int(res) % lcm != 0:
        # 尝试其他组合
        res = max(combinations(res, k), key=lambda x: int(''.join(x)))

    return res
时间复杂度

时间复杂度:$O(n\log n+k^k)$, 其中 n 是数组 nums 的长度。求最小公倍数的时间复杂度为 O(n),排序的时间复杂度为 O(n log n),判断字符串是否能被最小公倍数整除的时间复杂度为 O(k^k)。