应用乘法原理统计集合元素组合个数 |周末学习

简介: 应用乘法原理统计集合元素组合个数 |周末学习

网络异常,图片无法展示
|


题目描述



这是 LeetCode 上的 477. 汉明距离总和 ,难度为 中等


Tag : 「位运算」、「数学」


两个整数的 汉明距离 指的是这两个数字的二进制数对应位不同的数量。


给你一个整数数组 nums,请你计算并返回 nums 中任意两个数之间汉明距离的总和。

 

示例 1:


输入:nums = [4,14,2]
输出:6
解释:在二进制表示中,4 表示为 0100 ,14 表示为 1110 ,2表示为 0010 。(这样表示是为了体现后四位之间关系)
所以答案为:
HammingDistance(4, 14) + HammingDistance(4, 2) + HammingDistance(14, 2) = 2 + 2 + 2 = 6
复制代码


示例 2:


输入:nums = [4,14,4]
输出:4
复制代码


提示:


1 <= nums.length <= $10^5$
0 <= nums[i] <= $10^9$
复制代码


按位统计



我们知道,汉明距离为两数二进制表示中不同位的个数,同时每位的统计是相互独立的。


即最终的答案为 \sum_{x = 0}^{31} calc(x)x=031calc(x),其中 calccalc 函数为求得所有数二进制表示中的某一位 xx 所产生的不同位的个数。


我们考虑某个 cacl(x)cacl(x) 如何求得:


事实上,对于某个 nums[i] 我们只关心在 nums 中有多少数的第 xx 位的与其不同,而不关心具体是哪些数与其不同,同时二进制表示中非 0011


这指导我们可以建立两个集合 s0s0s1s1,分别统计出 nums 中所有数的第 xx 位中 00 的个数和 11 的个数,集合中的每次计数代表了 nums 中的某一元素,根据所在集合的不同代表了其第 xx 位的值。那么要找到在 nums 中有多少数与某一个数的第 xx 位不同,只需要读取另外一个集合的元素个数即可,变成了 O(1)O(1) 操作。那么要求得「第 xx 位所有不同数」的对数的个数,只需要应用乘法原理,将两者元素个数相乘即可。


网络异常,图片无法展示
|


前面说到每位的统计是相对独立的,因此只要对「每一位」都应用上述操作,并把「每一位」的结果累加即是最终答案。


代码:


class Solution {
    public int totalHammingDistance(int[] nums) {
        int ans = 0;
        for (int x = 31; x >= 0; x--) {
            int s0 = 0, s1 = 0;
            for (int u : nums) {
                if (((u >> x) & 1) == 1) {
                    s1++;
                } else {
                    s0++;
                }  
            }
            ans += s0 * s1;
        }
        return ans;
    }
}
复制代码


  • 时间复杂度:O(C * n)O(Cn)CC 固定为 3232
  • 空间复杂度:O(1)O(1)


最后



这是我们「刷穿 LeetCode」系列文章的第 No.477 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先将所有不带锁的题目刷完。


在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。


为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:github.com/SharingSour…


在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。

相关文章
|
16天前
|
算法 JavaScript 测试技术
【数学】【组合数学】1830. 使字符串有序的最少操作次数
【数学】【组合数学】1830. 使字符串有序的最少操作次数
|
2月前
|
算法 测试技术 C++
【动态规划】【前缀和】【数学】2338. 统计理想数组的数目
【动态规划】【前缀和】【数学】2338. 统计理想数组的数目
|
3月前
|
算法 测试技术 C#
【数学】LeetCode1526: 形成目标数组的子数组最少增加次数
【数学】LeetCode1526: 形成目标数组的子数组最少增加次数
|
5月前
|
算法
代码随想录算法训练营第二十六天 | LeetCode 39. 组合总和、40. 组合总和 II、131. 分割回文串
代码随想录算法训练营第二十六天 | LeetCode 39. 组合总和、40. 组合总和 II、131. 分割回文串
30 0
|
6月前
代码随想录Day22 LeetCode T39 组合总和 T40 组合总和II T131 分割回文串
代码随想录Day22 LeetCode T39 组合总和 T40 组合总和II T131 分割回文串
19 0
|
6月前
数列中,第一项为3,后一项都比前一项的值增5。下列给定程序中,函数fun的功 能是:计算前n(4≤n≤50)项的累计和。在累加过程中把那些被4除后余2的当前累 加值放入数组中
数列中,第一项为3,后一项都比前一项的值增5。下列给定程序中,函数fun的功 能是:计算前n(4≤n≤50)项的累计和。在累加过程中把那些被4除后余2的当前累 加值放入数组中
|
10月前
|
存储 Python
Python实现划分数组为连续数字的集合
Python实现划分数组为连续数字的集合
76 0
|
10月前
|
算法 Java 网络架构
代码随想录训练营day27| 39. 组合总和 40.组合总和II 131.分割回文串
代码随想录训练营day27| 39. 组合总和 40.组合总和II 131.分割回文串
|
10月前
|
存储 算法 前端开发
前端算法-除自身外数组的乘积
前端算法-除自身外数组的乘积
|
Scala 开发者
集合化简介绍和案例 | 学习笔记
快速学习集合化简介绍和案例
143 0
集合化简介绍和案例 | 学习笔记