【算法题】不用做任何比较,返回两个数中的最大值!

hello!今天我们来看一道算法题!!!

在线OJ链接

image-20211007114208972

给定两个数,不做任何比较,返回最大值。

分析:我们都知道1乘以任何数,得到的是它本身;0乘以任何数都是得0。根据这个性质啊,我们就能够做出一些事情来。题目既然给了两个数,我们将两个数相减,假设被减数是a,减数是b。a-b肯定会得到一个正数或者负数。如果是正数,说明a比较大,反之就是b比较大。

然后我们就将这个结果进行处理,如果是负数,我们就让他等于0;如果是正数,我们就让他等于1。再将这1或者0,去乘以a或者b。肯定有一个得到他本身,另外一个得到0,二者相加作为结果返回即可。代码如下:

public int getMax1(int a, int b) {
    
    
    int c = a - b; //得到差值,根据差值的正负判断大小
    int scA = sign(c); //判断差值的正负。正数返回1,负数返回0
    int scB = flip(scA); //scA和scB取相反
    return scA * a + scB * b; //scA和scB,肯定有一个是0,有一个是1
}

private int sign(int n) {
    
    
    return flip((n >> 31) & 1); //拿到n的符号位。根据符号位判断正负
}

private int flip(int n) {
    
    
    return n ^ 1; //如果n是1,就返回0。如果n是0,就返回1。
}

如上代码,就是初级版的代码,能够解决一般的数值问题。但是有一个问题就是,a-b溢出怎么办???溢出的话,肯定是会影响到后续的判断的。

我们先想一想为什么会溢出???

溢出的情况,只能是a和b两个数不同号,且数值相对比较大的时候,才会产生溢出。a和b同号的话,是不可能产生溢出的,如果同号,解决方案就是上面的代码;问题就在于不同号的情况。所以我们先判断一下a和b是否同号,然后再做处理。

public int getMax2(int a, int b) {
    
    
    int c = a - b;
    int scA = sign(a);
    int scB = sign(b); //得到a和b的正负情况
    int scC = sign(c); 
    
    int difSab = scA ^ scB; //相同为0,相异为1;判断是否同号
    int sameSab = flip(difSab); //difSab和sameSab,一个是1,一个是0
    
    //如果同号,difSab就是0,sameSab就是1
    //如果不同号,difSab就是1,sameSab就是0
    int returnA = sameSab * scC + difSab * scA;
    int returnB = flip(returnA);
    
    return returnA * a + returnB * b;
}

解释:重点就在于第12行的代码,我们来看

  • 如果a和b同号的话,说明a-b不会溢出,sameSab等于1,此时我们只需要看scC的正负情况,来判断大小。sameSab * scC
  • 如果a和b不同号的话,difSab等于1,此时只需判断scA或者scB的正负情况即可。difSab * scA

最后returnA和returnB,肯定有一个是0,有一个是1。二者互斥,最后相乘,肯定是要么返回a的值,要么返回b的值。

好啦,本期更新就到此结束啦!欢迎评论区留言!!!

猜你喜欢

转载自blog.csdn.net/x0919/article/details/120634654