算法|2.异或运算

news/2024/12/23 6:18:01/

算法|2.异或运算

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

题意:不用额外变量交换(数组中)两个数的值

解题思路:

  • 使用异或运算的性质

在这里插入图片描述

代码及运行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kkTo46xE-1685088032675)(F:\typora插图\image-20230526125538881.png)]

2.找到唯一出现奇数次的数字

题意:一个数组中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这种数

解题思路:

  • 说明:补码的补码即相反数的补码等于原数补码连同符号位取反末尾加
  • 将数组中的数全部异或一遍,得到的即是结果

核心代码:

//arr中,只有一种数出现奇数次
public static void printOddTimesNum1(int[] arr){int ero=0;for (int cur:arr) {ero^=cur;}System.out.println("出现奇数次的数字分别是:"+ero);
}

测试方法:

说明,本题和下一题均为写对数器,并且测试方法在同一个main方法中写着呢。故下边不再写该部分内容。

//for test
public static void main(String[] args) {int[] arr1 = { 3, 3, 2, 3, 1, 1, 1, 3, 1, 1, 1 };//        System.out.println("预期结果:"+2);printOddTimesNum1(arr1);//        int[] arr2={1,1,2,2,2,3,3,3,4,4};int[] arr2 = { 4, 3, 4, 2, 2, 2, 4, 1, 1, 1, 3, 3, 1, 1, 1, 4, 2, 2 };//        System.out.println("预期结果:"+2+" "+3);printOddTimesNum2(arr2);}

测试结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aOPZG8a5-1685088032675)(F:\typora插图\image-20230526140344898.png)]

3.找到唯二出现奇数次的数字

题意:一个数组中有两种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这两种数

解题思路:

在这里插入图片描述

  • 拿到最右侧的1:原数与相反数求与
  • 将数组中的数分为两组。分组依据:异或全数组的数据最右侧是否有1
  • 拿到最右侧为1的位置==》体现在一个二进制序列==》十进制数==》利用这个数判断数组中的数这一位是否有1,有则异或到一个ero1,得到其中一个结果
  • 另一个结果通过异或过整组数的ero和ero1再异或可得到

核心代码:

//arr中,有两种数出现奇数次
public static void printOddTimesNum2(int[] arr){int ero=0;for (int cur:arr) {ero^=cur;}//提取出最右侧的1:原数与相反数相与int rightestOne=ero&(-ero);//        System.out.println(rightestOne);//ero':提取出最右侧为这个1的一组数的结果int ero1=0;for (int cur:arr) {ero1^=(cur&rightestOne)==0?0:cur;}ero=ero^ero1;System.out.println("出现奇数次的数字分别是:"+ero+" "+ero1);
}

4.找出唯一出现K次的数字

题意:一个数组中有一种数出现K次,其他数都出现了M次,已知M > 1,K < M,找到出现了K次的数,要求额外空间复杂度O(1),时间复杂度O(N)

解题思路:

在这里插入图片描述

  • 说明:1.辅助数组为定长数组长度,空间复杂度为O(1)2.判断最右侧是不是(num>>i)&1,结果为1/0;提取最右侧的1:num&(-num),结果为2的整数次幂
  • 使用辅助数组统计本数组中有多少个数字第i个二进制位上为1——统计方法:得到每个元素的2进制序列,将1出现的情况加到统计数组中
  • 使用ans变量,遍历这个数组如果这个位置1出现的次数对m取模若为k,说明目标数字这一位上有这个1,把它搞进结果变量中——或的手段
  • 取模m可取的前提是k<m。否则可能存在km的存在倍数关系。

对数器:

  • 使用map的方式

  • 查找次数为k的数值遍历表的方法——keySet(key)或者entrySet(ky和value的关系)

    对数器使用的keySet,这里对entrySet的使用做演示:

Set<Map.Entry<String, String>> entryseSet=map.entrySet();for (Map.Entry<String, String> entry:entryseSet) {System.out.println(entry.getKey()+","+entry.getValue());}
//即通过getKey()得到K,getValue得到V
  • 打乱顺序(shuffleOrder):i位置数和随机生成的j(0~N-1)位置数进行交换

核心代码:

public static int km(int[] arr,int k,int m){int[] help=new int[32];//统计for (int cur:arr) {for (int i = 0; i < 32; i++) {help[i]+=(cur>>i)&1;}}//判断出现k次数的数中1出现的位置,并将相关状况放在ans的二进制序列中int ans=0;for (int i = 0; i < 32; i++) {ans|=help[i]%m==0?0:1<<i;}return ans;
}

测试代码:

    //for testpublic static int test(int[] arr,int k,int m){HashMap<Integer,Integer> map=new HashMap<>();for (int i = 0; i < arr.length; i++) {if(map.containsKey(arr[i])){map.put(arr[i],map.get(arr[i])+1);}else{map.put(arr[i],1);}}int ans=0;for (int num:map.keySet()) {if(map.get(num)==k){ans=num;break;}}return ans;}//for testpublic static int[] generateRandomArray(int maxKinds,int range,int k,int m){int kNum=(int) (Math.random()*(range+1))-(int) (Math.random()*(range+1));int kinds= (int) (Math.random()*maxKinds)+2;//2~maxkinds+1//System.out.println("kinds:"+kinds);int[] arr=new int[k+(kinds-1)*m];//生成km的随机函数没写对....
//        int[] arr= new int[0];
//        try {
//            arr = new int[k+(kinds-1)*m];
//        } catch (NegativeArraySizeException e) {
//            System.out.println("k:"+k);
//            System.out.println("kinds:"+kinds);
//            System.out.println("m:"+m);
            k:2
            kinds:0
            m:4
//            throw new RuntimeException(e);
//        }int index=0;for(;index<k;index++){arr[index]=kNum;}kinds--;HashSet<Integer> set=new HashSet<>();set.add(kNum);while(kinds--!=0){int curNum=0;do {curNum=(int) (Math.random()*(range+1))-(int) (Math.random()*(range+1));}while(set.contains(curNum));set.add(curNum);for (int i = 0; i < m; i++) {arr[index++]=curNum;}}shuffleOrder(arr);return arr;}//for test//打乱数组顺序:public static void shuffleOrder(int[] arr){for (int i = 0; i < arr.length; i++) {int j= (int) (Math.random()*arr.length);int tmp=arr[i];arr[i]=arr[j];arr[j]=tmp;}}//for testpublic static void main(String[] args) {boolean succeed=true;int kinds=5;int range=30;int maxTimes=9;int testTimes=1000;for (int i = 0; i < testTimes; i++) {int a = (int) (Math.random() * maxTimes) + 1; // a 1 ~ 9int b = (int) (Math.random() * maxTimes) + 1; // b 1 ~ 9int k = Math.min(a, b);int m = Math.max(a, b);// k < mif (k == m) {m++;}int[] arr=generateRandomArray(kinds,range,k,m);int ret1=km(arr,k,m);int ret2=test(arr,k,m);if(ret1!=ret2){System.out.println("k="+k+"  m="+m);System.out.println("km:"+ret1);System.out.println("test:"+ret2);System.out.println(Arrays.toString(arr));System.out.println("Oops!Error!");succeed=false;break;}}if(succeed){System.out.println("succeed!");}}

测试结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-anDCEMKM-1685088032677)(F:\typora插图\image-20230526153038004.png)]

位运算之异或运算题目总结

定义:

相同为0,相异为1。

理解:无进位相加

性质:

  • 0^N=N
  • N^N=0
  • 满足交换律和结合律

例题总结:

  • 不使用临时变量交换:三个等式aba
  • 寻找偶数次中的唯一奇数次:全部异或
  • 寻找偶数次中的唯二奇数次:异或分组异或;分组规则最右侧的1(相反数的补)
  • 寻找M次中的K次:辅助数组;对每个二进制统计(移位);对辅助数组遍历(或)

http://www.ppmy.cn/news/90647.html

相关文章

挂耳式耳机品牌排行榜,看看谁被推荐上榜

下班路上就想放空自己刷会儿视频&#xff0c;但是马路、地铁还有公交上都会有嘈杂的声音影响&#xff0c;如果佩戴入耳式耳机放大声音不仅会过度屏蔽外界&#xff0c;同时还会损伤我们的耳朵&#xff0c;所以新近流行的开放式耳机很好的解决了这些问题&#xff0c;但也有很多小…

Go 存储系列:Hash存储引擎 Bitcask

Hash 存储引擎 在现代软件系统中&#xff0c;存储和检索数据是一个非常重要的任务。随着数据量的不断增长&#xff0c;如何高效地存储和检索数据变得越来越重要。Hash 存储引擎是一种常见的存储引擎&#xff0c;它可以快速地存储和检索数据。 在本文中&#xff0c;我们将介绍…

基于langChain 的privateGPT 文档问答 研究

参考&#xff1a;gihtub代码 https://github.com/imartinez/privateGPT 官网 privateGPT可以在断网的情况下&#xff0c;借助GPT和文档进行交互&#xff0c;有利于保护数据隐私。 privateGPT可以有四个用处&#xff1a; 1.增强知识管理&#xff1a;私有LLMs自动化&#xff0c…

「实在RPA·制造业数字员工」助力制造业加「数」发展

作为世界制造大国&#xff0c;制造行业一直是国家经济发展的重要载体。2023年度政府工作报告将制造业摆在突出位置&#xff0c;指出要加快建设现代化产业体系&#xff0c;将围绕制造业重点产业链&#xff0c;集中优质资源合力推进关键核心技术攻关。国资委机械院创新中心主任宋…

快手上市后首次盈利,直播电商业务成造血利器

5月22日盘前&#xff0c;快手业绩还没有发布&#xff0c;股价却先涨为敬&#xff0c;中信证券、彭博、中金公司等多家机构给出超预期业绩的预测。盘后公布的业绩确实超过市场的一致预期&#xff0c;市场在今天也给出正面回应&#xff0c;股价再次上扬&#xff0c;最高点达57.10…

最快实现一个自己的扫地机

​ 作者&#xff1a;良知犹存 转载授权以及围观&#xff1a;欢迎关注微信公众号&#xff1a;羽林君 或者添加作者个人微信&#xff1a;become_me 扫地机介绍 扫地机器人行业本质是技术驱动型行业&#xff0c;产品围绕导航系统的升级成为行业发展的主旋律。按功能划分&a…

python基于协同过滤推荐算法的电影观后感推荐管理系统的设计

本课题所设计的影单管理系统&#xff0c;使用B/S架构&#xff0c;Python语言进行开发&#xff0c;它的优点代码不能从浏览器查看&#xff0c;保密性非常好&#xff0c;比其他的影单管理更具安全性。Python还容易修改和调试&#xff0c;毕竟影视是在不断发展过程中&#xff0c;难…

C++知识第三篇之继承

C继承 继承是面向对象编程的重要特征&#xff0c;是对类设计层次的复用 文章目录 C继承一.介绍1.继承定义2.继承方式3.class与struct 二.作用域1.成员变量2.成员函数 三.赋值转换1.给基类对象赋值2.给基类对象指针赋值 四.派生类的默认函数五. 其他1.友元2.静态 六.继承1.单继承…