优选算法2

五、位运算

常见位运算总结

&:有0就是0;

|:有1就是1

^:相同为0,相异就是1/无进位相加

给定一个数n,确定它的二进制表示中的第x位是0还是1:二进制中权值最小的是第0位,所以int整型是从第0位到第31位。于是n>>x &1就可以了

将一个数n的二进制表示的第x位修改成为1: (1<<x) | n

将一个数n的二进制表示的第x位修改成为0:(~(1<<x)) & n 

提取一个数n的二进制表示中最右侧的1:n&(-n),正数变成负数的二进制表示就是按位取法再加1。-n的本质是将最右侧的1的左边区域(不包括最右侧的1也就是当前位置)全部变成相反,其余的都不变。

干掉一个数n二进制表示中最右侧的1,也就是将这个1变成0:n&(n-1) ,n-1的本质是将最右侧的1右边的区域(包含1)全部变成相反。

异或:a^a=0;a^0=a;a^b^c=a^(b^c);交换律;采用无进位相加很容易证明 

 1.判断字符是否唯一


采用位图的思想:因为单独的一个整型变量就有32位比特位

优化点:鸽巢原理,也就是如果字符串的长度超过26,必定存在重复字符。

class Solution {
public:bool isUnique(string astr) {//利用鸽巢原理进行优化if(astr.size()>26) return false;int bitmap=0;for(auto ch:astr){//判断字符出现在哈希表中if((1<<(ch-'a')) & bitmap) return false;//将当前字符加入到位图中else bitmap+=(1<<(ch-'a'));//bitmap |= (1<<(ch-'a'))}return true;}
};

2.丢失的数字

class Solution {
public:int missingNumber(vector<int>& nums) {int n=nums.size()+1;int result=0;for(auto ch:nums) result^=ch;for(int i=0;i<n;i++) result^=i;return result;}
};

3.两整数之和(巧妙)



利用异或的无进位相加,然后找到需要进位的地方。通过a&b可以找到需要进位的地方,因为只有1&1才能得到1,而这也是我们需要进位的地方。(a&b)<<1才是我们需要进位的位置。

class Solution {
public:int getSum(int a, int b) {while(b){int temp_a=a;a=temp_a^b;//先算出无进位相加的结果b=(temp_a&b)<<1;//算出进位}return a;}
};

4.只出现一次的数字


 

class Solution {
public:int singleNumber(vector<int>& nums) {int ret=0;for(int i=0;i<32;i++)//依次去修改ret中的每一位{int sum=0;//统计nums中第i比特位出现1的次数for(auto ch:nums)if(ch & (1<<i)) sum++;if(sum%3) ret |= (1<<i);//修改ret的第i比特位}return ret;}
};

5.消失的两个数

  

class Solution {
public:vector<int> missingTwo(vector<int>& nums) {vector<int> result;//将所有的数全部都异或到一起int tmp=0;int n=nums.size();for(auto ch:nums) tmp^=ch;for(int i=1;i<=n+2;i++) tmp^=i;//找到tmp中,比特位为1的那一位pos,在该比特位上a和b的比特值是不一样的。int pos;for(pos=0;pos<32;pos++) if((tmp>>pos)&1) break;//根据pos位的不同,划分成为两类来异或int a=0,b=0;for(auto ch:nums){if((ch>>pos)&1) a^=ch;else b^=ch;}for(int i=1;i<=n+2;i++){if((i>>pos)&1) a^=i;else b^=i;}return {a,b};}
};

六、模拟算法

模拟算法就是依葫芦画瓢,思路比较简单,但是算法流程存在很多细节,将流程转换成为算法有比多要注意的细节。模拟题找优化一般都是通过找规律进行的。

6.替换所有的问号

class Solution {
public:string modifyString(string s) {int n=s.size();//遍历字符串for(int i=0;i<n;i++){//找到?字符if(s[i]=='?'){//遍历26个字母替换该字符for(char ch='a';ch<='z';ch++){//找到符合要求的字符,下面的if条件是关键if((i==0 || ch!=s[i-1]) && (i==n-1 || ch!=s[i+1])){s[i]=ch;break;}}}}return s;}
};

7.提莫攻击


 

class Solution {
public:int findPoisonedDuration(vector<int>& timeSeries, int duration) {int result=0;for(int i=0;i<timeSeries.size()-1;i++){if(timeSeries[i+1]-timeSeries[i]>=duration) result+=duration;else result+=(timeSeries[i+1]-timeSeries[i]);}return result+duration;}
};

8.Z字形变换


class Solution {
public:string convert(string s, int numRows) {//处理边界情况if(numRows==1) return s;string result;int n=s.size();int d=numRows*2-2;//公差d//1.先处理第一行for(int i=0;i<n;i+=d){result+=s[i];//}//2.处理中间行for(int k=1;k<numRows-1;k++)//枚举每一行{for(int i=k,j=d-k;i<n || j<n;i+=d,j+=d)//注意不要将i<n || j<n写成了i<n && j<n{if(i<n) result+=s[i];if(j<n) result+=s[j];}}//3.最后处理最后一行for(int i=numRows-1;i<n;i+=d){result+=s[i];}return result;}
};

9.外观数列

class Solution {
public:string countAndSay(int n) {string result="1";if(n==1) return result;for(int i=1;i<n;i++)//翻译n次{string tmp;int len=result.size();//采用双指针来进行翻译for(int left=0,right=0;right<len;){while(right<len && result[left]==result[right]) right++;//当right=len-1的边界情况也可以正确处理tmp+=to_string(right-left);//to_string函数处理下标left和right的值不同的时候tmp+=result[left];left=right;}result=tmp;}return result;}
};

10.数青蛙


上述总结就是代码的逻辑非常重要

class Solution {
public:int minNumberOfFrogs(string croakOfFrogs) {string t="croak";int n=t.size();vector<int> hash(n);//用数组来模拟哈希表unordered_map<char,int> index;//存储t字符串每个字符char以及对应的下标intfor(int i=0;i<n;i++) index[t[i]]=i;//遍历字符串for(auto ch:croakOfFrogs){//1、如果ch不在字符串t的范围内if(index.count(ch)==0) return -1;//2、如果字符ch不是c并且前面并没有匹配的字符if(ch!=t[0] && hash[index[ch]-1]<1) return -1;//3、正常运作if(ch==t[0] && hash[n-1]<1) hash[0]++;else if(ch==t[0] && hash[n-1]>=1) hash[0]++,hash[n-1]--;else hash[index[ch]]++,hash[index[ch]-1]--;}for(int i=0;i<n-1;i++) if(hash[i]!=0) return -1;return hash[n-1];}
};

七、分治

分治就是分而治之,将一个大问题转换成为若干个相同或者相似的子问题,直到划分到子问题可以快速解决为止。

10.颜色分类(快排关键)


 

class Solution {
public:void sortColors(vector<int>& nums) {int n=nums.size();int left=-1,right=n;for(int i=0;i<right;)//条件是i<right不是i<n,这是一个易错点。{if(nums[i]==0) swap(nums[++left],nums[i++]);else if(nums[i]==1) i++;else swap(nums[--right],nums[i]);}}
};

 11.排序数组 (快排)

class Solution {
public:int getrandom(vector<int>& nums,int left,int right){int r=rand();return nums[r % (right-left+1) + left];}void sortArray_help(vector<int>& nums,int l,int r){//定义递归出口if(l>=r) return;//随机方式选择基准元素int standar=getrandom(nums,l,r);int left=l-1;int right=r+1;//分成三块for(int i=l;i<right;){if(nums[i]<standar) swap(nums[++left],nums[i++]);else if(nums[i]==standar) i++;else swap(nums[--right],nums[i]);  }sortArray_help(nums,l,left);sortArray_help(nums,right,r);}vector<int> sortArray(vector<int>& nums) {srand(time(NULL));//种下一棵随机数种子sortArray_help(nums,0,nums.size()-1);return nums;}
};

12.数组中的第k个最大元素

class Solution {
public:int getrandom(vector<int>&nums,int left,int right){int r=rand();return nums[r%(right-left+1)+left];}int qsort(vector<int>& nums,int l,int r,int k){if(l==r) return nums[l];//容易遗漏的点//1、随机选择基准元素int standard=getrandom(nums,l,r);//2、根据基准元素将数组分成三块int left=l-1;int right=r+1;int i=l;while(i<right){if(nums[i]<standard) swap(nums[++left],nums[i++]);else if(nums[i]==standard) i++;else swap(nums[--right],nums[i]);}//分情况讨论//下面的三个条件判断是关键if(r-right+1>=k) return qsort(nums,right,r,k);else if(r-left>=k) return standard;else return qsort(nums,l,left,k-r+left);}int findKthLargest(vector<int>& nums, int k) {srand(time(NULL));return qsort(nums,0,nums.size()-1,k);}
};

13.最小k个数(未做)

14.归并排序(归并排序)

class Solution {
public:vector<int> tmp;//辅助数组用来排序void mergesort(vector<int>& nums,int left,int right){if(right<=left) return;//1、选择中间点划分区间int mid=(left+right)/2; //2、将左右区间排序int left1=left;int right1=mid;int left2=mid+1;int right2=right;mergesort(nums,left1,right1);mergesort(nums,left2,right2);int i=0;//3、合并两个有序数组while(left1<=right1 && left2<=right2) tmp[i++]=nums[left1]<=nums[left2]?nums[left1++]:nums[left2++];//4、处理没有遍历完的数组while(left1<=right1) tmp[i++]=nums[left1++];while(left2<=right2) tmp[i++]=nums[left2++];//5、还原for(int i=left;i<=right;i++) nums[i]=tmp[i-left];     }vector<int> sortArray(vector<int>& nums) {tmp.resize(nums.size());mergesort(nums,0,nums.size()-1);return nums;}
};

15.交易逆序对的总数(未做)

class Solution {
public:int reversePairs_helper(vector<int>& nums,int left,int right){if(left>=right) return 0;int ret=0;//1、找中间点,将数组分成两部分int mid=(left+right)>>1;//2.左边的个数+排序+右边的个数+排序ret +=reversePairs_helper(nums,left,mid);ret +=reversePairs_helper(nums,mid+1,right);//3.一左一右的个数int cur1=left,cur2=mid+1,i=0;vector<int> tmp(right-left+2);while(cur1<=mid && cur2<=right){if(nums[cur1]<=nums[cur2]) tmp[i++]=nums[cur1++];else{ret+= mid-cur1+1;tmp[i++]=nums[cur2++];}}while(cur1<=mid) tmp[i++]=nums[cur1++];while(cur2<=right) tmp[i++]=nums[cur2++];for(int j=left;j<=right;j++)nums[j]=tmp[j-left];return ret;}int reversePairs(vector<int>& record) {return reversePairs_helper(record,0,record.size()-1);}
};

16.計算右側小於當前元素的個數

class Solution {vector<int> ret;vector<int> index;//记录nums当前元素的下标、int tmpNums[500010];int tmpIndex[500010];
public:vector<int> countSmaller(vector<int>& nums) {int n=nums.size();ret.resize(n);index.resize(n);for(int i=0;i<n;i++)index[i]=i;mergesort(nums,0,nums.size()-1);return ret;}void mergesort(vector<int>& nums,int left,int right)  {if(left>=right) return;int mid=(left+right)>>1;mergesort(nums,left,mid);mergesort(nums,mid+1,right);int cur1=left,cur2=mid+1,i=0;while(cur1<=mid && cur2<=right){if(nums[cur1]>nums[cur2]){tmpNums[i]=nums[cur1];ret[index[cur1]]+=right-cur2+1;tmpIndex[i]=index[cur1];i++;cur1++;}else{tmpNums[i]=nums[cur2];tmpIndex[i]=index[cur2];i++;cur2++;}}while(cur1<=mid){tmpNums[i]=nums[cur1];tmpIndex[i]=index[cur1];i++;cur1++;}while(cur2<=right){tmpNums[i]=nums[cur2];tmpIndex[i]=index[cur2];i++;cur2++;}for(int j=left;j<=right;j++){nums[j]=tmpNums[j-left];index[j]=tmpIndex[j-left];}}
};

17.翻转对

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/35325.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

坚持100天学习打卡Day1

1.大小端 2.引用的本质 及 深拷贝与浅拷贝 3.初始化列表方式 4.类对象作为类成员 5.静态成员 static

vue3使用v-html实现文本关键词变色

首先看应用场景 这有一段文本内容&#xff0c;是项目的简介&#xff0c;想要实现将文本中的关键词进行变色处理 有如下关键词 实现思路 遍历文本内容&#xff0c;找到关键词&#xff0c;并使用某种方法更改其字体样式。经过搜寻资料决定采用v-html实现&#xff0c;但是v-h…

解决pycharm安装dlib失败的问题

今天使用pycharm来学习opencv人脸识别库face-recognition的时候出现了一点小问题&#xff0c;在pycharm中直接安装face-recognition会失败&#xff0c;说是因为缺少依赖库dlib&#xff0c;但是直接使用pycharm安装dlib库也有问题&#xff0c;不知道大家遇到没有 错误提示 note…

【深度学习】菜品目标检测软件系统

深度学习类文章回顾 【YOLO深度学习系列】图像分类、物体检测、实例分割、物体追踪、姿态估计、定向边框检测演示系统【含源码】 【深度学习】物体检测/实例分割/物体追踪/姿态估计/定向边框/图像分类检测演示系统【含源码】 【深度学习】YOLOV8数据标注及模型训练方法整体流程…

AI智能写作工具,AI写作助手大全

随着人工智能技术的快速发展&#xff0c;AI智能写作工具助手已成为学术研究、内容创作和商业文案等领域的重要辅助工具。它们不仅能够提高写作效率&#xff0c;还能激发创意灵感&#xff0c;为各行各业的专业人士提供了强大的支持。下面小编将为大家全面介绍目前市场上备受瞩目…

[C#][opencvsharp]C#使用opencvsharp进行年龄和性别预测支持视频图片检测

使用 OpenCVSharp 来调用 age_net.caffemodel 和 gender_net.caffemodel 来进行性别和年龄预测涉及几个步骤。以下是一个简化的流程和示例文案&#xff1a; 1. 准备工作 确保你已经安装了 OpenCVSharp 和相关的依赖项。确保你有 age_net.prototxt、age_net.caffemodel、gende…

正版软件 | 『闪点清单』— 您的智能悬浮任务管理专家

在繁忙的日常中&#xff0c;我们经常需要一个既能随时提醒&#xff0c;又不会打扰我们的待办事项管理工具。『闪点清单』&#xff0c;一款简约而不简单的悬浮清单软件&#xff0c;为您带来全新的任务管理体验。 设计简约&#xff0c;功能强大 『闪点清单』以其简约的设计和强大…

CVPR讲座总结(二)-探索图像生成基础模型的最新进展探索多模态代理的最新进展:从视频理解到可操作代理

引言 在CVPR24上的教程中&#xff0c;微软高级研究员Linjie Li为我们带来了多模态代理的深入探索。这些代理通过整合多模态专家和大语言模型&#xff08;LLM&#xff09;来增强感知、理解和生成能力。本文总结了Linjie Li的讲座内容&#xff0c;重点介绍了多模态记忆、可操作代…

供应链攻击是什么?

随着企业对技术和连接性的依赖日益增加&#xff0c;以及对第三方的普遍依赖&#xff0c;供应链攻击变得越来越普遍。这些攻击旨在通过供应商和商业伙伴损害企业。 供应链攻击可能对企业和组织构成重大威胁&#xff0c;因为它们可能危及它们的安全以及向客户提供的产品和服务的…

《昇思25天学习打卡营第2天 | 张量 Tensor》

《昇思25天学习打卡营第2天 | 张量 Tensor》 《昇思25天学习打卡营第2天 | 张量 Tensor》 《昇思25天学习打卡营第2天 | 张量 Tensor》什么是张量&#xff08;Tensor&#xff09;张量的创建方式根据数据直接生成从NumPy数组生成使用init初始化器构造张量继承另一个张量的属性&a…

unity 导入的模型设置讲解

咱们先讲Model这一栏 Model Scene&#xff1a;场景级属性&#xff0c;例如是否导入灯光和照相机&#xff0c;以及使用什么比例因子。 Scale Factor&#xff1a;缩放因子&#xff08;也就是模型导入后大小如果小了或者大了在这里直接改是相当于该模型的大小的&#xff0c;而且在…

浏览器扩展V3开发系列之 chrome.runtime 的用法和案例

【作者主页】&#xff1a;小鱼神1024 【擅长领域】&#xff1a;JS逆向、小程序逆向、AST还原、验证码突防、Python开发、浏览器插件开发、React前端开发、NestJS后端开发等等 chrome.runtime API 提供了一系列的方法和事件&#xff0c;可以通过它来管理和维护 Chrome 扩展的生命…

什么!你还不会Redis?跟着我讲透Redis【上篇之初识与安装】

1 NoSQL是什么 1.1 NoSQL数据库概述 NoSQL(NoSQL Not Only SQL )&#xff0c;意即”不仅仅是SQL“&#xff0c;泛指非关系型的数据库。 NoSQL 不依赖业务逻辑方式存储&#xff0c;而以简单的key-value模式存储。因此大大的增加了数据库的扩展能力。 不遵循SQL标准。不支持A…

PKG打包sqlite3项目,如何添加node_sqlite3.node依赖

项目地址&#xff1a;https://github.com/helson-lin/pkg_sqlite 在ffandown项目内&#xff0c;由于项目使用了sqlite3&#xff0c;在跨平台打包的时候&#xff0c;除了本机外其他平台打包之后运行缺少node_sqlite3.node依赖。 为了解决问题&#xff0c;百度了很久&#xff0c…

思维导图麒麟liunx系统

系统管理与计划任 ” 使用at命令提交任务。 6.2.1 at任务概述 6.1.4 定时任务的使用场景 at任务是指使用at命令安排的&#xff0c;只执行一次的任务它允许用户指定在未来某个特定时间执行命令或脚本定时更新系统软件包。定时清理系统临时文件。自动备份文件和数据库。 at:用于一…

【websocket】websocket网课视频记录

仅个人方便回顾。 【WebSocket入门与案例实战-哔哩哔哩】 https://b23.tv/2p1f9t2 课程对应代码仓库: https://gitee.com/duoli-java/websocket-demo.git

C++编程(二)引用

文章目录 一、C中的引用&#xff08;一&#xff09;引用1. 语法格式2. 作用3. 注意事项 &#xff08;二&#xff09;常引用2. 其他场景 &#xff08;三&#xff09;引用和函数结合使用1. 引用可以作为函数的参数2. 引用可以作为函数的返回值 &#xff08;四&#xff09;引用和指…

记因hive配置文件参数运用不当导致 sqoop MySQL导入数据到hive 失败的案例

sqoop MySQL导入数据到hive报错 ERROR tool.ImportTool: Encountered IOException running import job: java.io.IOException: Hive exited with status 64 报错解释&#xff1a; 这个错误表明Sqoop在尝试导入数据到Hive时遇到了问题&#xff0c;导致Hive进程异常退出。状态码…

HarmonyOS Next开发学习手册——通过startAbility拉起文件处理类应用

使用场景 开发者可以通过调用startAbility接口&#xff0c;由系统从已安装的应用中寻找符合要求的应用来实现打开特定文件的意图&#xff0c;例如&#xff1a;浏览器下应用下载PDF文件&#xff0c;可以调用此接口选择文件处理应用打开此PDF文件。开发者需要在请求中设置待打开…

0625_ARM2

练习&#xff1a; 汇编实现1-100累加&#xff0c;结果保存在r0 .text .global _start start:mov r0,#0mov r1,#1b loop loop:add r0,r0,r1add r1,r1,#1cmp r1,#101bne loop .end思维导图&#xff1a;