344.反转字符串
void reverseString(vector<char>& s) {
int length = s.size();
int left = 0;
int right = length-1;
while (left < right) {
char temp = s[left];
s[left] = s[right];
s[right] = temp;
left++;
right--;
}
}
本题是很简单的双指针做法,很简单没什么可说的。唯一要注意的是不要直接调用库函数来解决,这样就丧失了理解原理的作用了。
void reverseString(vector<char>& s) {
for (int i = 0, j = s.size() - 1; i < s.size()/2; i++, j--) {
swap(s[i],s[j]);
}
}
这是示例代码,使用了swap函数和循环来做的,更加简洁
541. 反转字符串II
void reverse(string& s, int start, int end) {
for (int i = start,j = end; i < j; i++, j--) {
swap(s[i], s[j]);
}
}
string reverseStr(string s, int k) {
int length = s.size();
for (int i = 0; i < length; i += 2*k) {
if (i+k <= length) {
reverse(s, i, i+k-1);
}
else {
reverse(s, i, length-1);
}
}
return s;
}
模拟题,使用循环i+=2*k来进行计数每2k个数,若后面还有k个数字或更多,则翻转k个字母,否则翻转至结尾的字母。这道题的启示是当要一段一段去处理数据的时候,循环中的索引可以不只加一,而是可以加一整段。
剑指Offer 05.替换空格
题目链接/文章讲解: 代码随想录
string pathEncryption(string path) {
string result = "";
for (int i = 0; i < path.size(); i++) {
if (path[i] != '.')
result += path[i];
else result += ' ';
}
return result;
}
这道题好像很轻松,直接将.替换即可。
原来是力扣貌似把剑指offer的题删掉了,原来第题目是这样的:
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
示例 1: 输入:s = "We are happy."
输出:"We%20are%20happy."
string replaceSpace(string s) {
int count = 0; // 统计空格的个数
int sOldSize = s.size();
for (int i = 0; i < s.size(); i++) {
if (s[i] == ' ') {
count++;
}
}
// 扩充字符串s的大小,也就是每个空格替换成"%20"之后的大小
s.resize(s.size() + count * 2);
int sNewSize = s.size();
// 从后先前将空格替换为"%20"
for (int i = sNewSize - 1, j = sOldSize - 1; j < i; i--, j--) {
if (s[j] != ' ') {
s[i] = s[j];
} else {
s[i] = '0';
s[i - 1] = '2';
s[i - 2] = '%';
i -= 2;
}
}
return s;
}
这道题不再开一个字符串来存储答案的做法是这样的,首先先算出字符串中的空格数量,然后将原有的字符串扩容,再通过双指针的方法,一个指针指向原字符串最后一个字母,一个指针指向现在字符串的结尾,从后向前来填充字符串和%20即可。
其实很多数组填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。
这么做有两个好处:
- 不用申请新数组。
- 从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。
151.翻转字符串里的单词
题目链接/文章讲解/视频讲解: 代码随想录
void removeExtraSpace(string& s) { //使用双指针做法
int slow = 0, fast = 0;
//先移除前面的空格
for (int i = 0; i < s.size(); i++) {
if (s[i] == ' ')
fast++;
else break;
}
//再去除中间多余的空格
for (; fast < s.size(); fast++) {
if (fast-1 > 0 && s[fast] == ' ' && s[fast] == s[fast-1])
continue; //如果有两个重复空格则跳过
else {
s[slow++] = s[fast];
}
}
//再去除尾部的空格
if (s[slow-1] == ' ')
s.resize(slow-1);
else s.resize(slow);
}
string reverseWords(string s) {
removeExtraSpace(s);
reverse(s.begin(), s.end());
int left = 0;
for (int i = 0; i < s.size(); i++) {
if (s[i] == ' ') {
reverse(s.begin()+left, s.begin()+i);
left = i+1;
}
else if (i == s.size()-1)
reverse(s.begin()+left, s.end());
}
return s;
}
这道题应该先去除头部、中间重复的和尾部的空格再进行翻转单词操作。在去除空格函数中,采用的是双指针的方法,如果快指针找到要删除的空格则跳过,否则就让满指针的位置复制上快指针的元素,最后在调整字符串大小即可完成去空格。在翻转单词部分,也很简单,只需要全部翻转字符串,然后再在遇到空格的地方,翻转相应的单词即可完成单词翻转。
剑指Offer58-II.左旋转字符串
string dynamicPassword(string password, int target) {
reverse(password.begin(), password.end());
reverse(password.begin(), password.end()-target);
reverse(password.end()-target, password.end());
return password;
}
这道题只需先全部翻转,然后再按照target的位置,翻转后就是从后向前第target的位置在相应做翻转操作即可