首页 > 其他分享 >剑指offer——Day22 位运算(中等)

剑指offer——Day22 位运算(中等)

时间:2023-02-04 14:13:17浏览次数:54  
标签:set 运算 offer int 题解 Day22 异或 vector 遍历

Day22 2023.2.4 位运算(中等)

剑指offer 56 - Ⅰ. 数组中数字出现的次数

自己实现

就直接结合set进行遍历,然后出现重复就从set里面删除掉,最后就能得到只包含出现过一次的set

代码如下:

class Solution {
public:
    vector<int> singleNumbers(vector<int>& nums) {
        vector<int> res;
        set<int> s;
        for(int i=0;i<nums.size();i++){
            auto pos = s.find(nums[i]);
            if(pos==s.end())s.insert(nums[i]);
            else{
                s.erase(pos);
            }
        }
        for(auto i=s.begin();i!=s.end();i++)res.push_back(*i);
        return res;
    }
};

代码表现

时间花费有点太多了,看看题解

题解

首先有一个关于异或运算的使用性质

通过异或的这个性质,可以对整个数组进行遍历异或,结果会得到x^y

然后通过用一个比特位的1来循环左移找到x^y不等于0的那一个比特位(即x和y不同的那一个比特位)

然后可以根据这个比特位将原来的数组划分为两个子数组再来遍历验证

参考题解思路自己写的代码如下:

class Solution {
public:
    vector<int> singleNumbers(vector<int>& nums) {
        int x=0,y;
        for(int i=0;i<nums.size();i++){
            x^=nums[i];
        }
        int m=1;
        while((x&m)==0){
            m<<=1;
        }
        x=0,y=0;
        for(int i=0;i<nums.size();i++){
            if(nums[i]&m)x^=nums[i];
            else y^=nums[i];
        }
        return vector<int> {x,y};
    }
};

代码表现

hint

  • set的遍历是for(set<int>::iterator it=s.begin();it!=s.end();it++)判断条件是!=而不能写成<
  • &的优先级比==要低,所以如果要对&的结果进行条件判断的话要打括号!
  • 收获了一种新的异或的用法

剑指offer 56 - Ⅱ. 数组中数字出现的次数Ⅱ

自己实现

虽然收获了上一题的思路,但是三个数字相同的话就不能再使用异或了,直接看答案了

题解

方法一:有限状态自动机

大概理解但具体的代码理论支撑形成比较困难

具体可见K神题解

方法二:遍历统计

同样看K神题解,这个还没来得及看

方法一的代码如下:

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int ones = 0, twos = 0;
        for(int num : nums){
            ones = ones ^ num & (~twos);
            twos = twos ^ num & (~ones);
        }
        return ones;
    }
};

代码表现

hint:

  • 这个位运算吧,可以算作一种很奇特的方法,比如在有偶数个重复数字的情况下,可以用遍历异或来快速筛选出这些数。但是位运算对应的用法和使用场景需要多积累,毕竟要多转几个弯,代码优化的时候应该能用上。

标签:set,运算,offer,int,题解,Day22,异或,vector,遍历
From: https://www.cnblogs.com/cspzyy/p/17091362.html

相关文章

  • C语言学习 指针的运算和比较
    1#include<stdio.h>2#include<io_utils.h>34intmain(){5{6inta=2;7int*p=&a;89PRINT_INT(p+1);10PRINT_INT(......
  • 费解的开关(位运算+递推)
    题目描述:你玩过“拉灯”游戏吗?25盏灯排成一个5x5的方形。每一个灯都有一个开关,游戏者可以改变它的状态。每一步,游戏者可以改变某一个灯的状态。游戏者改变一个灯的状态会产......
  • 运算符重载
    基本概念:重载的运算符是具有特殊名字的函数:它们的名字由关键字operator和其后面要定义的运算符号共同组成。同其他函数一样,重载的运算符函数也包含返回类型、参数列表以......
  • java运算符
    1.概述运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等。1)算术运算符2)赋值运算符3)关系运算符[比较运算符]4)逻辑运算符5)位运算符[需要二进制基础]......
  • 三元运算符
    三元运算符packageoperator;publicclassdemo06{publicstaticvoidmain(String[]args){//三元运算符x?a:b//如果x=true,则结果为a,否......
  • 扩展赋值运算符
    扩展赋值运算符packageoperator;publicclassdemo05{publicstaticvoidmain(String[]args){inta=10;intb=20;a+=b;//a......
  • 逻辑运算符&&和||和!
    逻辑运算符逻辑运算符&&,||,!packageoperator;publicclassdemo03{publicstaticvoidmain(String[]args){//逻辑运算符,与(and)、或(or)、非(取反)......
  • 位运算符
    位运算符packageoperator;publicclassdemo04{publicstaticvoidmain(String[]args){/*位运算符与,或,非&|~A=00111100B=......
  • 位运算符<<和>>计算方法详细说明
    左移和右移详细说明1、<<(左移)1.运算规则:按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零。2.语法格式:需要移位的数字<<移位的次数例......
  • Python算术运算符
    Python算术运算符以下假设变量: a=10,b=20:运算符描述实例+加-两个对象相加a+b输出结果30-减-得到负数或是一个数减去另一个数a-b输出结果-10*乘-两个数相乘或......