【leetcode-位运算】格雷编码/数字的补数/Pow(x,n)/2的幂/3的幂/4的幂/两整数之和

格雷编码

格雷编码是一个二进制数字系统,在该系统中,两个连续的数值仅有一个位数的差异。
给定一个代表编码总位数的非负整数 n,打印其格雷编码序列。即使有多个不同答案,你也只需要返回其中一种。
格雷编码序列必须以 0 开头。

示例 1:
输入: 2
输出: [0,1,3,2]
解释:
00 - 0
01 - 1
11 - 3
10 - 2
对于给定的 n,其格雷编码序列并不唯一。
例如,[0,2,3,1] 也是一个有效的格雷编码序列。
00 - 0
10 - 2
11 - 3
01 - 1

示例 2:
输入: 0
输出: [0]
解释: 我们定义格雷编码序列必须以 0 开头。
给定编码总位数为 n 的格雷编码序列,其长度为 2n。当 n = 0 时,长度为 20 = 1。
因此,当 n = 0 时,其格雷编码序列为 [0]。

模拟

class Solution {
    public List<Integer> grayCode(int n) {
        List<Integer> result = new ArrayList<Integer>() {{add(0);}};
        
        int head = 1;
        for (int i = 0; i < n; i++) {
            for (int j = head - 1; j >= 0; j--)
                result.add(result.get(j) + head);
            head <<= 1;
        }
        return result;
    }
}

异或

class Solution {
    public List<Integer> grayCode(int n) {
        List<Integer> result = new ArrayList<Integer>();
        for(int i = 0; i < (1 << n); i++)
            result.add(i ^ (i >> 1));
        return result;
    }
}

数字的补数

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

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

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

异或

5的二进制为 0101,其最高的1到最低位全置1,即 0111。二者异或得到 0010

class Solution {
    public int findComplement(int num) {
        int top = 0, tmp = num;
        while (tmp != 0) {
            top++;
            tmp >>>= 1;
        }
        return num ^ ((1 << top) - 1);
    }
}

Pow(x,n)

实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,xn)。

示例 1:
输入:x = 2.00000, n = 10
输出:1024.00000

示例 2:
输入:x = 2.10000, n = 3
输出:9.26100

示例 3:
输入:x = 2.00000, n = -2
输出:0.25000
解释:2-2 = 1/22 = 1/4 = 0.25

递归

class Solution {
    public double myPow(double x, int n) {
        if (n == Integer.MIN_VALUE)
            return 1.0 / quickMul(x, Integer.MAX_VALUE) / x;
        double result = quickMul(x, Math.abs(n));
        return (n >= 0) ? result : 1.0 / result;
    }

    private double quickMul(double x, int n) {
        if (n == 0) {
            return 1.0;
        }
        double y = quickMul(x, n >> 1);
        return (n & 1) == 0 ? y * y : y * y * x;
    }
}

迭代

class Solution {
    public double myPow(double x, int n) {
        if (n == Integer.MIN_VALUE)
            return 1.0 / quickMul(x, Integer.MAX_VALUE) / x;
        double result = quickMul(x, Math.abs(n));
        return (n >= 0) ? result : 1.0 / result;
    }

    private double quickMul(double x, int n) {
        double ans = 1.0, y = x;
        while (n > 0) {
            if (n % 2 == 1)
                ans *= y;
            y *= y;
            n >>= 1;
        }
        return ans;
    }
}

2的幂

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

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

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

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

位移

class Solution {
    public boolean isPowerOfTwo(int n) {
        int cur = 1;
        for (int i = 0; i < 31; i++) {
            if (cur == n)
                return true;
            cur <<= 1;
            if (cur > n)
                break;
        }
        return false;
    }
}

求模

int 的最大二次幂为 2 30 2^{30} 230,其余二次幂是它的因数。

class Solution {
    public boolean isPowerOfTwo(int n) {
        return n > 0 && (1 << 30) % n == 0;
    }
}

去除最右侧的1

class Solution {
    public boolean isPowerOfTwo(int n) {
        if (n == 0)
            return false;
        long x = n;
        return (x & (x - 1)) == 0;
    }
}

保留最右侧的1

class Solution {
    public boolean isPowerOfTwo(int n) {
        return n > 0 && (n & -n) == n;
    }
}

3的幂

给定一个整数,写一个函数来判断它是否是 3 的幂次方。如果是,返回 true ;否则,返回 false 。
整数 n 是 3 的幂次方需满足:存在整数 x 使得 n == 3x

示例 1:
输入:n = 27
输出:true

示例 2:
输入:n = 0
输出:false

示例 3:
输入:n = 9
输出:true

示例 4:
输入:n = 45
输出:false

整数限制

int 中 最大的 3的幂 为 1162261467

class Solution {
    public boolean isPowerOfThree(int n) {
        return n > 0 && 1162261467 % n == 0;
    }
}

4的幂

给定一个整数,写一个函数来判断它是否是 4 的幂次方。如果是,返回 true ;否则,返回 false 。
整数 n 是 4 的幂次方需满足:存在整数 x 使得 n == 4x

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

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

示例 3:
输入:n = 1
输出:true

位运算

class Solution {
    public boolean isPowerOfFour(int n) {
        return n > 0 && (n & (n - 1)) == 0 && (n & 0xaaaaaaaa) == 0;
    }
}

位运算+数学运算

class Solution {
    public boolean isPowerOfFour(int n) {
        return n > 0 && (n & (n - 1)) == 0 && n % 3 == 1;
    }
}

两整数之和

不使用运算符 + 和 - ​​​​​​​,计算两整数 ​​​​​​​a 、b ​​​​​​​之和。

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

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

递归

异或 为不进位二进制加法,当且仅当两个数的相同为都为1时才有进位,所以用 与运算。

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

迭代

class Solution {
    public int getSum(int a, int b) {
        while (b != 0) {
            int carry = (a & b) << 1;
            a ^= b;
            b = carry;
        }
        return a;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值