位运算基础
&运算:有0就是0
示例:
|运算:有1就是1
示例:
^运算:相同为0,相异为1
示例:
后面学到其它位运算再补!
面试题 01.01. 判定字符是否唯一 - 力扣(LeetCode)
解法一:使用哈希表思路
1、0~26的小写字母(所以我们开25空间的哈希表数组)
2、扫描一次字符串,当出现第一次就++,再继续扫描,如果同样的也就是++,我们可以特判,此时大于1就是重复了,直接false,否则继续扫描,扫描完没有重复就true
class Solution { public: bool isUnique(string astr) { // 创建一个长度为26的整型数组,用来记录26个小写字母出现的次数 // 下标0对应'a',下标1对应'b',...,下标25对应'z' // 初始值全部为0,表示所有字母都还没出现过 int haxi[26] = {0}; // 遍历字符串中的每一个字符 // i从0开始,到字符串长度-1结束 for (int i = 0; i < astr.size(); i++) { // 计算当前字符对应的数组下标 // 例如:'a'-'a'=0,'b'-'a'=1,'c'-'a'=2 // 这样就能把字母映射到数组的对应位置 int index = astr[i] - 'a'; // 将该字母的出现次数加1 // 第一次出现:0变成1;第二次出现:1变成2 haxi[index]++; // 检查该字母是否已经重复出现 // 如果出现次数大于1,说明之前已经出现过一次了 // 现在又遇到一次,所以字符串中有重复字符 if (haxi[index] > 1) { return false; // 发现重复,直接返回false,结束函数 } } // 如果遍历完整个循环都没有返回false // 说明所有字符都只出现了一次,没有重复 return true; } };解法二:位图
利用位图思想,每一个比特位代表的是字符,并且int变量里面的32位足够表示所有的小写字母了,当比特位里面如果是0就是没有出现,如果是1就表示出现过了
注意优化:当他的字符串要是27位是不是就表示,他必定有重复的字符串?
class Solution { public: bool isUnique(string astr) { // 优化 if(astr.size()>26)return false; int arr=0; for(auto c : astr) { // 字符转数字 int i = c -'a'; // 取字符是不是1,是1就是出现过 if(((arr>>i) & 1) == 1)return false; // 出现过了,装进去 arr |= 1<<i; } return true; } };268. 丢失的数字 - 力扣(LeetCode)
这题隐约在牛客周赛刷到过,好像cf也有,年代太久了,那我这次就带大家学一下,自己也复习一遍
方法一:哈希表
开一个哈希表,扫描一下原来的数组,把数组里面的数字映射到哈希表,然后哈希表改成1,最后在扫描一下哈希表,如果是0就是丢失的数字
class Solution { public: int missingNumber(vector<int>& nums) { int haxi[10005] = {0}; for(auto c : nums) { haxi[c]=1; } for(int i=0;i<n;i++) { if(haxi[i]==0) { return i; } } return -1; } };方法二:高斯求和
把数字的1~n的下标给求和起来,记住一定是下标,最后的值减去数组里面的值就是丢失的数字。
例如:【3,0,1】,下标求和是6,6-3-1=2,那这个不就是丢失的数字吗?
class Solution { public: int missingNumber(vector<int>& nums) { int n = nums.size(); int sum = (1+n)*n; int result = sum/2; for(auto c : nums) { result-=c; } return result; };方法3:位运算(消消乐异或和)
最简单的理解,异或和就是一样的可以消掉
例如:【3,0,1】
【0,1,2,3】
0,1,3是不是消掉了,剩下2?
class Solution { public: int missingNumber(vector<int>& nums) { int ret=0; for(auto c : nums) ret^=c; for(int i=0;i<nums.size()+1;i++) ret^=i; return ret; };