文章目录
一、剑指offer 05. 替换空格
(一)原字符串进行修改
- 思路:先计算出该字符串中有多少个空格,然后将字符串的空间调整为替换后的大小,然后再从字符串的最后进行移动,从最后进行移动的原因是将会花费更少次数的元素拷贝过程,提高效率
如下图所示:
代码如下所示:
class Solution
{
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param s string字符串
* @return string字符串
*/
string replaceSpace(string s)
{
// write code here
//先计算空格的个数
int count=0;
int n=s.length();
for(int i=0;i<n;i++)
{
if(s[i]==' ')
{
count++;
}
}
//重新调整s的大小
s.resize(count*2+n);
for(int i=n-1,j=s.size()-1;i<j;i--,j--)
{
if(s[i]!=' ')
{
s[j]=s[i];
}
else
{
s[j--]='0';
s[j--]='2';
s[j]='%';
}
}
return s;
}
};
二、剑指offer 48.最长不含重复字符串的子字符串
- 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。
(一)滑动窗口
思路:
- 先判断当前字符在当前子串中出现了没;
- 如果没有出现则继续判断下一个字符;
- 如果出现了则要判断当前子串的长度与最大子串长度哪个大;max取较大的一个数值
- 然后删除掉从0到当前字符(包含当前字符)之间的元素;
- 再将当前字符添加到当前子串中
- 再最后遍历完成之后还需要再判断一次max
代码如下:
class Solution
{
public:
int lengthOfLongestSubstring(string s)
{
int max=0;//统计子串的最大长度
int n=s.size();
int t;//保存当前字符在子串中出现的位置
string str="";//当前子串
for(int i=0;i<n;i++)
{
t=str.find(s[i]);//查找当前字符在子串中的位置
if(t!=-1)//该字符在当前子串中存在
{
if(max<str.size())//判断子串的长度与之前记录的长度哪个值更大,取大的值
{
max=str.size();
}
str.erase(0,t+1);//然后将当前子串清空
}
str+=s[i];//子串从当前字符开始重新统计
}
if(max<str.size())//最终还得给max的值做一次比较;
{
max=str.size();
}
return max;
}
};
三、力扣409. 最长回文串
(一)统计每个字符出现的次数,遇到次数为奇数的在最终结果里减一并且进行奇数变量标记
思路:由于我们只需要统计最长的回文串的长度,所以我们可以将该题转化成统计每个字符出现的次数。
回文串的长度有两种情况:
- 回文串中的每个字符都出现了偶数次
- 回文串中只有一个字符出现了奇数次,别的字符都出现了偶数次
所以解决本道题,我们只需要借助一个哈希表来记录字符串中的每个字符出现的次数,一遍遍历完成之后,开始遍历哈希表的value值,从一开始遍历就将value的值加到返回的结果中,如果是偶数则继续遍历,如果是奇数就将返回的结果减一;最后不要忘了如果出现过奇数次数的字符,要将返回的结果加1.
代码如下:
class Solution
{
public:
int longestPalindrome(string s)
{
int ans=0;//返回最长回文子串的长度
int odd=0;//判断有没有字符出现次数为奇数,0表示没有,1表示有
unordered_map<int,int>hash;
for(int i=0;i<s.size();i++)//遍历字符串
{
hash[s[i]]++;
}
for(auto & x:hash)
{
ans += x.second;
if(x.second % 2 != 0)//如果是奇数,则将长度减一
{
ans--;
odd=1;
}
}
if(odd==1)//将任意一个出现次数为奇数的字符添加到最长子串中
{
ans+=1;
}
return ans;
}
};
(二)统计字符串中被单出来的字符个数【比如aaa,两两成对必有一个a被单出来】
思路:统计字符串中所有出现次数为奇数的字符个数,如果没有,那就都是偶数,直接返回字符串的长度,如果有字符出现次数为奇数次,那么选择其中一个字符加入回文串的长度即可
代码如下:
class Solution
{
public:
int longestPalindrome(string s)
{
int ans=0;//返回最长回文子串的长度
int count = 0;
unordered_map<int,int>hash;
for(int i=0;i<s.size();i++)//遍历字符串
{
hash[s[i]]++;
}
for(auto & x:hash)
{
if(x.second%2!=0)
{
count++;//统计字符次数出现奇数次的字符个数
}
}
if(count == 0)
{
return s.size();//如果没有字符次数为奇数,那么直接返回字符串的长度
}
return s.size()-count+1;
}
};
(三)贪心算法
思路:该种解法参考力扣官方题解,学到了新的编码技能
代码如下:
class Solution {
public:
int longestPalindrome(string s) {
unordered_map<int,int>hash;
int ans=0;
for(int i=0;i<s.length();i++)
{
hash[s[i]]++;
}
for(auto &x:hash)
{
ans += x.second /2 * 2;
if(x.second % 2!=0 & ans%2==0)
{
ans++;
}
}
return ans;
}
};
✨✨✨