java 位运算取8位_征战----位运算

1 根据数字二进制下 1 的数目排序

2 最大值

3 翻转数位

4 多数元素

5 丢失的数字

6 2的幂

7 二进制链表转数字

8 整数数组的子集

9 数组中两个数的最大异或值

10 串联字符串的最大长度

11 只出现一次的数字-3

12 比特位计数

13 判断1的个数

14 颠倒给定的32位无符号整数的二进制位

15 比特位计数

1

给你一个整数数组 arr 。请你将数组中的元素按照其二进制表示中数字 1 的数目升序排序 如果存在多个数字二进制中 1 的数目相同,则必须将它们按照数值大小升序排列。

请你返回排序后的数组。

输入:arr = [0,1,2,3,4,5,6,7,8]

输出:[0,1,2,4,8,3,5,6,7]

解释:[0] 是唯一一个有 0 个 1 的数。

[1,2,4,8] 都有 1 个 1 。

[3,5,6] 有 2 个 1 。

[7] 有 3 个 1 。

按照 1 的个数排序得到的结果数组为 [0,1,2,4,8,3,5,6,7]

function sortByBits(arr) {
  function countBits(n) {
    let count = 0;
    while (n != 0) {  // 转二进制的操作
      count += n & 1; // 是1就+1,是0就+0 
      n >>= 1;	      // 即,除以2
    }
    return count;
  }
  return arr.sort((a, b) => { // 如果有差,则按bits数排,如果无差,则按原值排
    return countBits(a) - countBits(b) || a - b;
  });
}
链接:https://leetcode-cn.com/problems/sort-integers-by-the-number-of-1-bits/solution/fu-xi-wei-yun-suan-fu-1356-gen-ju-shu-zi-er-jin-zh/

2

编写一个方法,找出两个数字ab中最大的那一个。不得使用if-else或其他比较运算符。

示例:

9db1958bb328ef0a8f4b42c7e277b52b.png
输入: a = 1, b = 2
输出: 2
var maximum = function(a, b) {          
    return ((Math.abs(a-b) + a + b)/2);
};

链接:https://leetcode-cn.com/problems/maximum-lcci/solution/li-yong-shu-xue-si-wei-de-fang-fa-by-nhan/

3

给定一个32位整数 num,你可以将一个数位从0变为1。请编写一个程序,找出你能够获得的最长的一串1的长度。

示例 1:

输入: num = 1775(110111011112)

输出: 8

示例 2:力扣示例 2:

输入: num = 7(01112)

输出: 4

 int l=0,r=0,Max=0;//以0为分界点,L是0左边连续1的数量,R是0右边连续1的数量,Max记录最大值
    for(int i=0;i<32;i++){
        if(num&1) r++; 
        else l=r+1,r=0; //当遇见0时, 0的左边连续1的数量等于上一个0右边连续1的数量加一(0本身反转后算一个长度)
        Max=max(l+r,Max); 
        num>>=1;
    }
    return Max;

链接:https://leetcode-cn.com/problems/reverse-bits-lcci/solution/10xing-dai-ma-jie-jue-by-123-405/

4

给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。你可以假设数组是非空的,并且给定的数组总是存在多数元素。

示例 1:

输入: [3,2,3]
输出: 3

示例 2:

输入: [2,2,1,1,1,2,2]
输出: 2
const majorElement = function(nums){
  var major = 0
  var count = 0
  for(var i=0;i<nums.length;i++){
    if(count===0){
      major = nums[i]
    }
    if(major == nums[i]){
      count +=1
    } else {
      count -=1
    }
  }
  return major
}
console.log(majorElement([3,2,3,4,4,4]))

5

给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的

输入:nums = [3,0,1]

输出:2

解释:n = 3,因为有 3 个数字,所以所有的数字都在范围 [0,3] 内。2 是丢失的数字,因为它没有出现在 nums 中。

示例 2:

输入:nums = [0,1]

输出:2

解释:n = 2,因为有 2 个数字,所以所有的数字都在范围 [0,2] 内。2 是丢失的数字,因为它没有出现在 nums 中。

示例 3:

输入:nums = [9,6,4,2,3,5,7,0,1]

输出:8

解释:n = 9,因为有 9 个数字,所以所有的数字都在范围 [0,9] 内。8 是丢失的数字,因为它没有出现在 nums 中。

示例 4:

输入:nums = [0]

输出:1

解释:n = 1,因为有 1 个数字,所以所有的数字都在范围 [0,1] 内。1 是丢失的数字,因为它没有出现在 nums 中。

class Solution:
    def missingNumber(self, nums: List[int]) -> int:
        nums.sort()
        left = 0
        right = len(nums)
        while left < right:
            mid = left + (right - left) // 2
            if nums[mid] > mid:
                right = mid 
            else:
                left = mid + 1
        return left

作者:powcai
链接:https://leetcode-cn.com/problems/missing-number/solution/er-fen-fa-qiu-he-wei-yun-suan-by-powcai/

6

2的幂

输入: 1 输出: true 解释: 20 = 1

const computeCount = function (n){
  return (n > 0) && (n & (n - 1)) == 0
}
console.log(computeCount(16))

7

二进制链表转数字

给你一个单链表的引用结点 head。链表中每个结点的值不是 0 就是 1。已知此链表是一个整数数字的二进制表示形式。

请你返回该链表所表示数字的 十进制值 。

输入:head = [1,0,1]
输出:5
解释:二进制数 (101) 转化为十进制数 (5)
示例 2:
输入:head = [0]
输出:0
示例 3:
输入:head = [1]
输出:1
var getDecimalValue = function(head) {
    ret = 0;
    while(head){
        ret = ret << 1;
        ret += head.val;
        head = head.next;
    }
    return ret;
};

链接:https://leetcode-cn.com/problems/convert-binary-number-in-a-linked-list-to-integer/solution/yong-wei-yi-yun-suan-by-jiong-zi-richard/

8

给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

力扣 说明:解集不能包含重复的子集。示例:

输入: nums = [1,2,3]
输出:
[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]
const subsets = (nums) => {
  const res = [];

  const dfs = (index, list) => {
    if (index == nums.length) { // 指针越界
      res.push(list.slice());   // 加入解集
      return;                   // 结束当前的递归
    }
    list.push(nums[index]); // 选择这个数
    dfs(index + 1, list);   // 基于该选择,继续往下递归
    list.pop();             // 上面的递归结束,撤销该选择
    dfs(index + 1, list);   // 不选这个数,继续往下递归
  };

  dfs(0, []);
  return res;
};

const subsets = (nums) => {
  const res = [];

  const dfs = (index, list) => {
    res.push(list.slice());     // 进入子递归前加入解集
    for (let i = index; i < nums.length; i++) { // 枚举出所有可选的数
      list.push(nums[i]);       // 选这个数
      dfs(i + 1, list);         // 基于选这个数,继续递归,传入的是i+1不是index+1
      list.pop();               // 撤销选这个数
    }
  };

  dfs(0, []);
  return res;
};
链接:https://leetcode-cn.com/problems/subsets/solution/shou-hua-tu-jie-zi-ji-hui-su-fa-xiang-jie-wei-yun-/

9

数组中两个数的最大异或值

给定一个非空数组,数组中元素为 a0, a1, a2, … , an-1,其中 0 ≤ ai < 231 。

找到 ai 和aj 最大的异或 (XOR) 运算结果,其中0 ≤ i,  j < n 。

你能在O(n)的时间解决这个问题吗?

示例:

输入: [3, 10, 5, 25, 2, 8]

输出: 28

解释: 最大的结果是 5 ^ 25 = 28.

链接:https://leetcode-cn.com/problems/maximum-xor-of-two-numbers-in-an-array
/**
 * @param {number[]} nums
 * @return {number}
 */
var findMaximumXOR = function(nums) {
    // 获取最大数的二进制长度,因为数字大二进制越长
    // 测试数据中25最大,二进制11001长度为5,要计算是否最终能异或到11111
    let L = Math.max(...nums).toString(2).length;

    // max是在计算后能得到的最大值,maxCur是每一轮理想状态能达到的最大值
    // 例如,第一轮max=0,maxCur=1
    // 假设第一轮计算后max首位是1,第二轮max计算前先左移成10,maxCur设置为11
    // 每次cur都将max左移后最后一位置为1,因为它就是一个寻求最大值的变量,
    // 如果确实能够得到maxCur则赋值给max后退出循环进行下一轮
    let max = 0,maxCur; 

    // 存储前缀,1,10,110等,每一次存储每一个数的前缀且位数从小到大
    // 每次计算前要清空
    // 如果不用Set就会超时,因为后面有一个查找数组里面是否包含异或后的结果
    // 用Set去重后就不会超时
    let prefix = new Set();
    for(let i = L-1;i>-1;i--){

        // max左移
        max <<= 1;
        // 上面左移一位后最后一位是0,把它设为1就是表示当前位数的最大值,后面就是计算是否能异或到,能就            重新赋值
        maxCur = max | 1;

        // 前缀数组置为空
        prefix.clear();

        // 按照例子来看,最长二进制位数为5,移动4位后就是在计算第5位,例如01001右移动4位就是0
        for(let num of nums) prefix.add(num >> i);

        for(let p of prefix){
            // 如果 a = b ^ maxCur,那么a ^ b = maxCur
            // 也就是如果数组里面含有当前迭代的值与maxCur异或的结果,
            // 那就说明数组里面有两个数异或后得到maxCur
            if(prefix.has(p ^ maxCur)){
                // 如果真的能得到理想状态的maxCur,那就赋值给max
                max = maxCur;
            }
        }
    }
    return max;
};

链接:https://leetcode-cn.com/problems/maximum-xor-of-two-numbers-in-an-array/solution/gen-ju-guan-fang-de-si-lu-yong-jsxie-quan-cheng-su/

10

串联字符串的最大长度
给定一个字符串数组 arr,字符串 s 是将 arr 某一子序列字符串连接所得的字符串,如果 s 中的每一个字符都只出现过一次,那么它就是一个可行解。
请返回所有可行解 s 中最长长度。
示例 1:
输入:arr = ["un","iq","ue"]
输出:4
解释:所有可能的串联组合是 "","un","iq","ue","uniq" 和 "ique",最大长度为 4。
示例 2:
输入:arr = ["cha","r","act","ers"]
输出:6
解释:可能的解答有 "chaers" 和 "acters"。
示例 3:
输入:arr = ["abcdefghijklmnopqrstuvwxyz"]
输出:26
链接:https://leetcode-cn.com/problems/maximum-length-of-a-concatenated-string-with-unique-characters

11

给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。

示例 :

输入: [1,2,1,3,2,5]
输出: [3,5]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/single-number-iii
/**
 * @param {number[]} nums
 * @return {number[]}
 */
var singleNumber = function(nums) {
    const len = nums.length
    const map = new Map()
    const res = []
    for (let i = 0; i < len; i++) {
        const num = nums[i]
        if (map.has(num)) {
            map.delete(num) 
        } else {
            map.set(num, 1)
        }
    }
    map.forEach((val, key) => {
        res.push(key)
    })
    return res
};

作者:catboy
链接:https://leetcode-cn.com/problems/single-number-iii/solution/javascript-shi-yong-map-by-catboy-3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

12 比特位计数

给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。
示例 1:
输入: 2
输出: [0,1,1]
示例 2:
输入: 5
输出: [0,1,1,2,1,2]

var countBits = function(num) {
    let result = [0];
    let n = 1;
    while(n <= num){
        let count = 0;
        let mask = 1;
        for(let i = 0;i < 32;i++){
            if((n & mask) != 0){
                count++;
            }
            mask <<= 1;
        }
        n++;
        result.push(count);
    }
    return result;
};

作者:Alexer-660
链接:https://leetcode-cn.com/problems/counting-bits/solution/338-bi-te-wei-ji-shu-by-alexer-660/

13

判断1的个数

输入:00000000000000000000000000001011

输出:3

解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。

var hammingWeight = function(n) {
    let sum = 0
    while(n != 0){
        sum++
        n = n&(n-1)
    }
    return sum
};

var hammingWeight = function(n) {
    let count = 0;
    while(n){
        // n % 2 == 1
        if(n & 1 == 1){
            count++;
        }
        n >>>= 1;
    }
    return count;
};


链接:https://leetcode-cn.com/problems/number-of-1-bits/solution/191-wei-1de-ge-shu-by-alexer-660/

14

颠倒给定的32位无符号整数的二进制位

var reverseBits = function (n) {
  let ans = 0
  for(let i = 0;i < 32; i++){
    ans = (ans << 1) + (n & 1)
    n >>= 1
  }
  return ans >>> 0
}

15

比特位计数

输入 2
输出:[0,1,1]
输入 5
输出: [0,1,1,2,1,2]
var countBits = function(num) {
    let res = [0,1,1];
    for(let i = 3; i<=num;++i){
        res[i] = res[i>>1]+i%2;
    }
    return res.slice(0,num+1);
};

链接:https://leetcode-cn.com/problems/counting-bits/solution/dp-by-yhh-3/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值