反转字符串II
雙指針法
class Solution { public:string reverseStr(string s, int k) {int n = s.size();int start = 0, end = n - 1;while(start < n) {if(start + 2 * k < n) { //剩余的字符>=2*k個,則一定可以找到下一段起點.reverse(s.begin() + start, s.begin() + start + k);start = start + 2 * k; }else if(start + k > n) { //不足k個reverse(s.begin() + start, s.end());break;}else { //剩余字符大于等于k小于2k個reverse(s.begin() + start, s.begin() + start + k);break;}}return s;} };雙指針簡化版
class Solution { public:string reverseStr(string s, int k) {int n = s.size();int start = 0, end = n - 1;while(start < n) {if(start + k > n) { //不足k個,超出了字符串范圍reverse(s.begin() + start, s.end());break;}reverse(s.begin() + start, s.begin() + start + k);start = start + 2 * k; }return s;} };改進版1
其實還有一種做法就是在遍歷字符串的過程中,只要讓 i += (2 * k),i 每次移動 2 * k 就可以了,然后判斷是否需要有反轉的區間。
因為要找的也就是每2 * k 區間的起點,這樣寫程序會高效很多。
「所以當需要固定規律一段一段去處理字符串的時候,要想想在在for循環的表達式上做做文章。」
class Solution { public:string reverseStr(string s, int k) {for (int i = 0; i < s.size(); i += (2 * k)) {// 1. 每隔 2k 個字符的前 k 個字符進行反轉,也就是剩余字符>=2k,則一定可以找到下一段起點,//放心反轉本段前k個字符即可// 2. 剩余字符小于 2k 但大于或等于 k 個,則反轉前 k 個字符//包含著剩余元素大于2k情況if (i + k <s.size()) {reverse(s.begin() + i, s.begin() + i + k );//+i是因為要先追上i,然后才進行偏移continue;}// 3. 剩余字符少于 k 個,則將剩余字符全部反轉。//通俗點說,給定一個字符串,我站在第一個字符上向后計數,如果+K個后超出范圍,說明本字符后面不足k個reverse(s.begin() + i, s.begin() + s.size());}return s;} };改進版2
class Solution { public:void reverse(string &s,int start,int end){for(;start<end;start++,end--){swap(s[start],s[end]); }}string reverseStr(string s, int k) {for (int i = 0; i < s.size(); i += (2 * k)) {// 1. 每隔 2k 個字符的前 k 個字符進行反轉,也就是剩余字符>=2k,則一定可以找到下一段起點,//放心反轉本段前k個字符即可// 2. 剩余字符小于 2k 但大于或等于 k 個,則反轉前 k 個字符if (i + k <= s.size()) {reverse(s,i,i + k-1 );//+i是因為要先追上i,然后才進行偏移continue;}// 3. 剩余字符少于 k 個,則將剩余字符全部反轉。//通俗點說,給定一個字符串,我站在第一個字符上向后計數,如果+K個后超出范圍,說明本字符后面不足k個reverse(s,i,s.size()-1);}return s;} };總結
- 上一篇: 四数之和
- 下一篇: 翻转字符串里面的单词(*****)