题目
给定一个字符串 s 和一个整数 k,你需要对从字符串开头算起的每隔 2k 个字符的前 k 个字符进行反转。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
代码
一、自己写的,有些冗长
1 class Solution { 2 public: 3 string reverseStr(string s, int k) { 4 if(s.size() < k) reverse(s.begin(),s.end()); 5 else if(s.size() >= k && s.size() < 2*k){ 6 for(int i = 0,j = k-1;i < k/2;i++,j--) swap(s[i],s[j]); 7 } 8 else{ 9 int i,j; 10 int l = (s.size() -1 ) / (2*k) + 1; //l表示循环的次数,除法向上取整 11 for(int loop = 0;loop < l;loop++){ 12 i = 2 *loop*k; 13 j = s.size() -1 > i + k - 1 ? i + k - 1 : s.size() -1; //别忘记最后一次的右边界 14 for(;i < j;i++,j--){ 15 swap(s[i],s[j]); 16 } 17 } 18 } 19 return s; 20 } 21 };
就是简单模拟而已,自己写的很烂!自己的想法时,用外层循环控制有多少个2K需要reverse,内部循环来做reverse,反转的区间用 i,j 每次更新规律来控制。外部循环是向上取整,这里用到了一个数论的小结论:
N/M 向上取整: = (N - 1) / M + 1
思考怎样进一步优化循环,将双循环去掉?
二、抓住剩余,题目化简为了
1.每隔k个反转k个
2.剩余不足k个全部反转
1 class Solution { 2 public: 3 string reverseStr(string s, int k) { 4 for(int i = 0;i < s.size();i += 2*k){ 5 //1.每隔k个反转k个 = 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符 6 if(i + k <= s.size()){ 7 reverse(s.begin() + i,s.begin() + i + k ); 8 } 9 //2.剩余不足k个全部反转 10 else{ 11 reverse(s.begin() + i,s.end()); 12 } 13 } 14 return s; 15 } 16 };
注意
第六行是 s.size() 而不是s.size() -1