• LeetCode 1711. 大餐计数 做题小结


    题目

    大餐 是指 恰好包含两道不同餐品 的一餐,其美味程度之和等于 2 的幂。
    
    你可以搭配 任意 两道餐品做一顿大餐。
    
    给你一个整数数组 deliciousness ,其中 deliciousness[i] 是第 i​​​​​​​​​​​​​​ 道餐品的美味程度,返回你可以用数组中的餐品做出的不同 大餐 的数量。结果需要对 109 + 7 取余。
    
    注意,只要餐品下标不同,就可以认为是不同的餐品,即便它们的美味程度相同。
    
     
    
    示例 1:
    
    输入:deliciousness = [1,3,5,7,9]
    输出:4
    解释:大餐的美味程度组合为 (1,3) 、(1,7) 、(3,5) 和 (7,9) 。
    它们各自的美味程度之和分别为 4 、8 、8 和 16 ,都是 2 的幂。
    示例 2:
    
    输入:deliciousness = [1,1,1,3,3,3,7]
    输出:15
    解释:大餐的美味程度组合为 3 种 (1,1) ,9 种 (1,3) ,和 3 种 (1,7) 。
     
    
    提示:
    
    1 <= deliciousness.length <= 105
    0 <= deliciousness[i] <= 220
    
    

    解题思路与算法

    一. 暴力解法

    显然,此题可以通过暴力解法解决:双层for循环找到所有满足要求的两数之和,并统计次数。时间复杂度为O(n^2), 超时。

    二. 哈希表记录数字出现次数

    通过暴力解法我们可以发现,在查找两数之和的第二个数时,用了O(n)时间(遍历整个数组)。又由于我们只关心次数,而并非具体的哪两个数,所以我们可以用哈希表记录数字与其出现次数,这样可以把查找时间优化到O(1)。注意到此题的输入限制,数字最大为2^20,所以我们可以在有限的空间枚举。代码如下:

       public int countPairs(int[] deliciousness) {
           Map<Integer, Integer> map = new HashMap<>();
           int mod = 1000000007;
           int answer = 0;
           int length = deliciousness.length;
           for (int num : deliciousness) {
               int powerOfTwo = 1;
               // 为什么是21? 因为数字最大为2^20, 2^20 + 2^20 = 2^21为可能的最大值,不可能再大啦!
               for (int i = 0; i <= 21; i++) {
                   if (powerOfTwo >= num && map.containsKey(powerOfTwo - num)) {
                       answer += map.get(powerOfTwo - num);
                       answer %= mod;
                   }
                   powerOfTwo *= 2;
               }
               map.put(num, map.getOrDefault(num, 0) + 1);
           }
           return (int)answer;
       }
    

    参考:https://leetcode-cn.com/problems/count-good-meals/solution/onshi-jian-fu-za-du-jie-fa-liang-shu-zhi-v0fo/

  • 相关阅读:
    HDU 5818 Joint Stacks
    HDU 5816 Hearthstone
    HDU 5812 Distance
    HDU 5807 Keep In Touch
    HDU 5798 Stabilization
    HDU 5543 Pick The Sticks
    Light OJ 1393 Crazy Calendar (尼姆博弈)
    NEFU 2016省赛演练一 I题 (模拟题)
    NEFU 2016省赛演练一 F题 (高精度加法)
    NEFU 2016省赛演练一 B题(递推)
  • 原文地址:https://www.cnblogs.com/nmydt/p/14256310.html
Copyright © 2020-2023  润新知