力扣 字符串专题
38. 外观数列
https://leetcode-cn.com/problems/count-and-say/
class Solution {
public:
string countAndSay(int n) {
string s="1";
for(int i=2;i<=n;i++){
string temp="";
for(int j=0;j<s.size();){
char n=s[j];
int num=0;
while(s[j]==n && j<s.size()){
num++;
//cout<<num<<endl;
j++;
}
temp=temp+to_string(num)+n;
//cout<<temp<<endl;
}
s=temp;
}
return s;
}
};
49. 字母异位词分组
https://leetcode-cn.com/problems/group-anagrams/
思路:满足条件的字符串在排序后必相同
可以开一个hash表 第一个映射为排序后的字符串,第二个为原字符串
映射完毕输出即可
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
unordered_map<string,vector<string>> hash;
for(auto s:strs){
string temp=s;
sort(s.begin(),s.end());
hash[s].push_back(temp);
}
vector<vector<string>> res;
for(auto s:hash){
res.push_back(s.second);
}
return res;
}
};
151. 翻转字符串里的单词
https://leetcode-cn.com/problems/reverse-words-in-a-string/
class Solution {
public:
string reverseWords(string s) {
int k=0;
for(int i=0;i<s.size();){
int j=i;
while(s[j]==' '&&j<s.size()) j++;
if(j==s.size()) break;
i=j;
while(s[j]!=' '&&j<s.size()) j++;
reverse(s.begin()+i,s.begin()+j);
if(k) s[k++]=' ';
while(i<j) s[k++]=s[i++];
}
s.erase(s.begin()+k,s.end());
reverse(s.begin(),s.end());
return s;
}
};
165. 比较版本号
https://leetcode-cn.com/problems/compare-version-numbers/
class Solution {
public:
vector<int> fun(string ver){
//将每一个版本的数字压入vector
vector<int> ans;
for(int i=0;i<ver.size();){
int j=i;
int s=0;
while(j<ver.size() && ver[j]!='.'){
s=s*10+ver[j]-'0';
j++;
}
i=j+1;
ans.push_back(s);
}
//删除后端0 如1.0和1.0.0 后面的0不影响大小
//但是如果不删除 vector比较会出问题
while(ans.size() && ans.back()==0) {
ans.pop_back();
}
return ans;
}
int compareVersion(string version1, string version2) {
auto n1=fun(version1);
auto n2=fun(version2);
if(n1>n2) return 1;
else if(n1==n2) return 0;
else {
return -1;
}
}
};
3. 无重复字符的最长子串
https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/

总结:这个思路主要还是和双指针基本思路一致:固定一段,另外一端只要满足条件就继续往前.不满足就让不动的一段移动
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_map<char, int> hash;
int res = 0;
for (int i = 0, j = 0; j < s.size(); j ++ )
{
hash[s[j]] ++ ;
while (hash[s[j]] > 1) hash[s[i ++ ]] -- ;
res = max(res, j - i + 1);
}
return res;
}
};
166. 分数到小数
https://leetcode-cn.com/problems/fraction-to-recurring-decimal/
计算小数部分的难点在于如何判断是否是循环小数,以及找出循环节的位置。
回忆手工计算除法的过程,每次将余数乘10再除以除数,当同一个余数出现两次时,我们就找到了循环节。
所以我们可以用一个哈希表 unordered_map<int,int> 记录所有余数所对应的商在小数点后第几位,当计算到相同的余数时,上一次余数的位置和当前位置之间的数,就是该小数的循环节。
时间复杂度分析:计算量与结果长度成正比,是线性的。所以时间复杂度是 O(n)。
class Solution {
public:
string fractionToDecimal(int numerator, int denominator) {
long long n=numerator,d=denominator;
bool minus=false;
//处理负数情况
if(n<0) minus=!minus,n=-n;
if(d<0) minus=!minus,d=-d;
string res=to_string(n/d);
n=n%d;
//无小数情况
if(n==0){
if(minus&&res!="0") return '-'+res;
else return res;
}
res+='.';
unordered_map<long long, int> hash;
while(n){
if(hash[n]){
res=res.substr(0,hash[n])+'('+res.substr(hash[n])+')';
break;
}
else hash[n]=res.size();
n*=10;
res+=to_string(n/d);
n%=d;
}
if(minus) res='-'+res;
return res;
}
};
- 实现 Trie (前缀树)
https://leetcode-cn.com/problems/implement-trie-prefix-tree/
Trie树例图:

被打上标记的尾结尾符号,此图保存的单词有:a,abc,bac,bbc,ca
class Trie {
public:
struct Node{
bool is_end;//标记是否结尾
Node *next[26];
Node(){
is_end=false;
for(int i=0;i<26;i++){
next[i]=0;
}
}
};
Node *root;
/** Initialize your data structure here. */
Trie() {
root=new Node();
}
/** Inserts a word into the trie. */
void insert(string word) {
Node *p=root;
for(char c : word){
int son=c-'a';
if(!p->next[son]) p->next[son]=new Node();
p=p->next[son];
}
p->is_end=true;
}
/** Returns if the word is in the trie. */
bool search(string word) {
Node *p=root;
for(char c:word){
int son=c-'a';
if(p->next[son]) p=p->next[son];
else return false;
}
return p->is_end;
}
//返回trie中是否有以给定前缀开头的单词。
//将上面函数最后判断是否是结尾修改即可
/** Returns if there is any word in the trie that starts with the given prefix. */
bool startsWith(string prefix) {
Node *p=root;
for(char c: prefix){
int son=c-'a';
if(p->next[son]) p=p->next[son];
else return false;
}
return true;
}
};
/**
* Your Trie object will be instantiated and called as such:
* Trie* obj = new Trie();
* obj->insert(word);
* bool param_2 = obj->search(word);
* bool param_3 = obj->startsWith(prefix);
*/
class Solution {
public:
vector<vector<string>> ans;//答案
vector<string> path;//当前选择
bool check(string &now)//检查是不是回文串
{
if(now.empty()) return false;
for(int i = 0, j = now.size() - 1; i < j; i ++, j --)
if(now[i] != now[j])
return false;
return true;
}
vector<vector<string>> partition(string s) {
dfs("", 0, s);
return ans;
}
void dfs(string now,int u,string &s){
if (u == s.size())
{
if (check(now))
{
path.push_back(now);
ans.push_back(path);
path.pop_back();
}
return;
}
if (check(now))
{
path.push_back(now);
dfs("", u, s);
path.pop_back();
}
dfs(now + s[u], u + 1, s);
}
};

浙公网安备 33010602011771号