leetcode - 位运算题目汇总(上)

2015-09-10 23:06:00  浏览:2019  作者:管理员

最近在看位运算的知识,十分感叹于位运算的博大精深,正好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 00 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;// thena ^ 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;};

评论区

共 0 条评论
  • 这篇文章还没有收到评论,赶紧来抢沙发吧~

【随机新闻】

返回顶部