五月训练第二天——字符串
前言:
一、今日收获
今天的习题是关于字符串的,为此通过练习习题基本复习了哈希表,离散化的相关内容,之后还需要继续刷一下相关的题目来巩固。同时还拓宽了思路,学到了匹配相关的内容可以用栈来写,string也可以进行栈的操作。
二、不足
感觉基础知识有点跟不上了,为此需要加快一下基础知识的学习了
解题报告:
-
500. 键盘行
题目概述:
给你一个字符串数组
words
,只返回可以使用在 美式键盘 同一行的字母打印出来的单词。键盘如下图所示。解题思路:
通过哈希表来统计各个字符所在的行,因为大小写共存的问题,所以先另设一个数组来当word使用并统一成小写,需要的时候遍历,只要在同一行那就添加这个单词为答案
源码剖析:
class Solution { public: vector<string> findWords(vector<string>& words) { int hash[26]={1,2,2,1,0,1,1,1,0,1,1,1,2,2,0,0,0,0,1,0,0,2,0,2,0,2};//(1) vector<string>res; vector<string>a=words; for(int i=0;i<words.size();i++)//(2) { for(int j=0;j<words[i].size();j++) { if(a[i][j]<='Z'&&a[i][j]>='A') a[i][j]=a[i][j]-'A'+'a'; } } for(int i=0;i<words.size();i++)//(3) { int flag=1; for(int j=0;j<words[i].size()-1;j++) { if(hash[a[i][j]-'a']!=hash[a[i][j+1]-'a']) flag=0; } if(flag) { res.push_back(words[i]); } } return res; } };
(1)预处理,用哈希表表示各个字母所在的行数
(2)把原数组的大写字母全部改为小写(在副本数组改,因为要返回原数组的单词是包含大小写的)
(3)遍历副本数组判断是否为同一行,添加答案添加原数组
题目概述:
给你一份『词汇表』(字符串数组) words 和一张『字母表』(字符串) chars。
假如你可以用 chars 中的『字母』(字符)拼写出 words 中的某个『单词』(字符串),那么我们就认为你掌握了这个单词。
注意:每次拼写(指拼写词汇表中的一个单词)时,chars 中的每个字母都只能用一次。
返回词汇表 words 中你掌握的所有单词的 长度之和。
解题思路:
与第一题同理,使用哈希表先记录所给字母表的字母的数量,再遍历单词表,如果单词表中的每个单词的字母的数量大于所给的字母表的数量,则无法拼写单词,如果可以拼写,需要减去相应的字母的数量(每个单词只能用一次)同时加上对应的单词的长度
源码剖析:
class Solution {
public:
int countCharacters(vector<string>& words, string chars) {
int res=0;
int hash[26];
for(int i=0;i<words.size();i++)
{
memset(hash, 0, sizeof(hash));
for(int j=0;j<chars.size();j++)//(1)
{
hash[chars[j]-'a']++;
}
bool flag=true;
for(int k=0;k<words[i].size();k++)//(2)
{
if(hash[words[i][k]-'a'] <= 0)
{
flag = false;
break;
}
else
hash[words[i][k]-'a']--;
}
if(flag){//(3)
res+=words[i].size();
}
}
return res;
}
};
(1)哈希表统计字母表
(2)遍历判断是否能够拼写
(3)计算拼写的单词的长度的总和
题目概述:
给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
解题思路:
这道题出现了两个相邻的相同项要删除,在这道题之前做过的类似题目有链表中的相同和栈的括号匹配,所以这道题用栈的操作删除相同元素
源码剖析:
class Solution {
public:
string removeDuplicates(string s) {
string a;
for(int i=0;i<s.size();i++)
{
if(a.empty()||a.back()!=s[i])
{
a.push_back(s[i]);
}
else{
a.pop_back();
}
}
return a;
}
};
-
题目概述:
键盘出现了一些故障,有些字母键无法正常工作。而键盘上所有其他键都能够正常工作。
给你一个由若干单词组成的字符串 text ,单词间由单个空格组成(不含前导和尾随空格);另有一个字符串 brokenLetters ,由所有已损坏的不同字母键组成,返回你可以使用此键盘完全输入的 text 中单词的数目。
解题思路:
用哈希表统计损坏的字母,然后进行比较,如果单词的字母损坏,那么就flag置零,继续遍历直到空格(开始需要往最后的位置添加空格)
源码剖析:
class Solution { public: int canBeTypedWords(string text, string brokenLetters) { int res=0; int hash[26]; memset(hash,0,sizeof(hash)); text.push_back(' ');//(1) for(int j=0;j<brokenLetters.size();j++)//(2) { hash[brokenLetters[j]-'a']++; } int flag=0; for(int i=0;i<text.size();i++)//(3) { if(text[i]==' ')//(4) { if(flag==0) { res++; } else{ flag=0; } continue; }else{ if(hash[text[i]-'a']!=0) { flag=1; continue; } } } return res; } };
(1)初始化置空格
(2)哈希表统计损坏字母个数
(3)遍历查询
(4)判断遇到空格