最近在看位运算的知识,十分感叹于位运算的博大精深,正好leetcode有 Bit Manipulation 的专题,正好拿来练练手。

Subsets


给出一个由不同的数字组成的数组,枚举它的子数组(子集)。

这道题我之前用递归解过,而且效率还不错(beat 83.33%),解法如下不加详述了:

/**
 * @param {number[]} nums
 * @return {number[][]}
 */

var ans, res, len;

function dfs(index, nums) {
  ans.push(res.concat());

  for (var i = index; i < len; i++) {
    res.push(nums[i]);
    dfs(i + 1, nums);
    res.pop();
  }
}

var subsets = function(nums) {
  nums.sort(function(a, b) {
    return a - b;
  });

  ans = [],
  res = [],
  len = nums.length;

  dfs(0, nums);

  return ans;
};

如果用位运算解,这是一道经典的枚举子集

比如我们有数组[1, 2, 3],还是要用到标志位的概念,全集为1 1 1,全集表示都取,它的子集有1 0 11 1 01 0 0等等,我们通过枚举子集,然后再通过子集获取原来数组的元素即可。

比如子集 1 0 1,我们可以依次获取最右边的1,然后根据获取的1的大小判断数组元素的index位置从而获取数组,之后把该1置为0即可。

/**
* @param {number[]} nums
* @return {number[][]}
*/
var subsets = function(nums) {
  nums.sort(function(a, b) {
    return a - b;
  });

  var all = (1 << nums.length) - 1
    , ans = [];

  // 枚举子集
  for (i = all; i; i = (i - 1) & all) {
    var tmp = i
      , res = [];

    while (tmp) {
      var rightMostOne = tmp & (-tmp)
        , index = Math.log(rightMostOne) / Math.log(2);

      res.push(nums[index]);
      tmp = tmp & (tmp - 1);
    }

    ans.push(res);
  }

  // 子集的枚举没有0,所以要special insert
  ans.push([]);
  return ans;
};

Power of Two


判断一个数是不是2的幂。如果一个数是2的幂,那么该数与上该数-1为0。我们以8举例:

1 0 0 0
0 1 1 1

很明显,上面两数做与运算的结果是0。但是有个特殊的情况是,0 & (0 - 1) === 0,所以我们还得判断该数为正。

/**
 * @param {number} n
 * @return {boolean}
 */
var isPowerOfTwo = function(n) {
  return (!(n & (n - 1)) && n > 0);
};

这里加强下,如果知道某数是2的幂,求解这个指数值。即Math.pow(2, x) = n ,求x的值。

也很简单,用个log的换底公式(其实没有涉及位运算):

return Math.log(n) / Math.IN2;

Missing Number


给出一个0~n组成的数组[0, 1, 2, 3 ... n],从中随即去掉一个数字,给你新的数组,求解被去掉的数字。比如给你[0, 1, 3],返回2

这题涉及^运算的性质:

// if
a ^ b = c;

// then
a ^ c = b;
b ^ c = a;

解法也就呼之欲出了。还是假设数组[0, 1, 3],我们可以知道n为3(等于数组长度),从而可以计算出0 ^ 1 ^ 2 ^ 3的值,我们把它赋值给c;然后我们计算所给数组的元素的异或值,赋值给a,假设被舍弃的元素为b,我们可以得到如下等式:

a ^ b = c;

根据前边所讲:

b = a ^ c;

完整代码:

/**
 * @param {number} n
 * @return {boolean}
 */
/**
 * @param {number[]} nums
 * @return {number}
 */
var missingNumber = function(nums) {
  var a = nums.reduce(function(pre, item) {
    return pre ^ item;
  });

  var b = nums.reduce(function(pre, item, index) {
    return pre ^ index;
  }, nums.length);

  return a ^ b;
};

leetcode - 位运算题目汇总(上)的更多相关文章

  1. leetcode - 位运算题目汇总(下)

    接上文leetcode - 位运算题目汇总(上),继续来切leetcode中Bit Manipulation下的题目. Bitwise AND of Numbers Range 给出一个范围,[m, ...

  2. BitMap - leetcode [位运算]

    136. Single Number 因为A XOR A = 0,且XOR运算是可交换的,于是,对于实例{2,1,4,5,2,4,1}就会有这样的结果: (2^1^4^5^2^4^1) => ( ...

  3. All LeetCode Questions List 题目汇总

    All LeetCode Questions List(Part of Answers, still updating) 题目汇总及部分答案(持续更新中) Leetcode problems clas ...

  4. 78 leetCode 位运算解法

    按照自己的理解题目,数组内所有的组合:假如[1,2,3,4]看成1111到0000里面的排列组合,取位运算. vector<vector > subsets(vector&nums ...

  5. leetcode.位运算.136只出现一次的元素-Java

    1. 具体题目 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找出那个只出现了一次的元素. 说明:你的算法应该具有线性时间复杂度. 你可以不使用额外空间来实现吗? 示例 1 ...

  6. leetcode top 100 题目汇总

    首先表达我对leetcode网站的感谢,与高校的OJ系统相比,leetcode上面的题目更贴近工作的需要,而且支持的语言广泛.对于一些比较困难的题目,可以从讨论区中学习别人的思路,这一点很方便. 经过 ...

  7. leetcode 位运算异或

    1. 只出现一次的数字(136) 异或的性质总结: 相异为1,相同为0: a ^ a = 0; 0 ^ a = a; 如果 a ^ b = c 成立,那么a ^ c = b 与 b ^ c = a 均 ...

  8. JavaScript 位运算总结&拾遗

    最近补充了一些位运算的知识,深感位运算的博大精深,此文作为这个系列的总结篇,在此回顾下所学的位运算知识和应用,同时也补充下前文中没有提到的一些位运算知识. 把一个数变为大于等于该数的最小的2的幂 一个 ...

  9. 位运算总结&拾遗

    JavaScript 位运算总结&拾遗 最近补充了一些位运算的知识,深感位运算的博大精深,此文作为这个系列的总结篇,在此回顾下所学的位运算知识和应用,同时也补充下前文中没有提到的一些位运算知识 ...

随机推荐

  1. 因GIT默认忽略.dll文件导致的Visual Studio项目通过Bamboo编译失败

    背景 由GIT管理的Visual Studio项目,使用Stash管理远端代码库,通过与Stash集成的Bamboo生成项目并发布 现象 Visual Studio项目本地生成成功,用SourceTr ...

  2. 不同Framework下StringBuilder和String的性能对比,及不同Framework性能比(附Demo)

    本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 文章是哥(mephisto)写的,SourceLink 阅读目录 介绍 环境搭建 测试用例 MSDN说明 ...

  3. Nginx 切片模块、断点续传

    熟悉 CDN 行业主流技术的朋友应该都比较清楚,虽然 Nginx 近几年发展的如日中天,但是基本上没有直接使用它自带的 proxy_cache 模块来做缓存的,原因有很多,例如下面几个: 不支持多盘 ...

  4. CentOS 7最小化安装后找不到‘ifconfig’命令——修复小提示

    如果你不知道在哪里可以找到ifconfig命令,请按照以下简单的步骤来找到它.首先,让我们找出哪个包提供了ifconfig命令.要完成这项任务,输入以下命令: [root@jrserver app_f ...

  5. linux基础-第八单元 正文处理命令及tar命令

    第八单元 正文处理命令及tar命令 使用cat命令进行文件的纵向合并 两种文件的纵向合并方法 归档文件和归档技术 归档的目的 什么是归档 tar命令的功能 tar命令的常用选项 使用tar命令创建.查 ...

  6. RabbitMQ与Redis队列对比

    本文仅针对RabbitMQ与Redis做队列应用时的情况进行对比具体采用什么方式实现,还需要取决于系统的实际需求 简要介绍 RabbitMQ RabbitMQ是实现AMQP(高级消息队列协议)的消息中 ...

  7. 使用数据库sqlite3 C语言实现登陆注册的功能

    //此代码为注册功能 void create_regtable() { int rc; //rc为返回值,判断函数是否执行成功 rc=0函数执行成功,rc !=0函数执行失败 sqlite3 *db; ...

  8. HDU 4866 Shooting(持久化线段树)

    view code//第二道持久化线段树,照着别人的代码慢慢敲,还是有点不理解 #include <iostream> #include <cstdio> #include & ...

  9. Android+Sqlite 实现古诗阅读应用(三)

    往期传送门: Android+Sqlite 实现古诗阅读应用(一) Android+Sqlite 实现古诗阅读应用(二) 加入截图分享的功能. 很多应用都有分享的功能,我也想在我的古诗App里加入这个 ...

  10. 三星s4宣传片配色有惊喜

    三星s4宣传片配色有惊喜据了解,一周前,三星曾对外发布了新旗舰手机galaxy s4的宣传视频,不过那份视频里所含信息仅仅只有s4发布会的邀请函.而日前,三星官方发布了s4的第二弹宣传片则暗示该机在配 ...