日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

字符串经典题

發布時間:2025/3/15 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 字符串经典题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
序號題目難度鏈接外鏈
1.僅僅反轉字母簡單跳轉LeetCode
2.第一個唯一的字符簡單跳轉LeetCode
3.最后一個單詞的長度簡單跳轉LeetCode
4.驗證回文串簡單跳轉LeetCode
5.字符串加法簡單跳轉LeetCode
6.字符串乘法中等跳轉LeetCode
7.字符串轉換為整數簡單跳轉牛客
8.字符串區間反轉簡單跳轉LeetCode
9.反轉單詞簡單跳轉LeetCode
10.羅馬數字轉換為整數簡單跳轉LeetCode
11.字符串匹配問題(KMP)中等跳轉LeetCode
12.外觀數列簡單跳轉LeetCode
13.二進制加法簡單跳轉LeetCode
14.贖金信簡單跳轉LeetCode
15.求單詞的個數簡單跳轉LeetCode
16.重復的子字符串中等跳轉LeetCode
17.URL化簡單跳轉LeetCode
18.學生出勤記錄I簡單跳轉LeetCode
19.長按鍵入簡單跳轉LeetCode
20.親密字符串中等跳轉LeetCode

LeetCode917:僅僅反轉字母

思路很簡單,前后掃描即可

class Solution { public:bool Isalpha(char ch){if(ch>='a' && ch<='z')return true;if(ch>='A' && ch<='Z')return true;return false;}string reverseOnlyLetters(string S) {size_t begin=0;size_t end=S.size()-1;while(begin<end){if(S.empty())return S;while(begin<end && !Isalpha(S[begin]))begin++;while(begin<end && !Isalpha(S[end]))end--;swap(S[begin],S[end]);begin++;end--;}return S;} };

LeetCode387:字符串中第一個唯一字符

這種題暴力破解會導致時間復雜度非常高,所以可以使用散列表的思想,為每個字母添加一個映射,利用數組,相同字母個數就增加。這里可以以字母a作為基準,這樣的話數組下標就可以從0開始了

class Solution { public:int firstUniqChar(string s){int cout[26]={0};//26個字母進行映射for(int i=0;i<s.size();i++)//相同字母進行統計{cout[s[i]-'a']++;}for(int i=0;i<s.size();i++){if(cout[s[i]-'a']==1)//第一個出現1次的輸出return i;}return -1;} };

牛客:最后一個單詞的長度

這道題思路比較簡單,但是要注意一個問題,字符串是以空格分隔的,所以使用cin接受時可能導致空格之后的單詞無法接收到,所以要使用getline,他可以接受一行,也就是接受空格

#include <string> #include <iostream>using namespace std; int main() {string s;getline(cin,s);size_t pos=s.rfind(" ");if(pos!=string::npos){ cout<<s.size()-1-pos<<endl;}else{cout<<s.size()<<endl;}}

LeetCode125:驗證回文串

此題也是比較簡單

class Solution { public:bool isPalindrome(string s) {for(int i=0;i<s.size();i++)//將所有的小寫字母轉換為大寫字母{if(s[i]>='a' && s[i]<='z'){s[i]-=32;}}int begin=0;int end=s.size()-1;while(begin<end){while(begin<end && !isalnum(s[begin]))//不是字母或數字begin++;while(begin<end && !isalnum(s[end]))end--;if(s[begin]!=s[end]){return false;}else{begin++;end--;}}return true;} };

LeetCode415:大數運算之加法(重要)

這是一道非常經典的題目,運算時每次單個位相加,同時注意數字和字符之間的轉換,然后注意進位。最后字符由于是尾插進去的,所以要反轉

class Solution { public:string addStrings(string num1, string num2) {string ret;//返回結果字符串int end1=num1.size()-1;int end2=num2.size()-1;//end1和end2分別用來從后向前掃描num1和num2字符串int next=0;//標記進位while(end1>=0 || end2>=0)//掃描{int ret1=0,ret2=0;//用來接受對應單個位置的字符if(end1>=0){ret1=num1[end1--]-'0';//轉換為數字}if(end2>=0){ret2=num2[end2--]-'0';//轉換為數字}int retch=ret1+ret2+next;//單位相加注意加進位if(retch>=10)//如果大于10表示,下一位要進位{retch-=10;//留下個位數字next=1;}else{next=0;//如果不大于10,就不僅為}ret+=(retch+'0');//轉化為字符,并尾插到返回字符數組中}if(next==1)//有一種特殊情況就是9999+1,所以特殊處理{ret+='1';}reverse(ret.begin(),ret.end());//由于是尾插所以注意反轉return ret;} };

LeetCode43:大數運算之乘法

解法就是豎式計算,第二行的從后向前每一位去乘第一行的每一位,注意第二行不從倒數第一個開始時要補位

string multiply(string num1, string num2) {if(num1=="0" || num2=="0")//0乘任何數都是0return "0";string ret="0";//返回的字符串int n1=num1.size()-1,n2=num2.size()-1;//n1和n2分別掃描num1和num2for(int i=n2;i>=0;i--)//掃描num2{ string curr;//單個位相乘,暫時保存的字符串int add=0;//用于進位for(int j=n2;j>i;j--)//用于補位{curr.push_back('0');}int y=num2[i]-'0';//乘法運算,用num2的這一位去乘num1的每一位for(int j=n1;j>=0;j--)//num1的每一位{int x=num1[j]-'0';//轉換為數字int retch=x*y+add;//注意加上進位curr.push_back((retch%10)+'0');//結果尾插進去字符串add=retch/10;//進位值}while(add!=0)//比如9×9=81,這種特殊情況{curr.push_back(add%10+'0');add/=10;}reverse(curr.begin(),curr.end());//由于是尾插,注意反轉ret=addStrings(ret,curr);//結果依次進行字符串相加}return ret;

牛客:字符串轉換為整數

此題也非常簡單

class Solution { public:int StrToInt(string str) {int flag=1;//判斷是否為負數int begin=0;//起始位置int end=str.size()-1;//結束位置int sum=0;//返回的數字int j=10;//倍加if(str[begin]=='-')//處理負號{flag=-1;begin++;}if(str[begin]=='+')//處理正號{flag=1;begin++;}while(begin<=end){if(str[begin]>='0' && str[begin]<='9')//只有合法才可以轉換{int num=str[begin]-'0';sum=sum*j+num;begin++;}elsereturn 0;}return sum*flag;} };

LeetCode 541:字符串部分區間反轉

這道題,用for循環每次控制2k個區間,然后每次循環時去判斷剩余字符個數是否小于個,如果大于等于k個就反轉這個2k區間的前k個,循環結束時,肯定剩余的字符就小于了k個,然后把剩余字符反轉

class Solution { public:string reverseStr(string s, int k) {for(int i=0;i<s.size();i+=(2*k)){if(i+k<=s.size())//剩余的字符大于等于k個,但小于2k{reverse(s.begin()+i,s.begin()+i+k);//反轉前k個continue;//繼續反轉,直到}reverse(s.begin()+i,s.begin()+s.size());//剩余k個}return s;}};

LeetCode557:反轉字符串中的單詞

這道題可以用到上面講到過過的find_first_of,不斷找下一個空格

class Solution { public:string reverseWords(string s) {int begin=0;int end=s.find_first_of(" ");//先找到第一個空格if(end==string::npos)//如果整個字符串沒有空格{reverse(s.begin(),s.end());//翻轉整個字符串}while(end!=string::npos)//不斷找空格{reverse(s.begin()+begin,s.begin()+end);//翻轉區間begin=end+1;//begin向后走end=s.find_first_of(" ",begin);//end從下一個位置開始再找空格if(end==string::npos)//一旦end=npos時,就無法進入while了,直接把剩余部分翻轉{reverse(s.begin()+begin,s.end());break;}}return s;} };

羅馬數字轉換為整數

此題也是非常簡單,掃描字符串,挨個累加即可
處理情況時,舉個例子,IV應該被解析為4而不是6,所以在case V中,看一下它前一個字符是不是I,如果是I那么它已經被解析為了6,所以而與實際情況相比,相差2,所以減去2即可。依次類推

class Solution { public:int romanToInt(string s) {int num=0;for(int i=0;i<s.size();i++){switch (s[i]){case 'I':num+=1;break;case 'V':num+=5;if(i>0 && s[i-1]=='I')//特殊處理IVnum-=2;break;case 'X':num+=10;if(i>0 &&s[i-1]=='I')//特殊處理IXnum-=2;break;case 'L':num+=50;if(i>0 &&s[i-1]=='X')//特殊處理XLnum-=20;break;case 'C':num+=100;if(i>0 &&s[i-1]=='X')//特殊處理XCnum-=20; break;case 'D':num+=500;if(i>0 &&s[i-1]=='C')//特殊處理CDnum-=200;break;case 'M':num+=1000;if(i>0 &&s[i-1]=='C')//特殊處理CMnum-=200;break;default:break;}}return num;} };

LeetCode28:字符串匹配問題

此題可以用KMP算法求解,KMP算法對于初學者來說可以說是一個勸退算法,本人在這篇博客中對KMP有很詳細的講解,保證你看完就會

KMP算法詳細講解

class Solution { public:void getnext(string& target,int next[])//next數組{int i=0;int k=-1;next[0]=-1;while(i<target.size()-1)//注意越界問題,{if(k==-1 || target[i]==target[k]){i++;k++;next[i]=k;}else{k=next[k];}}}int strStr(string haystack, string needle) {if(needle=="")//目標串為空,返回0return 0;if(haystack=="")//主串為空,返回-1{return -1;}int* next=new int[needle.size()];//申請next數組int i=0;//i和j分別掃描主串和目標串int j=0;getnext(needle,next);//構建next疏忽組int m=haystack.size();//兩個字符串的長度int n=needle.size();while(i<m && j<n)//KMP算法{if(j==-1|| haystack[i]==needle[j]){i++;j++;}else{j=next[j];}}if(j>=needle.size())return i-needle.size();//返回目標串的下標elsereturn -1;//找不到返回-1} };

LeetCode38:外觀數列

此題題目較長,但是仔細理解后會發現比較有意思。這個數列每個對象都是對前一個對象的描述,所以它要第幾個對象,我就剩生成幾個對象,就是兩個for循環的迭代操作

class Solution { public:string countAndSay(int n) {string arr[n];//給幾個n就生成幾個對象arr[0]="1";//第一個是原始for(int i=1;i<n;i++)//每一個對象都要對前一個對象進行描述{int index=1;//這個表示連續字符的個數for(int j=0;j<arr[i-1].size();j++)//用于掃描前一個對象,以此來生成此對象{char ch=arr[i-1][j];//保存一下字符if(j+1<arr[i-1].size() && arr[i-1][j+1]==ch)//如果是連續的那么就多一個數目{index++;}else//直到不是連續的字符,直接進行對象對象{arr[i]+=(index+'0');//個數arr[i]+=ch;//字符index=1;//重新置為1}}}return arr[n-1];}};

LeetCode67 二進制加法

換湯不換藥

class Solution { public:string addBinary(string a, string b) {string ret;int end1=a.size()-1;int end2=b.size()-1;int next=0;while(end1>=0 || end2>=0){int ret1=0;int ret2=0;if(end1>=0){ret1=a[end1--]-'0';}if(end2>=0){ret2=b[end2--]-'0';}int retch=ret1+ret2+next;if(retch>1){retch-=2;//進位next=1;}elsenext=0;ret+=(retch+'0');}if(next==1){ret+='1';}reverse(ret.begin(),ret.end());return ret;} };

這道題其實和“第一個唯一的字符”那個題基本一致,都是進行映射

class Solution { public:bool canConstruct(string ransomNote, string magazine){if(ransomNote=="")//如果ransomnote為空,則返回truereturn true;if(magazine=="")//如果magazine為空,則返回flasereturn false;int* count=new int[26];//開辟存放26個字母的數組for(int i=0;i<26;i++){count[i]=0;} for(int i=0;i<magazine.size();i++)//映射{count[magazine[i]-'a']++;}for(int j=0;j<ransomNote.size();j++)//只要有的全部對應減去{if(count[ransomNote[j]-'a']>0){count[ransomNote[j]-'a']--;}else//一旦小于等于0,肯定不存在return false;}return true;} };

此題非常簡單,我寫得有點麻煩,不過可讀性很強

class Solution { public:int countSegments(string s) {if(s=="")//如果是空字符返回0return 0;int num=0;//記錄字符總數int start=0;//判斷非空格int non_sapace=0;//消除空格int end=s.size()-1;while(s[end]==' ')//消除后面的空格,直到最后一個單詞末尾{if(end==start && s[end]==' ')//如果end=start并且這個字符還是空那么就是0return 0;end--;}while(start<=end && non_sapace<=end)//掃描{while(s[non_sapace]==' ')//先用nonspace消除空格non_sapace++;start=non_sapace;//找到某個單詞的第一個位置while(start<=end && s[start]!=' ')//掃描完整個單詞{start++;}num++;//表示單詞+1non_sapace=start;//循環,用non——space消除空格}return num;} };

LeetCode459:重復的子字符串


這道題有必要好好說明一下

我們把字符串s中循環的子字符串稱為循環節,題目就是要讓我們判斷一個字符串有沒有循環節

如果沒有循環節,我們兩個字符串拼接到一起,稱為ss,那么ss中肯定有兩個s,那么從ss中尋找s,必然能找到,并且返回值一定是s.size()

如果有循環節,那么設循環節的長度為len,那么ss中必然有ss.size()/len+1個循環節,然后“去掉ss中的第一個字符”,也就是從ss的第二個位置開始尋找s,那么既然有循環節,所以如果其返回值不是s.size()的話那么就能證明成功

所以直接可以用一行代碼解決

class Solution { public:bool repeatedSubstringPattern(string s) {return (s+s).find(s,1)!=s.size();} };

LeetCode01.03:URL化

這道題和劍指offer的面試題5:替換空格基本相似,但是這道題中給出的是真實的字符串的長度,這一點是需要十分注意的

string replaceSpaces(string S, int length) {int length_bak=length;int i=0;int real_space=0;;while(length_bak--)//統計有效的空格{if(S[i]==' ')real_space++;i++;}string ret;ret.resize(length+2*real_space+1);//多申請一個空格存放'\0'int j=length-1;int k=ret.size()-2;//這里-2while(k>=0){if(S[j]!=' '){ret[k--]=S[j--];}else{ret[k--]='0';ret[k--]='2';ret[k--]='%';j--;}}return ret;}

LeetCode551:學生出勤記錄I

此題較為簡單。注意我們判斷時,只需判斷LLL是否是S的字符串,如果是那肯定false,如果不是就表明s中不可能存在LLL,LLLLL這樣的字符串,最多也只能是LL

class Solution { public:bool checkRecord(string s) {int A_number=0;if(strstr(s.c_str(),"LLL")!=NULL){return false;}else{for(int i=0;i<s.size();i++){if(s[i]=='A')++A_number;if(A_number>1)return false;}}return true;} };

LeetCode925:長按鍵入

這道題解決時使用for循環去遍歷typed,然后如果對應相同就同步掃描,然后如果不對應相同,那么就看一下此處typed[j]和name[i-1]是否相同,如果相同那么說明typed[j]就是被長按出來的

class Solution { public:bool isLongPressedName(string name, string typed) {int i=0;int j=0;for(j=0;j<typed.size();j++){if(name[i]==typed[j])//對應相等,同步掃描i++;else if(i-1>=0 && typed[j]==name[i-1])//如果不對應相等,看下typed[j]是否是被長按的{continue;}else//除此之外全部是flasereturn false;}if(i>name.size()-1)//防止name長,typede短的情況發生return true;elsereturn false;} };

LeetCode 859:親密字符串

這道題需要考慮情況較多。觀察其特點,如果是親密字符串,最多有兩個字符位置不同

class Solution { public:bool buddyStrings(string a, string b) {if(a.size()!=b.size())//如果長度不相同,肯定falsereturn false;string differ_a;string differ_b;//分別用兩個字符串記錄a和b不同的字母int count=0;//用來記錄有幾個不同的字母for(int i=0;i<a.size();i++){if(a[i]!=b[i])//如果不相同{differ_a+=a[i];differ_b+=b[i];//就把對應的字母依次放在兩個字符數組中count+=1;//說明不相同的字符讀多一個}if(count>2)//一旦出現兩個以上不同的字符,那么肯定不是親密字符串return false;}if(count==2 && differ_a[0]==differ_b[1] && differ_a[1]==differ_b[0])//然后如果是兩個字符不同,再看數組a[0]是否等于b[1],a[1]是否等于b[0]return true;if(count==0)//如果count等于0,說明兩個字符串相同,然后在這里,aa和aa返回的是true,ab和ab卻返回的是false, //所以就看一下a字符串里里面是否會有相同的字符,如果有那么就能交換因此是親密。比如說abab和abab{int arr[26]={0};//根據字母映射關系進行for(int i=0;i<a.size();i++){if(arr[a[i]-'a']==1)return true;arr[a[i]-'a']=1;}return false;}return false;} }; 新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!

總結

以上是生活随笔為你收集整理的字符串经典题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。