《算法题讲解指南:优选算法-位运算》--33.判断字符是否唯一,34.丢失的数字

《算法题讲解指南:优选算法-位运算》--33.判断字符是否唯一,34.丢失的数字

🔥小叶-duck个人主页

❄️个人专栏《Data-Structure-Learning》

《C++入门到进阶&自我学习过程记录》《算法题讲解指南》--从优选到贪心

未择之路,不须回头
已择之路,纵是荆棘遍野,亦作花海遨游


目录

位运算基础前置知识:

位1的个数

比特位计数

汉明距离

只出现一次的数字

只出现一次的数字|||

34. 判断字符是否唯一

题目链接:

题目描述:

题目示例:

解法(位图的思想):

算法思路:

C++算法代码:

算法总结及流程解析:

35. 丢失的数字

题目链接:

题目描述:

题目示例:

解法(位运算):

算法思路:

C++算法代码:

算法总结及流程解析:

结束语


位运算基础前置知识:

      回顾了上面位运算基础前置的知识这里有五道非常简单的题可以试试手,都是考察位运算的题目:

位1的个数

191. 位1的个数 - 力扣(LeetCode)

C++算法代码:

class Solution { public: int hammingWeight(int n) { int count = 0; while(n) { n &= (n - 1); count++; } return count; } };

比特位计数

338. 比特位计数 - 力扣(LeetCode)

C++算法代码:

class Solution { public: vector<int> countBits(int n) { vector<int> ans(n + 1, 0); for(int i = 0; i <= n; i++) { int count = 0; int num = i; while(num) { num &= (num - 1); count++; } ans[i] = count; } return ans; } };

汉明距离

461. 汉明距离 - 力扣(LeetCode)

C++算法代码:

class Solution { public: int hammingDistance(int x, int y) { int count = 0; int ret = x ^ y; while(ret) { ret &= (ret - 1); count++; } return count; } };

只出现一次的数字

136. 只出现一次的数字 - 力扣(LeetCode)

C++算法代码:

class Solution { public: int singleNumber(vector<int>& nums) { int val = 0; for(auto e : nums) { val ^= e; } return val; } };

只出现一次的数字|||

260. 只出现一次的数字 III - 力扣(LeetCode)

C++算法代码:

class Solution { public: if(nums.size() == 2) { return nums; } sort(nums.begin(), nums.end()); vector<int> res; int ans = 0; for(int i = 0; i < nums.size(); i++) { ans ^= nums[i]; } for(int i = 0; i < nums.size(); i += 2) { if(nums[i] != nums[i + 1]) { res.push_back(nums[i]); ans ^= nums[i]; break; } } res.push_back(ans); return res; } };

34. 判断字符是否唯一

题目链接:

面试题 01.01. 判定字符是否唯一 - 力扣(LeetCode)

题目描述:

题目示例:

解法(位图的思想):

算法思路:

      利用【位图】的思想,每一个【比特位】代表一个【字符,一个 int 类 型的变量 32 位足够表示所有的小写字母。比特位里面如果是 0,表示这个字符没有出现过。比特位里面的值是 1,表示该字符出现过
      那么我们就可以用一个【整数】来充当【哈希表】。

C++算法代码:

class Solution { public: bool isUnique(string astr) { //解法一:数组模拟实现哈希表 //解法一通过模拟实现哈希表来存放每个字符映射到数组的对应位置 //代码非常简单,这里就不演示了,而且因为需要额外使用数据结构不算加分项 //解法二:位图(不需要使用额外的数据结构) if(astr.size() > 26) { return false; } int m = 0; //作为比特位哈希表,通过一个数的二进制表示每个比特位存放对应的字符 for(int i = 0; i < astr.size(); i++) { //先判断当前字符是否在比特位哈希表中存在过 if(m >> (astr[i] - 'a') & 1) { return false; } //如果判断为假则该字符没有出现过,则相对应的比特位从0变成1 m = m | (1 << (astr[i] - 'a')); } return true; } };

算法总结及流程解析:

35. 丢失的数字

题目链接:

268. 丢失的数字 - 力扣(LeetCode)

题目描述:

题目示例:

解法(位运算):

算法思路:

      设数组的大小为 n ,那么缺失之前的数就是【0,n】,数组中是在【0,n】中缺失一个数形成的序列如果我们把数组中的所有数,以及【0,n】中的所有数全部【异或】在一起,那么根据【异或】运算的【消消乐】规律,最终的异或结果应该就是缺失的数

C++算法代码:

class Solution { public: int missingNumber(vector<int>& nums) { //解法一:高斯求和 // int ret = 0; // for(int i = 0; i < nums.size(); i++) // { // ret += (i + 1); // ret -= nums[i]; // } // return ret; //解法二:位运算 int ret = 0; for(int i = 0; i < nums.size(); i++) { ret ^= nums[i] ^= (i + 1); } return ret; } };

算法总结及流程解析:

结束语

      到此,33.判断字符是否唯一,34.丢失的数字 这两道算法题就讲解完了。通过两道经典例题讲解位图与异或技巧。33题利用位图思想,用整数比特位标记字符出现情况,实现O(1)空间复杂度判断字符唯一性。34题运用异或消消乐特性,通过数组与完整序列异或找出缺失数字。希望大家能有所收获!

Read more

从GetDiagnostics到C++全栈诊断:开发者必备的排障与调试工具集

文章目录 * 从GetDiagnostics到C++全栈诊断:开发者必备的排障与调试工具集 * 一、GetDiagnostics:通用诊断信息采集的“瑞士军刀” * 1. 什么是GetDiagnostics? * 2. 主流场景下的GetDiagnostics用法 * 场景1:PowerShell中的诊断数据采集(最常用) * 场景2:SQL中的执行诊断(错误处理必备) * 场景3:.NET/SCOM中的诊断规则查询 * 3. GetDiagnostics使用核心要点 * 二、C++开发全流程必备工具集 * 1. 编译/语法检查工具:提前拦截基础错误 * (1)GCC/Clang:自带警告与诊断能力 * (2)CMake:构建过程诊断 * 2. 调试工具:定位运行时逻辑错误 * (1)GDB:跨平台命令行调试器 * (2)LLDB:Clang配套调试器(macOS/Linux优先) * (3)Visual

By Ne0inhk
【Linux系统】C/C++的调试器gdb/cgdb,从入门到精通

【Linux系统】C/C++的调试器gdb/cgdb,从入门到精通

各位读者大佬好,我是落羽!一个坚持不断学习进步的学生。 如果您觉得我的文章还不错,欢迎多多互三分享交流,一起学习进步! 也欢迎关注我的blog主页:落羽的落羽 文章目录 * 一、调试前的预备知识 * 二、gdb/cgdb的使用 * 1. 启动,查看代码 * 2. 基础调试命令 * 3. 监视变量相关命令 * 4. 设置条件断点 一、调试前的预备知识 程序发布的方式有两种,debug模式和release模式。 * debug模式:生成的可执行程序中会包含程序的调试信息,便于程序员进行调试代码。 * release模式:会剥离或不生成这些调试信息。这使得文件更小,但也意味着调试器几乎无法工作,release版本程序无法进行调试。 Linux的gcc/g++,按照我们之前的写法gcc -o $@ $^,默认生成的是release版本的程序,是无法进行调试的。要在命令后加-g选项,指定以debug方式发布,debug模式下的程序我们才能进行调试。 gcc -o $@ $^ -g 二、gdb/cgdb的使用

By Ne0inhk
纸上谈“型”不如运行识“真”:深入 C++ RTTI 与多态的底层真相!

纸上谈“型”不如运行识“真”:深入 C++ RTTI 与多态的底层真相!

文章目录 * 本篇摘要 * RTTI(Run-Time Type Information,运行时类型信息) 介绍 * RTTI 的核心组成 * 1. `typeid` 运算符 * 2. `dynamic_cast` 运算符 * RTTI 如何工作?(底层原理) * ① 编译器为多态类型做了什么? * ② 当我们调用对应接口,RTTI底层是如何实现呢? * **`场景 1:typeid(obj)`** * 场景 2:dynamic_cast<Derived*> ( p ) * `std::type_info` 类简介 * RTTI 的开销与争议 * 优点: * 缺点: * 何时使用 RTTI? * 禁用 RTTI操作 * 为什么非多态类型不支持 RTTI? * 总结

By Ne0inhk
【Linux】Linux 进程通信:System V 共享内存(最快方案)C++ 封装实战 + 通信案例,4 类经典 Bug 快速修复

【Linux】Linux 进程通信:System V 共享内存(最快方案)C++ 封装实战 + 通信案例,4 类经典 Bug 快速修复

前言:欢迎各位光临本博客,这里小编带你直接手撕**,文章并不复杂,愿诸君**耐其心性,忘却杂尘,道有所长!!!! IF’Maxue:个人主页  🔥 个人专栏: 《C语言》 《C++深度学习》 《Linux》 《数据结构》 《数学建模》 ⛺️生活是默默的坚持,毅力是永久的享受。不破不立! 文章目录 * 二、System V共享内存:最快的进程间通信 * 1. System V共享内存核心概念 * 2. System V共享内存原理 * (1)进程虚拟地址空间结构 * (2)共享内存映射过程 * (3)共享内存的管理:先描述,再组织 * 3. System V共享内存核心接口 * (1)生成唯一Key:ftok * (2)创建/获取共享内存:shmget

By Ne0inhk