如果题目的关键部分直接用库函数就可以解决,那建议不要使用库函数,如果库函数仅仅是解题过程中的一部分,且十分清楚内部原理的话,可以考虑使用库函数
class Solution {
public:
void reverseString(vector& s) {
int first = 0;
int last = s.size()-1;
for(;first
// 可以对字符串直接处理,不用转成数组
class Solution {
public:
string reverseStr(string s, int k) {
for(int i=0; i s.size()-1){
reverse(s.begin()+i, s.end());
}
// 否则翻转前k 注意第二项填的是下一个指针,即左闭右开
else{
reverse(s.begin()+i, s.begin()+i+k);
}
}
return s;
}
};
本题中,reverse不是关键,所以可以直接用库,库函数输入的是地址
如果要自己写reverse,如果写成左闭右闭,那输入时要记得-1
很多数组填充问题,都是预先给数组扩容填充后的大小,然后从后往前进行操作,两个好处
具体步骤:
1-求空格数
2-扩充字符串,利用resize方法,扩充大小为空格数*2
3-快指针j和慢指针i,j从原字符串末尾开始,i从新字符串末尾开始,同时向左遍历,如果j遇到空格,则i填充0 2 %;如果j不是空格,则i填充与j相同的值
class Solution {
public:
string replaceSpace(string s) {
// 求空格个数
int count = 0;
// for(int i=0; i
分三步走:
1-移除多余空格,只剩下单词中间的一个空格
2-进行翻转,可以利用reverse(),时间复杂度也是O(n) (因为这一步不是关键步骤,所以可以用库函数,如果要写可以参照上面第一题)
3-每个单词内进行翻转
本题重点是移除多余空格,如果使用库函数erase(),则时间复杂度为O(n^2) (因为是在遍历中erase,纯erase是O(n)),所以应用双指针法,为O(n)
快指针要遍历全部元素
如果快指针指向元素不为空,就要进入一个循环,让fast后面的一个单词赋给slow(即fast指向空或者到头时跳出循环)
但在单词赋值之前要判断一下,这个单词是否为第一个单词,如果不是第一个单词,就要给slow先赋空格,再从fast把单词搬过来
class Solution {
public:
// 注意自定义的两个函数传递的是地址
// 翻转函数,要输入头和尾是方便后面单词的翻转
void reverse(string& s, int begin, int end){
for(int i=begin, j=end; i
包含三部分:翻转指定范围元素、去除多余空格(重点)、根据空格间隔翻转每个单词
在最后一部分中,巧妙的写法是i可以等于s.size(),这样把fast指向结尾的情况考虑进去,不用再分情况讨论
注意:自定义的两个函数传的是地址,不用return,而题目中给的函数是传入string类型返回string类型的,不是地址
思路:整体翻转+局部翻转的思路(实际为两个局部翻转,再整体翻转)
class Solution {
public:
void reverse(string& s, int begin, int end){
for(int i=begin, j=end; i
今日四道题都是反转问题。344 反转字符串是最简单,利用双指针;541 反转字符串Ⅱ加上条件,利用规律一段一段反转;151反转字符串中单词,先整体反转,再把每个单词反转回来(但这道题中最难的是去除多余空格-双指针法);最后一题左旋转字也是利用整体反转+局部反转
剩下一道替换空格,为先扩充数组,再利用双指针法,从后往前填充(如果从前往后会每次都让后面元素全部后移,时间复杂度O(n^2))