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

原创 2016年05月31日 09:17:59

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

给定一个数组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;
    }
};

相关文章推荐

不用任何比较判断找出两个数中较大的数

不用任何比较判断找出两个数中较大的数 【题目】   给定两个32位整数a和b,返回a和b中较大的。 【要求】   不用任何比较判断。 【解答】   这里有两种方法进行解决,两种方法原理都一...

比较练习

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

交换、比较

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

学习笔记---位运算

位运算 位运算符 优先级 运算符 功能 结合方式 2 ~ 按位取反 由左向右 5 > 左移   右移 由左向右 8 ...

JAVA学习笔记-位运算

今儿看到了JAVA的位运算,准备好好复习一下,查考了一些资料,挑出了一些容易理解的...

C语言中的位运算&结构体浅析 — <编程之美>1.2学习笔记

引子问题: 中国象棋将帅问题:在一把象棋的残局中,象棋双方的将帅不可以相见,即不可以在中间没有其他棋子的情况下在同一列出现。而将、帅各被限制在己方的3*3的格子中运动。相信大家都非常熟悉象棋的玩法吧,...

java学习笔记之位运算

位运算符用来对二进制位进行操作 ,Java编程语言支持位运算符 (&,|,^,~,>>,

C++学习笔记-----用位运算实现加减乘除

数据在计算机内存中是以二进制存储的。 几种常用的位运算:与运算&:对应位均为1时为1,其它为0。 或运算|:对应位均为0时为0,其它为1。 异或运算^:对应位不相同时为1,相同时为0. 按位取反~:...

枚举中的位运算学习笔记

我们经常遇到,系统定义的枚举中,经常遇到位运算。就像下面代码块中所用到的那样(...

黑马程序员 java学习笔记——位运算 左移 右移;

---------------------- android培训、java培训、期待与您交流! ----------------------     一、逻辑移位(无符号数):不管原码、反码、补...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:牛客网算法学习笔记-位运算
举报原因:
原因补充:

(最多只允许输入30个字)