【算法】【优选算法】位运算(下)

目录

  • [一、:⾯试题 01.01.判定字符是否唯⼀](#一、:⾯试题 01.01.判定字符是否唯⼀)
    • [1.1 位图](#1.1 位图)
    • [1.2 hash思路](#1.2 hash思路)
    • [1.3 暴力枚举](#1.3 暴力枚举)
  • 二、268.丢失的数字
    • [2.1 位运算,异或](#2.1 位运算,异或)
    • [2.2 数学求和](#2.2 数学求和)
  • 三、371.两整数之和
  • [四、137.只出现⼀次的数字 II](#四、137.只出现⼀次的数字 II)
  • [五、⾯试题 17.19.消失的两个数字](#五、⾯试题 17.19.消失的两个数字)

一、:⾯试题 01.01.判定字符是否唯⼀

题目链接::⾯试题 01.01.判定字符是否唯⼀

题目描述:

题目解析:

  • 给一个字符串,看字符串中字符是否有重复,有返回false,没有返回true。

1.1 位图

解题思路:

  • 因为这个字符串全是小写字符,所以只有26个字符,并且求得是是不是有重复。
  • 那么我们就可以使用一个int的32个比特位来表示,字符'a'到'z'分别对应二进制的0到25下标。
  • 如果下标变成1,后出现了该下标对应的字母,那么就是有重复字符。
  • 拿到二进制第 i 位是1还是0:(x >> i) & 1
  • 将二进制第 i 位变为1:x = x | (1 << i)

解题代码:

java 复制代码
//时间复杂度:O(N)
//空间复杂度:O(1)
class Solution {
    public boolean isUnique(String astr) {
        if(astr.length() > 26) return false;
        int bit = 0;
        for(int i = 0; i < astr.length(); i++) {
            int temp = bit;
            if( ( (temp >> astr.charAt(i) ) & 1) == 1) return false;
            bit = bit | ( 1 << astr.charAt(i));
        }
        return true;
    }
}

1.2 hash思路

解题思路:

  • 使用一个hash数组来记录每个字符出现的次数,因为全是小写字母,只需申请有效空间即可。

解题代码:

java 复制代码
//时间复杂度:O(N)
//空间复杂度:O(1)
class Solution {
    public boolean isUnique(String astr) {
        if(astr.length() > 26) return false;
        int[] hash = new int[26];
        for(int i = 0; i < astr.length(); i++) {
            if(hash[astr.charAt(i)-'a'] != 0) return false;
            hash[astr.charAt(i)-'a']++;
        }
        return true;
    }
}

1.3 暴力枚举

解题思路:

  • 直接两层for循环遍历,第一层遍历字符,第二层在剩下字符串种找是否有相同字符。

解题代码:

java 复制代码
//时间复杂度:O(n^2)
//空间复杂度:O(1)
class Solution {
    public boolean isUnique(String astr) {
        if(astr.length() > 26) return false;
        for(int i = 0; i < astr.length(); i++) {
            for(int j = i+1; j < astr.length(); j++) {
                if(astr.charAt(i) == astr.charAt(j)) return false; 
            }
        }
        return true;
    }
}

二、268.丢失的数字

题目链接:268.丢失的数字

题目描述:

题目解析:

  • 给一个长度为n的数组,数组中在 0 , n 中只有一个数字没包含,返回这个数字。

2.1 位运算,异或

解题思路:

  • 将数组中的元素一一进行异或运算,同时与 0 , n 的数字进行异或运算。
  • 到最后这剩下数组中没有的元素,没有与相同数字进行异或运算,最后就只剩下他了。

解题代码:

java 复制代码
//时间复杂度:O(n)
//空间复杂度:O(1)
class Solution {
    public int missingNumber(int[] nums) {
        int ret = 0;
        for(int i = 0; i < nums.length; i++) {
            ret = ret ^ i ^ nums[i];
        }
        return ret ^ nums.length;
    }
}

2.2 数学求和

解题思路:

  • 先将 0 , n 的和求出来。然后遍历数组,减去数组中元素。最后剩下的就是要求的数字。

解题代码:

java 复制代码
//时间复杂度:O(n)
//空间复杂度:O(1)
class Solution {
    public int missingNumber(int[] nums) {
        int n = nums.length;
        int sum = (n+1) * n / 2;
        for(int i = 0; i < n; i++)
            sum -= nums[i];
        return sum;
    }
}

三、371.两整数之和

题目链接:371.两整数之和

题目描述:

题目解析:

  • 不使用加法,算a+b

解题思路:

  • 使用异或,异或是无进位相加。
  • 那么我们只需要将要进位的地方记录下来,要进位的地方是两个数都是1才进位。也就是 按位与的结果,但是下一次异或的是,上一次按位与结果左移一位的结果。
  • 所以我们最多按位异或,按位与32次。

解题代码:

java 复制代码
//时间复杂度:O(1)
//空间复杂度:O(1)
class Solution {
    public int getSum(int a, int b) {
        while( b != 0) {
            int temp = a;
            a = a ^ b;
            b = (temp & b) << 1;
        }
        return a;
    }
}

四、137.只出现⼀次的数字 II

题目链接:137.只出现⼀次的数字 II

题目描述:

题目解析:

  • 给一个数组,数组中只有一个元素只出现一次,其余全出现了3次,返回只出现一次的那个元素。

解题思路:

  • 当我们将数组中元素的每一位比特位求和之后,假设只出现一次的数的比特位上是x,那么每位上的和都是3n+x。n就代表出现3次的元素的比特位求一次和的结果。
  • 所以当我们将和对3取余后,那么该比特位上的值就和要求元素一样了。

解题代码:

java 复制代码
//时间复杂度:O(n)
//空间复杂度:O(1)
class Solution {
    public int singleNumber(int[] nums) {
        int ret = 0;
        for(int i  = 0; i < 32; i++) {
        	//求比特位之和
            int sum = 0;
            for(int x : nums) {
                sum += ( (x>>i) & 1);
            }
            //修改结果对应比特位
            sum %= 3;
            if(sum == 1) ret = ret | (1 << i);
        }
        return ret;
    }
}

五、⾯试题 17.19.消失的两个数字

题目链接:⾯试题 17.19.消失的两个数字

题目描述:

题目描述:

  • 给一个数组,这个数组在 1 , nums.length + 2区间有两个数不包含,找到并返回。

解题思路:

  • 其实这道题跟上一篇的第六道是一道题。
  • 先将所有的元素(数组元素和 1 , nums.length + 2 的数)全部异或在一起,就相当于两个只出现一次的元素异或在一起。
  • 在去出上诉异或结果,最右边的1。这位上两个数字是不相同的。
  • 所以再次遍历数组与结果数组异或,如果该位上与第二步结果相同放一个下标,不同放另一个下标。最后得到的就是结果了

解题代码:

java 复制代码
//时间复杂度:O(n)
//空间复杂度:O(1)
class Solution {
    public int[] missingTwo(int[] nums) {
        int n = nums.length;
        int[] ret = new int[2];
        int last = 0;
        for(int i = 0; i <= n+2; i++) {
            if(i < n) last ^= nums[i];
            
            last ^= i;
        }
        last = last & -last;
        for(int i = 0; i <= n+2; i++) {
            if(i < n) {
                if((last & nums[i]) == 0)  ret[0] ^= nums[i];
                else ret[1] ^= nums[i];
            }
            if((last & i) == 0) ret[0] ^= i;
            else  ret[1] ^= i;
            
        }
        return ret;
    }
}
相关推荐
大明者省2 小时前
WSL2 Ubuntu22.04 GPU训练环境配置指南
人工智能·算法·计算机视觉
白狐_7984 小时前
408数据结构第8章:排序②——性质对比秒杀、场景选择与外部排序
java·数据结构·算法
zander2584 小时前
LeetCode 84:柱状图中的最大矩形——单调栈如何确定左右边界
java·数据结构·算法
Shell运维手记5 小时前
Linux 常用基础命令学习笔记
linux·运维·笔记·学习·算法·github
杨航 AI5 小时前
O(n log n):线性对数原理拆解 这个是排序算法的黄金复杂度之一。
算法·排序算法
船厂电气自动化ai大模型5 小时前
AI大模型与数学 第32课 函数凹凸性与二阶导数:拐点求解、凹凸区间计算(10道二阶导数计算题)
数据结构·人工智能·python·深度学习·算法
旖旎夜光6 小时前
LeetCode 3:无重复字符的最长子串(滑动窗口) —— 题解
数据结构·c++·算法·leetcode·滑动窗口
叠层归一研究院7 小时前
AGI 系统(十一):二阶网络 — 二阶递归 × 多主体 (元符号网络)
开发语言·人工智能·算法·php·agi
zlinear数据采集卡7 小时前
D223的PWM电机控制:6路独立脉冲+加减速算法深度解析
arm开发·stm32·嵌入式硬件·算法·fpga开发·架构
杨石兴8 小时前
31、玩具MoM:用2x2矩阵串起全套流程
人工智能·算法·矩阵·电磁学