在本篇文章里小编给大家整理的是一篇关于php计算汉明距离总和的实例讲解内容,有需要的朋友们可以跟着学习参考下。

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

计算一个数组中,任意两个数之间汉明距离的总和。

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

注意:

数组中元素的范围为从 0到 10^9。数组的长度不超过 10^4。

解题思路

穷举两两组合的数量,然后累加汉明距离,这个是最简单直白的方案。

结果是大量数据的时候会超时,阶乘的数量太多。

  1. class Solution {
  2. /**
  3. * @param Integer[] $nums
  4. * @return Integer
  5. */
  6. function totalHammingDistance($nums) {
  7. $count = count($nums);
  8. $sum = 0;
  9. for ($i = 0; $i < $count - 1; $i++) {
  10. for ($j = $i+1; $j < $count; $j++)
  11. {
  12. $sum += $this->hm($nums[$i], $nums[$j]);
  13. }
  14. }
  15. return $sum;
  16. }
  17. // 汉明距离方法
  18. function hm($x, $y)
  19. {
  20. return substr_count(decbin($x ^ $y), '1');
  21. }}

思路扩展:

解题思路扩展

咱们常常会这样分析问题:最简单的状况 -> 通常的、复杂的状况。以前咱们是:遍历全部可能的两两组合。

如今咱们换一个角度看:若是int只有1位-> int有32位。leetcode

首先,若是 int 只有 1 位,即数组 nums 中的元素只有两种状况,0 或者 1,此时求汉明距离总和的步骤以下:get

首先将数组分红两组,全 0 位一组,全 1 位一组

将两组数两两组合,记一个为a,一个为b

若是 a、b 均来自 0 那一组,或者均来自 1 那一组,此时不会有汉明距离产生。可是若是 a、b 一个来自 0 那一组,另一个来自1那一组,这时将会产生汉明距离

假设 nums 数组元素个数为 n,其中 0 元素个数为 k,则 1 元素的个数为 n-k,则上一步可以产生汉明距离的总和就是k*(n-k)

k*(n-k) 就是 int 只有 1 位的状况下的汉明距离总和

若是将 int 的位数从 1 位扩展到 32 位,那么就是将遍历每一位,而后求出在这一位上的汉明距离和,累加到一块儿,这样能够将算法复杂度从 $O(N^2)$ 下降到 $O(32\times N)$,即为 $O(N)$。

能够看下面这个例子:

十进制 二进制

4: 0 1 0 0

14: 1 1 1 0

2: 0 0 1 0

1: 0 0 0 1

先看最后一列,有三个 0 和一个 1,那么它们之间相互的汉明距离就是 3,即 1 和其余三个 0 分别的距离累加,而后在看第三列,累加汉明距离为 4,由于每一个 1 都会跟两个 0 产生两个汉明距离,同理第二列也是 4,第一列是 3。各列相互之间两两组合的汉明距离总和就是各列 0 的个数与 1 的个数之和,把各列汉明距离总和再累加就是题目所求的数组 nums 元素两两之间的汉明距离总和。

代码

  1. class Solution {
  2. /**
  3. * @param Integer[] $nums
  4. * @return Integer
  5. */
  6. function totalHammingDistance($nums) {
  7. $count = count($nums);
  8. $sum = 0;
  9. for($i = 0; $i < 32; $i++)
  10. {
  11. $tmpCount = 0;
  12. for($j = 0; $j < $count; $j++)
  13. $tmpCount += ($nums[$j] >> $i) & 1;
  14. }
  15. $sum += $tmpCount * ($count - $tmpCount);
  16. }
  17. return $sum;
  18. }
  19. }

更多相关文章

  1. php回溯算法计算组合总和的实例代码
  2. 放大镜效果2 (这个有点问题)
  3. 放大镜效果
  4. Android开发UI布局必备基础知识
  5. Android多点触控(图片的缩放Demo)
  6. 一个SQL语句获得某人参与的帖子及在该帖得分总和
  7. android 中文 api (64) —— Scroller
  8. 基本布局之线性布局(LinearLayout)
  9. SQLSERVER 根据地图经纬度计算距离差示例

随机推荐

  1. Android缓存理解
  2. Android(安卓)frameworks中Bn*和Bp*的区
  3. Android系统启动流程 -- android
  4. Android笔记-2
  5. 配置并使用Android支持的库
  6. Android(安卓)向系统发送一条短信
  7. 理解 Android 消息机制
  8. Android 修改横屏角度为顺时针270度
  9. 【Android】注解框架(三)-- 编译时注解,手写
  10. Android分享文稿 ( by quqi99 )