leetcode
leetcode 1551 ~ 1600
大餐计数

大餐计数

难度:

标签:

题目描述

代码结果

运行时间: 96 ms, 内存: 23.6 MB


/*
 * 题目思路:
 * 使用Java Stream和Collectors可以简洁地表达上面的算法。
 * 主要思路与上面相同,依然是使用HashMap来记录出现过的美味程度的次数。
 * 通过Stream的forEach遍历数组,并对每个元素计算其可能的美味程度之和,
 * 并检查这些和是否在哈希表中。
 * 最终结果依然需要对10^9+7取模。
 */
import java.util.HashMap;
import java.util.stream.IntStream;

public class Solution {
    public int countPairs(int[] deliciousness) {
        int MOD = 1000000007;
        HashMap<Integer, Integer> map = new HashMap<>();
        final int[] count = {0};

        IntStream.of(deliciousness).forEach(val -> {
            IntStream.rangeClosed(0, 21).forEach(i -> {
                int powerOfTwo = 1 << i;
                int complement = powerOfTwo - val;
                count[0] = (count[0] + map.getOrDefault(complement, 0)) % MOD;
            });
            map.put(val, map.getOrDefault(val, 0) + 1);
        });

        return count[0];
    }
}

解释

方法:

本题解使用哈希表记录每个美味程度的出现次数,然后针对每个可能的美味程度组合,计算它们的和是否是2的幂。为了快速判断和是否是2的幂,算法首先对美味程度进行排序,然后使用一个循环,其中外层循环遍历每个不同的美味程度,内层循环则尝试匹配使得两个美味程度之和达到下一个2的幂。如果当前的美味程度与其匹配的美味程度相同,则需要使用组合数计算方式计算配对数目。这种方法利用了数学的组合逻辑以及哈希表的高效性能来解决问题。

时间复杂度:

O(n log n)

空间复杂度:

O(n)

代码细节讲解

🦆
在题解中提到使用哈希表来计数每个美味程度的出现次数,请问这种方法在处理大量重复值时的效率如何?
使用哈希表来计数每个美味程度的出现次数在处理大量重复值时非常高效。哈希表(通常在Python中实现为字典)提供了平均O(1)时间复杂度的插入和查找操作。因此,当输入数据中存在大量重复项时,哈希表可以快速统计每个项的出现次数,不需要多次遍历整个数据集来计数,这大大提高了数据处理的速度。
🦆
题解提到了对美味程度进行排序,然后使用双循环来找到和为2的幂的美味程度组合,为什么选择排序这一步是必要的?
对美味程度进行排序是必要的,因为这样可以更高效地寻找和为2的幂的组合。排序后,可以使用双指针或者二分搜索的方法来查找目标和,而不必对每个可能的组合进行遍历。此外,排序后的美味程度数组可以帮助算法快速跳过那些不可能满足条件的组合,从而减少不必要的计算和比较。
🦆
题解中提到,当两个美味程度相同时,使用组合数计算方式来计算配对数目。能否详细解释这是如何实现的,以及在什么情况下需要这样处理?
当两个美味程度相同的时候,我们需要计算这个程度值的项与自身配对的组合数。组合数可以通过数学公式C(n, 2) = n*(n-1)/2来计算,其中n是该美味程度的出现次数。这是因为每对不同的项都可以形成一个有效的配对。例如,如果一个美味程度出现了3次,那么可以形成3*(3-1)/2 = 3种不同的配对。这种情况通常出现在美味程度的值与目标2的幂相等时,因为只有美味程度相等的情况下,两者之和才会等于一个2的幂。
🦆
题解中没有详细说明如何快速计算组合数,并对结果进行模运算(MOD = 1000000007)。在实现这一点时应注意哪些编程细节?
在计算组合数并进行模运算时,应注意以下几点编程细节:首先,当计算组合数C(n, 2) = n*(n-1)/2时,为了避免在乘法操作中产生溢出,应该先对n和(n-1)中的至少一个数进行MOD运算。其次,由于MOD是一个很大的质数,可以使用费马小定理来计算除法的模逆元,以便在模运算的环境下执行除法。此外,在实际编程实现中,还应当注意整数除法可能引入的舍入误差,确保所有的运算都在整数域中进行。

相关问题