拿捏几道经典的字符串模拟问题

news/2024/11/27 23:43:44/

希望本篇对你有所帮助

我发现这种字符串的问题其实写起来很麻烦,可能思路不难多少都能想到一些,主要就是代码的处理,细节问题。太考验代码编写的能力了。这两天写了好多道字符串,模拟之类的问题,今天就分享分享吧

刚开始刷题的朋友开卷有益啊

输入: 
paragraph = "Bob hit a ball, the hit BALL flew far after it was hit."
banned = ["hit"]
输出: "ball"
解释: 
"hit" 出现了3次,但它是一个禁用的单词。
"ball" 出现了2次 (同时没有其他单词出现2次),所以它是段落里出现次数最多的,且不在禁用列表中的单词。 
注意,所有这些单词在段落里不区分大小写,标点符号需要忽略(即使是紧挨着单词也忽略, 比如 "ball,"), 
"hit"不是最终的答案,虽然它出现次数更多,但它在禁用单词列表中。

首先读懂题意:

几个关键点

  1. 答案是唯一的
  2. 在做判断的时候不区分大小写,意思就是AOB等于aob
  3. 再者要在禁用列表里面找是不是禁用的单词
  4. 自动忽略标点符号,意思就是bob?或者bob.或者bob, 这些都按照bob这个单词去处理
  5. 拿到这题肯定第一反应就是用哈希表来映射,这是没问题的,那么就需要我们在里面做一个处理,我们记录的单词不能带标点

大致思路就出来了,定义一个map去记录各个单词映射,然后很多题解是把原来的这个字符串paragraph存到了一个字符串数组里面,这样方便遍历,然后把禁用列表用一个set再去存一下方便去find

不过这样我感觉空间就有了开销,我是这样写的

遍历整个字符串paragraph,用一个word去记录每次遇到的字母,只要是正常的字母我们就添加到word上面,如果遇到了空格或者标点了就说明我们这个单词记录完毕了,在单词列表里用find去查询此时记录的word,如果没找到说明可以把它记在map里面,然后每次做完这个判断就把word置为“”,用来进行下一个单词的组装

这样的话就用一个word来回组装,一遍遍历完成了给map的映射,最后再去map里面找最大的就行

代码如下:

 string mostCommonWord(string paragraph, vector<string>& banned) {unordered_map<string,int>mp;//用来记录单词出现的次数string word="";for(int i=0;i<paragraph.size();++i){//因为不区分大小写,所以要做if判断if(paragraph[i]>='A'&&paragraph[i]<='Z'){//如果是大写,要转成小写//word+=tolower(paragraph[i]);word+=paragraph[i]-'A'+'a';}else if(islower(paragraph[i]))//如果是小写{word+=paragraph[i];}else if(word!="")//其实就是判断了是各种标点或者空格了{                 //走到这就说明word已经加成了一个完整的单词//就要开始判断在不在禁用列表中if(find(banned.begin(),banned.end(),word)==banned.end())//没找到{mp[word]++;}word="";}}int maxlen=1;//遍历map,找出现次数最多的那个for(auto &x:mp){if(maxlen<=x.second){maxlen=x.second;word=x.first;}}return word;}

----------------------------------

再来一道叫做亲密的字符串,让我们看看他有多亲密啊

示例 1:

输入:s = "ab", goal = "ba"
输出:true
解释:你可以交换 s[0] = 'a' 和 s[1] = 'b' 生成 "ba",此时 s 和 goal 相等。

示例 2:

输入:s = "ab", goal = "ab"
输出:false
解释:你只能交换 s[0] = 'a' 和 s[1] = 'b' 生成 "ba",此时 s 和 goal 不相等。

示例 3:

输入:s = "aa", goal = "aa"
输出:true
解释:你可以交换 s[0] = 'a' 和 s[1] = 'a' 生成 "aa",此时 s 和 goal 相等。

拿到这题我最早想着就直接暴力,两个for循环两两交换去比较

pa的一下很快啊,代码出来了,很顺利啊,没有ac啊,超时了家人们,太慢了

我当初写的时候也是抱着侥幸心理哈哈哈,果然超时了

既然暴力走不通那么就好好审题,找找规律看看都有什么情况我们要做处理,反正我当初愣是没想到要记录下标到数组,废了老大功夫去做。

如果读完题你能想到,map和记录下标,那么这个题就没问题了

看看力扣给的示例我们ab和ba,我们会发现两个字符串的两个位置都不相同,且交换之后就相同了;示例ab和ab他本身相同,但是一交换就不相同了;示例aa和aa,本身相同且相同的字母有多个,意思就是aa是重复的,我们交换了,最终两个结果还是一样

这道题就是必须要交换一次,且只能交换一次

分析完三个示例,就能得到下面的规律:

  1. 两种情况
  2. s和goal有两个位置不相同,且这两个位置交换之后,就相等了
  3. 如果s和goal不相同的位置大于2了,肯定就不相同了
  4. s和goal完全相同,并且s有多余相同的字符,这样的话s和goal才能返回true
  5. 什么意思?ab  和ab都相同但是,交换就会有问题
  6.  aab和aab相同 a有多余 交换aa还是不变的 ,就说明可以返回true

看到这,我们就有思路了呀,定义一个map去记录s各个字母出现的次数,如果s里有多余出现的字母,我们就做个标记。在遍历s的时候如果当前位置的s字母和goal字母不一样了,说明有一个位置了,我们把这个位置保存在下标数组里面;我们定义下标数组的时候这个数组其实最终要么为空要么为2,为2就说明两处不一样可以去交换了,如果大于2了那么肯定一次交换是不行的,结果肯定就是false了 。

思路如下: 

统计字符串s,goal中字符不匹配的下标。

不匹配的下标个数不等于 0 或 2 时,不能由s得到goal。

不匹配的下标个数等于0时,s与goal中字符完全相同,还需要s中有重复字符。

不匹配的下标个数等于2时,判断交换两对字符后是否匹配。

这样pa的一下啊 代码又出来了

    bool buddyStrings(string s, string goal) {if(s.size()!=goal.size())return false;int flg=0;//有多余相同字母的标记for(int i=0;i<s.size();++i){if(s[i]!=goal[i]){index.push_back(i);}if(index.size()>2)return false;//大于2个位置不一样了mp[s[i]]++;if(mp[s[i]]>1)//说明有重复的{flg=1;}}//有两个不相同if(index.size()==2&&s[index[0]]==goal[index[1]]&&s[index[1]]==goal[index[0]]){return true;}//都相同 且有重复字符if(index.size()==0&&flg){return true;}//还有一种写法 不用map,和flg标记//当index的size等于0的时候,用s来构建一个set//unordered_set<char>set(s.begin(),s.end());//return set.size()<s.size();如果s里面有重复的那么set的长度肯定小于s长度return false;}

数组啊字符串很多题都是考能不能找到规律的问题,需要双指针,滑动窗口,map这些都是这一类题常见的解题技巧。

蹬蹬补充一道题:不是字符串的题,不过当初自己写的时候感觉蛮有意思(就是自己菜,没找到简单的规律),单独给这个题记录一篇博客,感觉太水了,我就浅浅加在这一篇吧。

看到就是赚到!!

这个思路是最最最简单的,反正我也是看了题解才知道OO~~哦可以这样

找到开头连续的0,找到结尾连续的0,再找中间连续的最大0

返回这三个里面最长的就行

 int maxDistToClosest(vector<int>& seats) {//找到开头连续0个数,结尾连续0//中间连续0,取最大int kaitou=0,jiewei=0,mid=0;int i=0,j=seats.size();while(i<j&&seats[i]==0){kaitou++;i++;}while(j>0&&seats[j-1]==0){jiewei++;j--;}int temp=0;//记录一下中间每次连着0的个数for(int k=i+1;k<j;++k){if(seats[k]==0){temp++;}else{mid=max(temp,mid);temp=0;}}return max(max(kaitou,jiewei),(mid+1)/2);}

其实写了很多题,好题太多了,我就挑一些不错的给大家分享分享~


http://www.ppmy.cn/news/10923.html

相关文章

linux系统中利用QT实现绘制图和图标的方法

大家好&#xff0c;今天主要和大家聊一聊&#xff0c;如何使用QT进行绘图和图标的方法。 第一&#xff1a;绘图和图表简介 绘图与图表在嵌入式里有的比较多&#xff0c;尤其是图表&#xff0c;我们常在股票里看到的“图表折线/曲线图/饼状图等”都可以用 Qt 的图表来实现。绘图…

Java基础算法每日5道详解(3)

136. Single Number 单号 Given a non-empty array of integers nums, every element appears twice except for one. Find that single one. You must implement a solution with a linear runtime complexity and use only constant extra space. 给定一个非空整数数组 nu…

shell原理及Linux权限

shell及Linux权限 目录shell及Linux权限一、指令1.tar指令&#xff08;重要&#xff09;2.热键3.bc命令4.uname –r指令&#xff1a;5.关机6.以下命令作为扩展:二.shell命令以及运行原理三.权限1.权限的概念&#xff1a;2.Linux下有两种用户&#xff1a;超级用户&#xff08;ro…

[C语言]进一步的来了解指针(多多多图详解)

本文章进一步的来讲解指针&#xff0c;如果是第一次接触指针的可以先看一下对于指针的初步理解 &#xff1a; [C语言]初步的来了解一下指针&#xff08;多图详解&#xff09;_HY_PIGIE的博客-CSDN博客 目录 1.字符指针 2.指针数组 2.1指针数组&#xff1a;char*类型举例说明 2…

Qt 使用 Matlab函数

背景&#xff1a;个人的Qt项目中&#xff0c;需要一个图片分割算法。该算法之前在Matlab上实现过&#xff0c;同时转成C版本有点麻烦&#xff0c;因此尝试通过Qt与Matlab编程相结合的方式&#xff0c;实现该功能。 注意&#xff1a;以下所有功能及配置过程&#xff0c;默认已经…

直观理解--马氏距离

首先我们很了解欧氏距离了&#xff0c;就是用来计算欧式空间&#xff08;就是我们常见的坐标系&#xff09;中两个点的距离的。 比如点 x(x1,…,xn)x (x_1,…,x_n)x(x1​,…,xn​) 和 y(y1,…,yn)y (y_1,…,y_n)y(y1​,…,yn​) 的欧氏距离为&#xff1a; d(x,y)(x1−y1)2(x2…

ESXI8.0一键安装黑群晖DSM7

&#x1f388; 作者&#xff1a;互联网-小啊宇 &#x1f388; 简介&#xff1a; CSDN 运维领域创作者、阿里云专家博主。目前从事 Kubernetes运维相关工作&#xff0c;擅长Linux系统运维、开源监控软件维护、Kubernetes容器技术、CI/CD持续集成、自动化运维、开源软件部署维护…

KubeSphere使用外部ES进行日志收集(多行日志)

环境kubesphere &#xff1a; v3.3.1Docker&#xff1a;20.10.8Fluent-Bit&#xff1a;2.0.6-2.0.8ESKibana&#xff1a;7.9.3Docker日志示例{"log":"2023-01-10 11:32:50.021 - INFO --- [scheduling-1] traceId: p6spy : 1|conn-0|statement|SELECT fd_id A…