题目链接
面试题 16.07. 最大数值 easy
题目描述
编写一个方法,找出两个数字a和b中最大的那一个。不得使用if-else
或其他比较运算符。
示例:
输入: a = 1, b = 2
输出: 2
解法:位运算
- 如果 a − b > 0 a - b > 0 a−b>0,那么 a − b a-b a−b的二进制位,最高位一定为 0
- 如果 a − b < 0 a - b < 0 a−b<0,那么 a − b a-b a−b的二进制位,最高位一定为 1
极端情况下
a
=
2147483647
,
b
=
−
2147483648
a = 2147483647, b = -2147483648
a=2147483647,b=−2147483648,
a
−
b
a - b
a−b 就会爆 int
。
所以为了方便,我们把
a
,
b
a,b
a,b都转为 long
类型的。
因为 C++ 中的 << , >>
都是算数左移 和 右移,是带着符号位的。
- 当 a − b > 0 a - b > 0 a−b>0时, k = ( a − b ) > > 63 = 0 k = (a - b) >> 63 = 0 k=(a−b)>>63=0
- 当 a − b < 0 a - b < 0 a−b<0时, k = ( a − b ) > > 63 = − 1 k =(a - b) >> 63 = -1 k=(a−b)>>63=−1
为了便于处理,我们将 k + = 1 k += 1 k+=1。即当 a − b > 0 a - b > 0 a−b>0时, k = 1 k = 1 k=1;当 a − b < 0 a - b < 0 a−b<0时, k = 0 k = 0 k=0。
所以最终返回的答案就是 a ∗ k + b ∗ ( k x o r 1 ) a * k + b * (k xor 1) a∗k+b∗(kxor1)
时间复杂度: O ( 1 ) O(1) O(1)
C++代码:
class Solution {
public:
int maximum(int a, int b) {
long c = a, d = b;
int k = ((c - d) >> 63) + 1;
return a * k + b * (k ^ 1);
}
};