leetcode
leetcode 751 ~ 800
重新排序得到 2 的幂

重新排序得到 2 的幂

难度:

标签:

题目描述

代码结果

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


/*
 * 思路:
 * 1. 首先我们需要生成2的幂的所有可能值,这些值应该在给定范围内(1 <= n <= 10^9)。
 * 2. 然后将每个2的幂转换为字符串并排序。
 * 3. 将给定的数字n转换为字符串并排序。
 * 4. 使用Java Stream API检查排序后的字符串是否与任何2的幂的排序字符串匹配。
 */
import java.util.stream.*;
public class Solution {
    public boolean reorderedPowerOf2(int n) {
        // 生成2的幂的排序字符串
        List<String> powerOf2Strings = IntStream.iterate(1, i -> i <= 1e9, i -> i * 2)
            .mapToObj(i -> {
                char[] chars = String.valueOf(i).toCharArray();
                Arrays.sort(chars);
                return new String(chars);
            }).collect(Collectors.toList());
        // 将n转换为排序字符串
        char[] nChars = String.valueOf(n).toCharArray();
        Arrays.sort(nChars);
        String sortedN = new String(nChars);
        // 检查是否匹配任何2的幂
        return powerOf2Strings.stream().anyMatch(s -> s.equals(sortedN));
    }
}

解释

方法:

该题解的思路是将给定的整数 n 转换为字符串,并对其字符进行排序。然后生成从 2^0 到 2^30 的所有 2 的幂,并对每个幂的字符进行排序。最后,检查排序后的 n 的字符是否与任何排序后的 2 的幂的字符相匹配。如果匹配,则返回 True,否则返回 False。

时间复杂度:

O(m log m),其中 m 是整数 n 的位数。

空间复杂度:

O(1)

代码细节讲解

🦆
为什么选择2^0到2^30的范围生成2的幂?这个范围是否覆盖了所有可能的n值?
选择2^0到2^30的范围是因为这个范围足以覆盖所有32位整数的可能值。2^30是1073741824,略大于10^9,而32位整数的最大值是2147483647。因此,这个范围确保了所有可能的10位数或更少位数的数字都被覆盖。这个范围确实覆盖了所有可能的n值,因为在这个范围内的2的幂已经包括了所有位数可能的排列形式。
🦆
在比较排序后的字符时,是否考虑了由于数字重复导致的多种排列的情况?
在这个算法中,通过对数字的字符进行排序来比较,实际上已经考虑了数字重复导致的多种排列情况。排序操作将数字的所有字符按照字典序排列,因此不同的排列方式如果拥有相同的字符集合,则排序后的结果将是相同的。这意味着即使数字中的某些字符重复,排序后的相等性检查仍然有效。
🦆
为什么在这个算法中,使用字符串排序而不是其他方法来判断能否重新排列成2的幂?
使用字符串排序的方法是因为它简单且易于实现。这种方法通过将数字转换为字符串,然后对字符进行排序,可以直接比较两个数字是否具有相同的字符组合,而不必考虑它们的原始顺序。这种方法避免了需要考虑所有可能的字符排列组合,从而提高了算法的效率。其他方法如生成所有可能的排列则计算量大得多,效率较低。
🦆
该算法在处理数字中包含前导零的情况时是如何处理的?例如输入为100。
在这个算法中,输入数字首先被转换为字符串,如果数字中包含前导零(例如格式化或某些形式的输入错误),这些零会在转换为字符串后存在。然而,由于算法涉及到对字符串的字符进行排序,排序操作会将所有字符(包括零)按照字典序重新排列。因此,前导零在排序后的结果中不会以前导形式出现,从而不影响最终的比较。例如,'100'排序后变为'001',进一步排序变为'010',这与'2^3=8'(排序后为'008'或'080'或'800')不匹配。

相关问题