直通BAT--数据结构与算法八(位运算)


1.不用任何额外变量交换两个整数的值

//请编写一个算法,不用任何额外变量交换两个整数的值。
//
//给定一个数组num,其中包含两个值,请不用任何额外变量交换这两个值,并将交换后的数组返回。
//
//测试样例:
//[1, 2]
//返回:[2, 1]

vector<int> GetSwap::getSwap(vector<int> num){

     //同时与一个数异或两次,则等于原来的数
     num[0] = num[0] ^ num[1];
     num[1] = num[0] ^ num[1];
     num[0] = num[0] ^ num[1];

     return num;
}


2.返回a和b中较大的,不能用任何比较判断

//对于两个32位整数a和b,请设计一个算法返回a和b中较大的。但是不能用任何比较判断。若两数相同,返回任意一个。
//
//给定两个整数a和b,请返回较大的数。
//
//测试样例:
//1, 2
//返回:2

int getSign(int a);
int flip(int a);

int GetMax::getMax(int a, int b){
     //a的符号,为正等于0
     int as = getSign(a);
     //a的符号,为正等于1
     int af = flip(as);
     //b的符号,为正等于0
     int bs = getSign(b);
     //b的符号,为正等于1
     int bf = flip(bs);
     //a和b符号相反,为1
     int diff = as^bs;
     //a和b符号相同,为1
     int same = flip(diff);
     //a-b符号.a>b为0
     int ds = getSign(a - b);
     //a-b符号.a>b为1
     int df = flip(ds);

     return diff*(a*af + b*bf) + same*(a*df + b*ds);
}

int getSign(int a){
     return (a >> 31) & 1;
}

int flip(int a){
     return a ^ 1;
}


3.一个数出现了奇数次,其他的数都出现了偶数次,请打印这个数

//有一个整型数组A,其中只有一个数出现了奇数次,其他的数都出现了偶数次,请打印这个数。要求时间复杂度为O(N),额外空间复杂度为O(1)。
//
//给定整形数组A及它的大小n,请返回题目所求数字。
//
//测试样例:
//[1, 2, 3, 2, 1], 5
//返回:3

int FindOdd::findOdd(vector<int> A, int n){
     int res = 0;
     //0与一个数异或为这个数,与一个数异或两次为0
     for (int i = 0; i < n; ++i){
          res ^= A[i];
     }
     return res;
}


4.两个数出现了奇数次,其他的数都出现了偶数次,找到这两个数

//给定一个整型数组arr,其中有两个数出现了奇数次,其他的数都出现了偶数次,找到这两个数。要求时间复杂度为O(N),额外空间复杂度为O(1)。
//
//给定一个整形数组arr及它的大小n,请返回一个数组,其中两个元素为两个出现了奇数次的元素, 请将他们按从小到大排列。
//
//测试样例:
//[1, 2, 4, 4, 2, 1, 3, 5], 8
//返回:[3, 5]

vector<int> FindOdds::findOdds(vector<int> arr, int n){
     int xorRes = 0;
     vector<int> res(2,0);

     //得到这两个数的异或
     for (int i = 0; i < n; ++i){
          xorRes ^= arr[i];
     }
     //由于两个数不相等,取xorRes某一位上为1,记录为1的位置
     int j = 0;
     for (; j < 32; ++j){
          if (xorRes & (1<<j))
              break;
     }
     //aXor上只有该位为1
     int aXor = 1<<j;
     //将集合中所有该位为1的数与aXor异或,最后得到的结果就是其中一个奇数个的数res[0]
     for (int i = 0; i < n; ++i){
          if (arr[i] & aXor)
              res[0] ^= arr[i];
     }
     //将res[0]与xorRes异或,得到res[1]
     res[1] = xorRes^res[0];
     //将res排序
     sort(res.begin(),res.end());;

     return res;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值