leetcode-位运算

231. 2的幂

给定一个整数,编写一个函数来判断它是否是 2 的幂次方。

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

示例 2:
输入: 16
输出: true
解释: 24 = 16

示例 3:
输入: 218
输出: false

class Solution 
{
public:
    bool isPowerOfTwo(int n) 
    {
        if (n <= 0) { return false; }
        if ((n & (n - 1)) == 0) { return true; }
        else { return false; }
    }
};

342. 4的幂

给定一个整数 (32 位有符号整数),请编写一个函数来判断它是否是 4 的幂次方。

示例 1:
输入: 16
输出: true

示例 2:
输入: 5
输出: false

进阶:
你能不使用循环或者递归来完成本题吗?

class Solution 
{
public:
    bool isPowerOfFour(int num) 
    {
        if (num <= 0) { return false; }
        if ((num & (num - 1)) == 0)
        {
            int res = 1;
            while (res < num) { res = res << 2; }
            if (res == num) { return true; }
            else { return false; }
        }
        else { return false; }
    }
};

面试题 05.01. 插入

插入。给定两个32位的整数N与M,以及表示比特位置的i与j。编写一种方法,将M插入N,使得M从N的第j位开始,到第i位结束。假定从j位到i位足以容纳M,也即若M = 10 011,那么j和i之间至少可容纳5个位。例如,不可能出现j = 3和i = 2的情况,因为第3位和第2位之间放不下M。

示例1:

输入:N = 10000000000, M = 10011, i = 2, j = 6
输出:N = 10001001100

示例2:

输入: N = 0, M = 11111, i = 0, j = 4
输出:N = 11111

class Solution {
public:
    int insertBits(int N, int M, int i, int j) {
        for(int k=i;k<=j;++k){
            if(N&(1<<k))N-=(1<<k);
        }
        return N+(M<<i);
    }
};

面试题 05.03. 翻转数位

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

示例 1:
输入: num = 1775(11011101111)
输出: 8

示例 2:
输入: num = 7(0111)
输出: 4

class Solution 
{
public:
    int reverseBits(int num) 
    {
        int count = 0, count_Pre = 0, max = 0;
        while (num)
        {
            if (num & 1) { ++count; }
            else
            {
                if (count + count_Pre + 1 > max) { max = count + count_Pre + 1; }
                count_Pre = count;
                count = 0;
            }
            num >>= 1;
        }
        if (count + count_Pre + 1 > max) { max = count + count_Pre + 1; }
        return max;
    }
};

面试题 05.06. 整数转换

整数转换。编写一个函数,确定需要改变几个位才能将整数A转成整数B。

示例1:
输入:A = 29 (或者0b11101), B = 15(或者0b01111)
输出:2

示例2:
输入:A = 1,B = 2
输出:2

提示:
A,B范围在[-2147483648, 2147483647]之间

class Solution 
{
public:
    int convertInteger(int A, int B) 
    {
        int result = 0;
        int height_A = long(A) & (0x80000000);
        int height_B = long(B) & (0x80000000);
        long a = long(A) & (0x7fffffff);
        long b = long(B) & (0x7fffffff);
        while (a || b) 
        {
            if ((a & 1) ^ (b & 1)) { ++result; }
            a = a >> 1;
            b = b >> 1;
        }
        if (height_A ^ height_B) { ++result; }
        return result;
    }
};

405. 数字转换为十六进制数

给定一个整数,编写一个算法将这个数转换为十六进制数。对于负整数,我们通常使用 补码运算 方法。
注意:
十六进制中所有字母(a-f)都必须是小写。
十六进制字符串中不能包含多余的前导零。如果要转化的数为0,那么以单个字符’0’来表示;对于其他情况,十六进制字符串中的第一个字符将不会是0字符。
给定的数确保在32位有符号整数范围内。
不能使用任何由库提供的将数字直接转换或格式化为十六进制的方法。

示例 1:
输入:
26
输出:
“1a”

示例 2:
输入:
-1
输出:
“ffffffff”
思路
int是32位二进制存储,转换成16进制就该有8位
每次让num向右移位4位,并和0xf(二进制的00000000 00000000 00000000 00001111)做与运算,即可得到本四位的十六进制表示。
由于负数右移动不能保证最终num==0,因此限制右移动的次数不超过8.

class Solution {
public:
    string toHex(int num) {
        if(num==0)  return "0";
        string hex = "0123456789abcdef";
        int resSize=0;//右移动的次数
        string res="";
        while(num && resSize<8)//32位转换成16进制就是八位
        {
            res = hex[num&0xf]+res;
            num>>=4;
            resSize++;
        }
        return res;
    }
};

面试题 17.01. 不用加号的加法

设计一个函数把两个数字相加。不得使用 + 或者其他算术运算符。
示例:
输入: a = 1, b = 1
输出: 2

提示:
a, b 均可能是负数或 0
结果不会溢出 32 位整数

class Solution 
{
public:
    int add(int a, int b) 
    {
        while (b != 0)
        {
            int sum = a ^ b;
            int carry = (unsigned int)(a & b) << 1;
            a = sum;
            b = carry;
        }
        return a;
    }
};

371. 两整数之和

不使用运算符 + 和 - ​​​​​​​,计算两整数 ​​​​​​​a 、b ​​​​​​​之和。
示例 1:
输入: a = 1, b = 2
输出: 3

示例 2:
输入: a = -2, b = 3
输出: 1

class Solution 
{
public:
    int getSum(int a, int b) 
    {
        while (b != 0)
        {
            int sum = a ^ b;
            int carry = (unsigned int)(a & b) << 1;
            a = sum;
            b = carry;
        }
        return a;
    }
};

268. 缺失数字

给定一个包含 0, 1, 2, …, n 中 n 个数的序列,找出 0 … n 中没有出现在序列中的那个数。

示例 1:
输入: [3,0,1]
输出: 2

示例 2:
输入: [9,6,4,2,3,5,7,0,1]
输出: 8

说明:
你的算法应具有线性时间复杂度。你能否仅使用额外常数空间来实现?

class Solution 
{
public:
    int missingNumber(vector<int>& nums) 
    {
        int missing = nums.size();
        for (int i = 0; i < nums.size(); ++i) { missing ^= i ^ nums[i]; }
        return missing;
    }
};

190. 颠倒二进制位

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

示例 1:
输入: 00000010100101000001111010011100
输出: 00111001011110000010100101000000
解释: 输入的二进制串 00000010100101000001111010011100 表示无符号整数 43261596,
因此返回 964176192,其二进制表示形式为 00111001011110000010100101000000。

示例 2:
输入:11111111111111111111111111111101
输出:10111111111111111111111111111111
解释:输入的二进制串 11111111111111111111111111111101 表示无符号整数 4294967293,
因此返回 3221225471 其二进制表示形式为 10111111111111111111111111111111 。

提示:
请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。
在 Java 中,编译器使用二进制补码记法来表示有符号整数。因此,在上面的 示例 2 中,输入表示有符号整数 -3,输出表示有符号整数 -1073741825。

class Solution 
{
public:
    uint32_t reverseBits(uint32_t n) 
    {
        uint32_t result = 0;
        int count = 31;
        while (n)
        {
            result += (n & 1) << count;
            n >>= 1;
            --count;
        }
        return result;
    }
};

693. 交替位二进制数

给定一个正整数,检查他是否为交替位二进制数:换句话说,就是他的二进制数相邻的两个位数永不相等。

示例 1:
输入: 5
输出: True
解释:
5的二进制数是: 101

示例 2:
输入: 7
输出: False
解释:
7的二进制数是: 111

示例 3:
输入: 11
输出: False
解释:
11的二进制数是: 1011

示例 4:
输入: 10
输出: True
解释:
10的二进制数是: 1010

class Solution 
{
public:
    bool hasAlternatingBits(int n) 
    {
        if (n == 1) { return true; }
        int res = n & 1;
        n = n >> 1;
        while (n!=0)
        {
            if ((n & 1) == res) { return false; }
            else 
           {
                res = n & 1;
                n = n >> 1;
           }
        }
        return true;
    }
};

389. 找不同

给定两个字符串 s 和 t,它们只包含小写字母。

字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母。

请找出在 t 中被添加的字母。

示例:
输入:
s = “abcd”
t = “abcde”

输出:
e

解释:
‘e’ 是那个被添加的字母。

class Solution 
{
public:
    char findTheDifference(string s, string t) 
    {
        int hash[26] = { 0 };
        for (int i = 0; i < s.size(); ++i) { hash[s[i] - 'a'] = hash[s[i] - 'a'] + 1; }
        for (int i = 0; i < t.size(); ++i)
        {
            hash[t[i] - 'a'] = hash[t[i] - 'a'] - 1;
            if (hash[t[i] - 'a'] == -1) { return t[i]; }
        }
        return 'a';
    }
};

169. 多数元素

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

示例 1:
输入: [3,2,3]
输出: 3

示例 2:
输入: [2,2,1,1,1,2,2]
输出: 2

class Solution
{
public:
    int majorityElement(vector<int>& nums)
    {
        if (nums.size() == 1) { return nums[0]; }
        unordered_map<int, int>nums_umap;
        for (int i = 0; i < nums.size(); ++i)
        {
            if (nums_umap.count(nums[i]))
            {
                ++nums_umap[nums[i]];
                if (nums_umap[nums[i]] > nums.size() / 2) { return nums[i]; }
            }
            else { nums_umap[nums[i]] = 1; }
        }
        return 0;
    }
};

面试题 17.04. 消失的数字

数组nums包含从0到n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗?
注意:本题相对书上原题稍作改动
示例 1:
输入:[3,0,1]
输出:2

示例 2:
输入:[9,6,4,2,3,5,7,0,1]
输出:8

class Solution 
{
public:
    int missingNumber(vector<int>& nums) 
    {
        int missing = nums.size();
        for (int i = 0; i < nums.size(); ++i) { missing ^= i ^ nums[i]; }
        return missing;
    }
};

784. 字母大小写全排列

给定一个字符串S,通过将字符串S中的每个字母转变大小写,我们可以获得一个新的字符串。返回所有可能得到的字符串集合。

示例:
输入: S = “a1b2”
输出: [“a1b2”, “a1B2”, “A1b2”, “A1B2”]

输入: S = “3z4”
输出: [“3z4”, “3Z4”]

输入: S = “12345”
输出: [“12345”]

注意:
S 的长度不超过12。
S 仅由数字和字母组成。

class Solution {
public:
    vector<string> letterCasePermutation(string S) {
        vector<string> result{S};
        for (int i = 0; i < S.size(); i++) {
            if (isupper(S[i])) {
                int size = result.size();
                for (int j = 0; j < size; j++) {
                    string temp = result[j];
                    temp[i] = tolower(temp[i]);
                    result.emplace_back(move(temp));
                }
            } else if (islower(S[i])) {
                int size = result.size();
                for (int j = 0; j < size; j++) {
                    string temp = result[j];
                    temp[i] = toupper(temp[i]);
                    result.emplace_back(move(temp));
                }
            }
        }
        return result;
    }
};

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

给你一个整数数组 arr 。请你将数组中的元素按照其二进制表示中数字 1 的数目升序排序。
如果存在多个数字二进制中 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]

示例 2:
输入:arr = [1024,512,256,128,64,32,16,8,4,2,1]
输出:[1,2,4,8,16,32,64,128,256,512,1024]
解释:数组中所有整数二进制下都只有 1 个 1 ,所以你需要按照数值大小将它们排序。

示例 3:
输入:arr = [10000,10000]
输出:[10000,10000]

示例 4:
输入:arr = [2,3,5,7,11,13,17,19]
输出:[2,3,5,17,7,11,13,19]

示例 5:
输入:arr = [10,100,1000,10000]
输出:[10,100,10000,1000]

提示:
1 <= arr.length <= 500
0 <= arr[i] <= 10^4

class Solution 
{ 
public:
    int get_oneNumber(int x)
    {
        int res = 0;
        while (x) { res += x & 1; x = x >> 1; }
        return res;
    }
    vector<int> sortByBits(vector<int>& arr) 
    {
        for (auto x : arr) { bit[x] = get_oneNumber(x); }
        sort(arr.begin(), arr.end(), [&](int x, int y) {return bit[x] == bit[y] ? x < y : bit[x] < bit[y]; });
        return arr;
    }
private:
    int bit[10010];
};

剑指 Offer 39. 数组中出现次数超过一半的数字

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。

示例 1:
输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2

限制:
1 <= 数组长度 <= 50000
注意:本题与主站 169 题相同:https://leetcode-cn.com/problems/majority-element/

class Solution 
{
public:
    int majorityElement(vector<int>& nums) 
    {
        if(nums.size()==1){return nums[0];}
        unordered_map<int, int>nums_umap;
        for (int i = 0; i < nums.size(); ++i)
        {
            if (nums_umap.count(nums[i])) 
            { 
                ++nums_umap[nums[i]]; 
                if (nums_umap[nums[i]] > nums.size() / 2) { return nums[i]; }
            }
            else { nums_umap[nums[i]] = 1; }
        }
        return 0;
    }
};

762. 二进制表示中质数个计算置位

给定两个整数 L 和 R ,找到闭区间 [L, R] 范围内,计算置位位数为质数的整数个数。

(注意,计算置位代表二进制表示中1的个数。例如 21 的二进制表示 10101 有 3 个计算置位。还有,1 不是质数。)

示例 1:
输入: L = 6, R = 10
输出: 4
解释:
6 -> 110 (2 个计算置位,2 是质数)
7 -> 111 (3 个计算置位,3 是质数)
9 -> 1001 (2 个计算置位,2 是质数)
10-> 1010 (2 个计算置位,2 是质数)

示例 2:
输入: L = 10, R = 15
输出: 5
解释:
10 -> 1010 (2 个计算置位, 2 是质数)
11 -> 1011 (3 个计算置位, 3 是质数)
12 -> 1100 (2 个计算置位, 2 是质数)
13 -> 1101 (3 个计算置位, 3 是质数)
14 -> 1110 (3 个计算置位, 3 是质数)
15 -> 1111 (4 个计算置位, 4 不是质数)

注意:
L, R 是 L <= R 且在 [1, 10^6] 中的整数。
R - L 的最大值为 10000。

class Solution 
{
public:
    int countPrimeSetBits(int L, int R) 
    {
        int result_count = 0;
        for (int i = L; i <= R; ++i)
        {
            int one_num = OneNum_Count(i);
            if (ifPrime(one_num)) { ++result_count; }
        }
        return result_count;
    }
private:
    int OneNum_Count(int n)
    {
        int count = 0;
        while (n)
        {
            ++count;
            n = n & (n - 1);
        }
        return count;
    }
    bool ifPrime(int n)
    {
        if (n == 1) { return false; }
        for (int i = 2; i <= sqrt(n); ++i)
        {
            if (n % i == 0) { return false; }
        }
        return true;
    }
};

191. 位1的个数

编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。

示例 1:
输入:00000000000000000000000000001011
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 ‘1’。

示例 2:
输入:00000000000000000000000010000000
输出:1
解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 ‘1’。

示例 3:
输入:11111111111111111111111111111101
输出:31
解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 ‘1’。

提示:
请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。
在 Java 中,编译器使用二进制补码记法来表示有符号整数。因此,在上面的 示例 3 中,输入表示有符号整数 -3。

class Solution 
{
public:
    int hammingWeight(uint32_t n) 
    {
        int result_count = 0;
        while (n != 0)
        {
            ++result_count;
            n = n & (n - 1);//n & (n-1):可以把从右边到左边的第 1个 1变成 0。
        }
        return result_count;
    }
};

476. 数字的补数

给定一个正整数,输出它的补数。补数是对该数的二进制表示取反。

示例 1:
输入: 5
输出: 2
解释: 5 的二进制表示为 101(没有前导零位),其补数为 010。所以你需要输出 2 。

示例 2:
输入: 1
输出: 0
解释: 1 的二进制表示为 1(没有前导零位),其补数为 0。所以你需要输出 0 。

注意:
给定的整数保证在 32 位带符号整数的范围内。
你可以假定二进制数不包含前导零位。
本题与 1009 https://leetcode-cn.com/problems/complement-of-base-10-integer/ 相同

class Solution 
{
public:
    int findComplement(int num) 
    {
        int32_t num_ = int32_t(num);
        int32_t count_ = num_&(0x7fffffff);
        int32_t heightest = num_ & (0x80000000);
        int32_t res = 1;
        while (count_)
        {
            num_ = num_ ^ res;
            res <<= 1;
            count_ >>= 1;
        }
        if (heightest) { num_ = heightest + num_; }
        return num_;
    }
};

面试题 05.07. 配对交换

配对交换。编写程序,交换某个整数的奇数位和偶数位,尽量使用较少的指令(也就是说,位0与位1交换,位2与位3交换,以此类推)。

示例1:
输入:num = 2(或者0b10)
输出 1 (或者 0b01)

示例2:
输入:num = 3
输出:3

提示:
num的范围在[0, 2^30 - 1]之间,不会发生整数溢出。

class Solution 
{
public:
    int exchangeBits(int num) 
    {
        uint64_t res = 1;
        uint64_t num_ = uint64_t(num);
        uint64_t num_cnt = num_;
        while (num_cnt)
        {
            uint64_t low = num_ & res;
            uint64_t up = num_ & (res << 1);
            num_ = num_ - (up + low) + ((up >> 1) + (low << 1));
            num_cnt = num_cnt << 3;
            res = res << 2;
        }
        return num_;
    }
};

136. 只出现一次的数字

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

说明:

你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 1:

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

示例 2:

输入: [4,1,2,1,2]
输出: 4

class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        number = 0
        for i in range(len(nums)):
            number = number ^ nums[i]
        return number

面试题 16.07. 最大数值

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

示例:
输入: a = 1, b = 2
输出: 2

class Solution {
public:
    int maximum(int a, int b) {
        long _sum=long(a)+long(b);
        long _diff=long(a)-long(b);
        long _abs=(_diff^(_diff>>63))-(_diff>>63);
        return (_sum+_abs)/2;
    }
};

剑指 Offer 15. 二进制中1的个数

请实现一个函数,输入一个整数,输出该数二进制表示中 1 的个数。例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。

示例 1:
输入:00000000000000000000000000001011
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 ‘1’。

示例 2:
输入:00000000000000000000000010000000
输出:1
解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 ‘1’。

示例 3:
输入:11111111111111111111111111111101
输出:31
解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 ‘1’。

注意:本题与主站 191 题相同:https://leetcode-cn.com/problems/number-of-1-bits/

class Solution 
{
public:
    int hammingWeight(uint32_t n) 
    {
        int result_count = 0;
        while (n != 0)
        {
            ++result_count;
            n = n & (n - 1);//n & (n-1):可以把从右边到左边的第 1个 1变成 0。
        }
        return result_count;
    }
};

461. 汉明距离

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

给出两个整数 x 和 y,计算它们之间的汉明距离。

注意:
0 ≤ x, y < 231.

示例:
输入: x = 1, y = 4
输出: 2
解释:
1 (0 0 0 1)
4 (0 1 0 0)
↑ ↑
上面的箭头指出了对应二进制位不同的位置。

class Solution {
public:
    int hammingDistance(int x, int y) {
        int result=0;
        while(x!=0||y!=0){
            result+=(x&1)^(y&1);
            x>>=1;
            y>>=1;
        }
        return result;
    }
};

1290. 二进制链表转整数

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

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

示例 1:
在这里插入图片描述

输入:head = [1,0,1]
输出:5
解释:二进制数 (101) 转化为十进制数 (5)

示例 2:
输入:head = [0]
输出:0

示例 3:
输入:head = [1]
输出:1

示例 4:
输入:head = [1,0,0,1,0,0,1,1,1,0,0,0,0,0,0]
输出:18880

示例 5:
输入:head = [0,0]
输出:0

提示:
链表不为空。
链表的结点总数不超过 30。
每个结点的值不是 0 就是 1。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution 
{
public:
    int getDecimalValue(ListNode* head) 
    {
        int32_t result = 0;
        vector<int>count;
        ListNode* node = head;
        while (node)
        {
            count.push_back(node->val);
            node = node->next;
        }
        for (int i = 0; i < count.size(); ++i)
        {
            result += count[i] << (count.size() - i - 1);
        }
        return result;
    }
};

342. 将数字变成 0 的操作次数

给你一个非负整数 num ,请你返回将它变成 0 所需要的步数。 如果当前数字是偶数,你需要把它除以 2 ;否则,减去 1 。

示例 1:
输入:num = 14
输出:6
解释:
步骤 1) 14 是偶数,除以 2 得到 7 。
步骤 2) 7 是奇数,减 1 得到 6 。
步骤 3) 6 是偶数,除以 2 得到 3 。
步骤 4) 3 是奇数,减 1 得到 2 。
步骤 5) 2 是偶数,除以 2 得到 1 。
步骤 6) 1 是奇数,减 1 得到 0 。

示例 2:
输入:num = 8
输出:4
解释:
步骤 1) 8 是偶数,除以 2 得到 4 。
步骤 2) 4 是偶数,除以 2 得到 2 。
步骤 3) 2 是偶数,除以 2 得到 1 。
步骤 4) 1 是奇数,减 1 得到 0 。

示例 3:
输入:num = 123
输出:12

提示:
0 <= num <= 10^6

class Solution 
{
public:
    int numberOfSteps(int num) 
    {
        int result_count = 0;
        while (num != 0){
            num = (num % 2 == 0) ? (num / 2) : (num - 1);
            ++result_count;
        }
        return result_count;
    }
};

1486. 数组异或操作

给你两个整数,n 和 start 。
数组 nums 定义为:nums[i] = start + 2*i(下标从 0 开始)且 n == nums.length 。
请返回 nums 中所有元素按位异或(XOR)后得到的结果。

示例 1:
输入:n = 5, start = 0
输出:8
解释:数组 nums 为 [0, 2, 4, 6, 8],其中 (0 ^ 2 ^ 4 ^ 6 ^ 8) = 8 。
“^” 为按位异或 XOR 运算符。

示例 2:
输入:n = 4, start = 3
输出:8
解释:数组 nums 为 [3, 5, 7, 9],其中 (3 ^ 5 ^ 7 ^ 9) = 8.

示例 3:
输入:n = 1, start = 7
输出:7

示例 4:
输入:n = 10, start = 5
输出:2

提示:
1 <= n <= 1000
0 <= start <= 1000
n == nums.length

class Solution {
public:
    int xorOperation(int n, int start) {
        int result=0;
        for(int i=0;i<n;++i)result^=(start+2*i);
        return result;
    }
};

338. 比特位计数

给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。

示例 1:
输入: 2
输出: [0,1,1]

示例 2:
输入: 5
输出: [0,1,1,2,1,2]

进阶:
给出时间复杂度为O(n*sizeof(integer))的解答非常容易。但你可以在线性时间O(n)内用一趟扫描做到吗?
要求算法的空间复杂度为O(n)。
你能进一步完善解法吗?要求在C++或任何其他语言中不使用任何内置函数(如 C++ 中的 __builtin_popcount)来执行此操作。

class Solution {
public:
    vector<int> countBits(int num) {
        if(num==0){return {0};}
        vector<int>dp(num+1);
        dp[0]=0;
        dp[1]=1;
        for(int i=2;i<=num;++i){
            if(i%2==0){dp[i]=dp[i/2];}
            else dp[i]=dp[i-1]+1;
        }
        return dp;
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yhwang-hub

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值