LeetCode541. 反转字符串 II

题目

给定一个字符串 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

原文地址:https://www.cnblogs.com/fresh-coder/p/14314055.html