首页 > 编程语言 >02-异或算法

02-异或算法

时间:2023-11-09 09:15:51浏览次数:32  
标签:02 arr int ++ 算法 eor 异或 ans

2. 异或算法

2.1 异或基础

  1. 0^N == N N^N == 0;
  2. 记为无进位相加即可,1+1 = 0;
  3. 异或运算满足交换律和结合。

2.1.1 不用额外变量交换两个数

解法:aba = b,abb = a。

2.1.2 找出现奇数次的数

1. 题目

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

2. 思路

​ 数组里每个元素都异或,两两相消,就只剩下奇数次的那个数

3. 代码

public static void main(String[] args) {
    int[] arr = {1,3,4,1,3,4,1,3,4,5,1,3,4};
    int ans = 0;
    for (int i = 0; i < arr.length; i++) {
        ans ^= arr[i];
    }
    System.out.println(ans);
}

2.2 提取右侧(最低位)的1

1. 题目

​ 怎么把一个int类型的数,提取出最右侧(最低位)的1来

2. 思路

1. 取反加一再和原来相与 a&(~a+1)

​ 取反:这样每一位都不一样,之前的0位置都变成了1,假设此时的值为b。

​ 加一:这样在右面+1就可以让他一直进位直到第一个0(也就是没取反的时候的1的位置),假设此时值为c。

​ 相与:此时c的状态是最低的1往右的值都是0,最低一位的1的位置和a相同,这一位再往右每一个都是不一样的,所以相与之后,直接就可以得到结果。

注意: ~a+1 就等于-a,所以也可以写成a&(-a)

2. 直接暴力

​ 先找位置,然后再把1右移

3. 代码

取反加一:

System.out.println((a&(~a+1)));
System.out.println((a&(-a)));

暴力:

private static int findRightest(int a) {
    int rightPos = 0;
    // 找最低位的1
    for(int i = 0; i < 32; i++){
        if((a & 1) == 1){
            rightPos = i;
            break;
        }
        a = a>>1;
    }

    a = 1;
    // 右移
    for (int i = 0; i < rightPos; i++) {
        a = a << 1;
    }
    System.out.println(a);
    return a;
}

2.3 找到两种奇数数

1. 题目

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

2. 思路

​ 全部异或,只留下eor = a^b

​ 因为a != b,所以二进制的ab至少有一位不一样,即eor != 0,也就是至少存在一位为1。

​ 既然有一位为1,代表a,b在这一位不同(异或:同0异1),那么就可以通过这一位来区分数组。

​ 这一位为0的放一边,为1的放一边,分别异或,这样得到的数就可以区分出来ab了。

只要是eor有一位为1就可以区分,具体是哪个无所谓,所以不妨设是最右侧的一个。

3. 代码

private static int[] getAB(int[] arr) {
    // 先异或,得到eor=a^b;
    int eor = 0;
    for (int i = 0; i < arr.length; i++) {
        eor ^= arr[i];
    }
    // 对于ab,最右侧一位的1提取出来
//        System.out.println(eor);
    int rightest = eor&(-eor);
//        System.out.println(rightest);
    // 根据这一位来区分属于谁
    // 不妨设a在这位为0,b在这位为1
    int[] ans = new int[2];
    for (int i = 0; i < arr.length; i++) {
        if((arr[i] & rightest) == 0){
            ans[0] ^= arr[i];
        }else{
            ans[1] ^= arr[i];
        }
    }
    return ans;
}

2.4 找到出现k次的数

1. 题目

​ 一个数组中有一种数出现K次,其他数都出现了M次,M > 1, K < M,

​ 要求:找到出现了K次的数,额外空间复杂度O(1),时间复杂度O(N)

2. 思路

​ 利用长度为32的数组,记录下每一位置出现1的次数,模M除K就得到二进制的所求数,再转为十进制。

3. 代码

private static int findKTimes(int[] arr, int m, int k) {
    int[] times = new int[32];
    // 记录所有数的32位的出现的次数
    for (int i = 0; i < arr.length; i++) {
        for (int j = 0; j < times.length; j++) {
            if((arr[i]&(1<<j)) != 0){
                times[j] ++;
            }
        }
    }
//        Arrays.stream(times).forEach(System.out::println);
    // 所有数%m/k 得到的数组合成int
    int ans = 0;
    for (int i = 0; i < times.length; i++) {
        times[i] = times[i]%m/k;
    }

    // 组合成int
    for (int i = 0; i < times.length; i++) {
        // cur = 1 1 0 1
        // times = 1 0 1 1
        ans += (times[i]<<i);
    }
    return ans;
}

标签:02,arr,int,++,算法,eor,异或,ans
From: https://www.cnblogs.com/ylw-blogs/p/17818899.html

相关文章

  • 2023ICPC南京站回忆录
    某种程度上来说集齐了金银铜铁,南京也因此成了刻在心底里的一道深深的痕迹。============================icpc南京站赛后总结  打得一言难尽,分析起来又说来话长。最后是3题,罚时很多,离铜线10名左右。如果罚时少一点也不至于打铁。如果能再开一题也不至于打铁。罚时多的原因:......
  • Matlab决策树、模糊C-均值聚类算法分析大学教师职称学历评分可视化
    全文链接:https://tecdat.cn/?p=34203原文出处:拓端数据部落公众号本文使用Matlab编程语言中的决策树和模糊C-均值聚类算法,帮助客户对大学教师职称、学历与评分之间的关系进行深入分析。背景随着高等教育的快速发展,教师队伍的素质和能力成为了影响高校发展的重要因素。职称和学......
  • 【misc】[HNCTF 2022 Week1]calc_jail_beginner(JAIL) --沙盒逃逸
    这是一道python沙盒逃逸的题目:沙箱逃逸:就是在给我们的一个代码执行环境下,脱离种种过滤和限制,最终成功拿到shell权限的过程,其实就是闯过重重黑名单,最终拿到系统命令执行权限的过程,这里不理解没关系,多做两道题就知道了,老实说国内的沙箱逃逸的题不是很多,而且大多都是面向新手的?对......
  • 2023年11月8日模拟赛
    这里观看体验更佳总结今天是模拟赛。还是比较难的。但是暴力能拿到210pts。说什么好呢。好像也没有什么好说的。感觉似乎还是那样。今天hyb生病了。可怜,希望他快点好起来。以前总是能在这个地方水一些东西,现在不想水了乎哉。题解今天的题思维和代码能力各需参半。看起来这......
  • CSP-S 2023 T1 题解
    CSP-S2023T1题解很简单,我们只需要暴力枚举五位密码,每次判断拨一个齿轮和两个齿轮能达到的状态数,如果等于\(n\),答案\(+1\)。时间复杂度\(O(10^5\times5n)\)。code#include<iostream>#include<algorithm>#include<cmath>#include<cstring>usingnamespacestd;......
  • CSP 2023 游只因
    CSP\(2023\)游只因前面不写太多。Day\(-\frac{114514}{191}\)雅礼(HN四大名校)集训。Day1:考试,讲题,改题。Day2:考试,讲题,改题。Day3:考试,讲题,改题。……Day\(0\)在雅礼开了会,然后教练复习知识,讲注意事项。晚上次火锅,然后van到了\(12\)点。Day\(1\)morning\(6:......
  • 2023版全新高质量商业级小程序全栈项目实战22章完结
    点击下崽:2023版全新高质量商业级小程序全栈项目实战22章完结  提取码:fxso小程序全栈项目是一种将前端、后端和数据库等技术结合起来,实现一个完整的小程序应用的项目。全栈项目可以让开发者更加高效地开发小程序,同时也可以提高小程序的性能和稳定性。本文将介绍如何构建一个小程......
  • 马上就要2024年了,Flutter还值得学习吗?
    为啥要学习Flutter最近突然想学习一下Flutter,不知道是哪个贤人说:学习就是先要把书读薄,然后再把书读厚。感觉非常有道理,所以在自学的过程中试试能不能三言两语说清楚一个知识点。如果是零基础想进入移动端开发的话,那么还是建议选择一种原生开发来学习,Flutter只是作为技术储备的扩充......
  • 分享2023全新GO工程师面试总攻略,助力快速斩获offer
    点击下崽:分享2023全新GO工程师面试总攻略,助力快速斩获offer  提取码:k8c8GO(Golang)是一种快速、高效、牢靠、平安的编程言语,被普遍应用于后端开发、云计算、人工智能等范畴。在GO工程师面试中,面试官通常会调查我们的编程才能、系统设计才能、算法和数据构造等方面的学问。本文将引......
  • 2023.11.8 近期杂题
    CF1797E设\(f(x,y)\)表示\(x,y\)要相同最大的变成多少。由于\(\varphi\)最多只需要做\(\log\)次就可以到\(1\),所以这是可以直接暴力的。我们现在只需维护区间\(f\)的值,外加区间取\(\varphi\)。区间取\(\varphi\)暴力。使用”小清新“线段树,或者用并查集。复杂......