leetcode
leetcode 2451 ~ 2500
给定数字乘积的最小数字

给定数字乘积的最小数字

难度:

标签:

题目描述

代码结果

运行时间: 32 ms, 内存: 16.0 MB


/*
 * Leetcode Problem 2847: Smallest Number With Given Product
 * 
 * Problem Statement:
 * Given an integer n, return the smallest positive integer that has a digit product of n.
 * If no such integer exists, return -1.
 * 
 * Approach:
 * 1. If n is less than 10, return n (since the smallest number with the digit product n is n itself).
 * 2. Use a list to store the digits.
 * 3. Iterate from 9 down to 2 and for each digit, add it to the list if it divides n.
 * 4. Sort the list and convert it to a number.
 */

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class SmallestNumberWithProductStream {
    public static int smallestNumber(int n) {
        if (n < 10) return n;
        List<Integer> digits = new ArrayList<>();
        for (int i = 9; i >= 2; i--) {
            while (n % i == 0) {
                digits.add(i);
                n /= i;
            }
        }
        if (n > 1) return -1;
        Collections.sort(digits);
        return digits.stream().reduce(0, (a, b) -> a * 10 + b);
    }

    public static void main(String[] args) {
        System.out.println(smallestNumber(36)); // Output: 49
        System.out.println(smallestNumber(100)); // Output: 455
        System.out.println(smallestNumber(7)); // Output: 7
    }
}

解释

方法:

该题解的思路是使用贪心算法的方法,寻找能够整除给定数字n的最小数字。从最大的单数位数字9开始,依次降到2,尝试用n除以这些数字,以检查能否整除。每当发现n可以被当前数字i整除时,就将i加入结果列表,并用n除以i更新n。这个过程一直持续到n不能被2到9之间的任何数字整除。最后,将结果列表逆序并连接成字符串形式,因为要返回最小的数字,较小的数字应该位于前面。如果最终n不等于1,说明n包含比9更大的质因数,这时应该返回'-1'。

时间复杂度:

O(log n)

空间复杂度:

O(log n)

代码细节讲解

🦆
为什么你选择从9开始向下至2遍历,而不是从2向上至9遍历?这种顺序对结果有什么影响?
选择从9开始向下至2遍历的原因是为了尽可能地使用较大的因数,这样可以减少因数的个数,从而在最后连接数字时得到较小的数字。例如,如果n可以被9整除,选择9作为因数比选择3三次更能减少数字长度,从而得到一个较小的结果。如果从2向上至9遍历,会导致结果中较小的数字更多,而这些较小的数字多次出现会使得最终组合的数字更大。因此,从9到2的遍历顺序可以帮助我们得到尽可能小的数字。
🦆
当n最终不等于1,返回'-1',这是否意味着n包含大于9的质因数?能否给出一个具体的例子来说明这种情形?
是的,当n最终不等于1且返回'-1'时,这意味着n包含大于9的质因数。例如,如果n是22,在试图用2到9之间的任何数字整除22时,最终n将变为11,因为22可以被2整除一次。由于11是一个质数且大于9,所以剩余的数11无法被2到9之间的任何数字再次整除。这种情况下,因为11大于9且没有被完全分解,所以算法返回'-1'。
🦆
你如何确保将因数添加到列表并最终逆序连接可以得到最小的数字?这种方法适用于所有情况吗?
将因数添加到列表并最终逆序连接得到最小的数字的策略是基于贪心算法的思想。由于我们从大到小添加因数,这样可以确保每步都是使用最大可能的因数,减少因数的数量。在完成所有可能的整除后,逆序连接是因为较小的因数在最终数字中应该位于更高位以形成更小的数。这种方法在n能被2至9的数字完全分解时适用,但如果n包含大于9的质因数,这种方法就不适用,因为这时无法将n完全分解为2至9之间的因数。
🦆
如果n是一个质数,比如11,题解中的算法会怎么处理?
如果n是一个质数,比如11,算法将无法找到2至9之间的任何数字来整除n。在这种情况下,n在尝试被所有的因数整除后仍然保持不变,即为11。因此,算法在最后检查是否n=1时发现n仍然大于1,因此返回'-1'。这表明11不能被分解为2至9的任何组合的乘积,因此无法得到一个有效的结果。

相关问题