牛客网算法学习笔记-位运算

请编写一个算法,不用任何额外变量交换两个整数的值。

给定一个数组num,其中包含两个值,请不用任何额外变量交换这两个值,并将交换后的数组返回。

测试样例:
[1,2]

返回:[2,1]

A^A=0, A^0 = A. A^B^A = B (因为A^A=0与位置无关)

class Swap {
public:
    vector<int> getSwap(vector<int> num) {
        // write code here
        num[0] = num[0]^num[1];
        num[1] = num[0]^num[1];
        num[0] = num[0]^num[1];
        return num;
    }
};


对于两个32位整数a和b,请设计一个算法返回a和b中较大的。但是不能用任何比较判断。若两数相同,返回任意一个。

给定两个整数ab,请返回较大的数。

测试样例:
1,2
返回:2
class Compare {
public:
    int getMax(int a, int b) {
        // write code here
        int sign1 = getSign(a);
        int sign2 = getSign(b);
        if(sign1 == sign2){ //同号
            int sign = getSign(a-b); //做差,观察结果的符号
            if(sign == 1) //符号0
                return a;
            else{ //符号1
                return b;
            }
        }
        else if (sign1 == 1){ //异号且a为正
            return a;
        }
        else{ //异号a为负
            return b;
        }
    }
    
    int getSign(int a){ //取符号
        return (a>>31)^1;
    }
};


有一个整型数组A,其中只有一个数出现了奇数次,其他的数都出现了偶数次,请打印这个数。要求时间复杂度为O(N),额外空间复杂度为O(1)。

给定整形数组A及它的大小n,请返回题目所求数字。

测试样例:
[1,2,3,2,1],5
返回:3

class OddAppearance {
public:
    int findOdd(vector<int> A, int n) {
        // write code here
        for(int i = 1 ; i<A.size();i++){
            A[0] = A[i]^A[0];
        }
        return A[0];
    }
};


给定一个整型数组arr,其中有两个数出现了奇数次,其他的数都出现了偶数次,找到这两个数。要求时间复杂度为O(N),额外空间复杂度为O(1)。

给定一个整形数组arr及它的大小n,请返回一个数组,其中两个元素为两个出现了奇数次的元素,请将他们按从小到大排列。

测试样例:
[1,2,4,4,2,1,3,5],8
返回:[3,5]
有两个数出现奇数次的情况下,对数组异或的结果为A^B,因为AB不同,所以可以按位进行与操作,找到其中一位为1的 但对于另一个数为0的情况,那么通过这一位就可以对两个数进行过滤,在第二次遍历时,只异或这位为1的数,那么可以找到其中一个数,再与之前的结果^则可以找到另一个数
class OddAppearance {
public:
    vector<int> findOdds(vector<int> arr, int n) {
        // write code here
        vector<int> rarr;
        int check1 = 0, check2 = 0, mask = 1;
        for(int i = 0; i < n; i++)
            check1 = check1 ^ arr[i];
        while(!(mask & check1))
            mask = mask<<1;
        for(int j = 0; j < n; j++){
            if(mask & arr[j])
                check2 = check2 ^ arr[j];
        }
        int res1 = check2;
        int res2 = check2 ^ check1;
         
        if(res1 >= res2)
            rarr = {res2, res1};
        else
            rarr = {res1, res2};
        return rarr;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值