题目:
给定一个字符串 s 和一个整数 k,你需要对从字符串开头算起的每隔 2k 个字符的前 k 个字符进行反转。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
这道题第一遍自己做的时候,把判断那块搞得乱七八糟,要分好几种情况分别处理,看了carl大神的做法,其实只需三步走就能把所有情况涵盖进去。非常巧妙,需要多加思考
class Solution {
public:
// 因为不同的条件下都需要做反转,但最主要的是确定反转的首元素,尾元素
// 因此定义一个反转函数,返回值类型定义为void
// 因为是在空间复杂度为 O(1)的情况下进行的,原地反转,无需返回值类型即可
// 注意传入字符串时,要用引用的方式进行传递,才能成功完成原地修改
// 题目给的函数,需要返回值类型,因为它是进行的 值传递,注意区分
void reverse(string& s,int start,int end)
{
// 这里**********一直搞错了,错误的写为 (end-start)/2
int n=(end-start+1)/2;
for(int i=0;i<n;i++)
{
swap(s[start+i],s[end-i]);
}
}
string reverseStr(string s, int k)
{
// 注意在for循环中最后的表达式怎么写的,
// *****************头一次遇见 i+=(2*k)
for(int i=0;i<s.size();i+=(2*k))
{
// 1.每隔 2k 个字符的前 k 个字符进行反转
// 2、剩余字符小于 2k 但大于 k 个,则反转前 k 个
if(i+k<s.size())
{
reverse(s,i,i+k-1);
continue;
}
// 3、剩余字符小于 k 个,则全部翻转
reverse(s,i,s.size()-1);
}
return s;
}
// //这里的逻辑写的乱七八糟的!!!!
// // 因为要分好几种情况来判断,因此这样写,对最后要判断的情况多而复杂,换思路
// string reverseStr(string s, int k) {
// int sSize=s.size();
// int n=sSize/(2*k);
// int m=sSize%(2*k);
// int i=0;
// for(int i=0;i<n;i++)
// {
// reverse(s,2*k*i,2*k*i+k-1);
// }
// if(m<k&&n>0)
// {
// reverse(s,2*k*n,2*k*n+m);
// }
// if((m<2*k)&& (m>=k))
// {
// reverse(s,2*k*n,2*k*n+k-1);
// }
// return s;
// }
};