代码随想录算法训练营第8天|● 344.反转字符串● 541. 反转字符串II● 卡码网:54.替换数字● 151.翻转字符串里的单词● 卡码网:55.右旋转字符串

344.反转字符串

思路:利用双指针进行字符串反转,i,j指数组头和尾,i,j下标指向元素两两交换,不断内缩,i也控制交换趟数。

代码:

void reverseString(vector& s) {
        int j = s.size()-1;
        int temp;
        for(int i = 0;i < s.size()/2;i++,j--){
            temp = s[i];
            s[i] = s[j];
            s[j] = temp;
        }
    }

541.反转字符串||

思路:每次处理的数组可以看作区间大小为2k的子数组,则每次for前进以2k大小前进,题目虽然给了3个反转条件,可以整理下1.若有2k个字符,反转前k个 2.若剩下字符小于2k且大于等于k,则反转前k个 3.若剩下字符小于k个,反转剩下的;对于以上条件,没必要还去分别判断字符满足多少个,其核心就是当前子区间是否满足k个?满足就反转k个,不满足就反转剩下的。

代码:

string reverseStr(string s, int k) {
        for(int i = 0;i < s.size();i += (2*k)){
            if(i + k < s.size()){//
            reverse(s.begin()+i,s.begin()+k+i);
            continue;
            }
            reverse(s.begin()+i,s.begin()+s.size());//剩的字符小于k个
        }
        return s;
    }

还需要注意.begin()是从哪算起的。是从当前下标索引的前面算起。如图:例s.begin()+0,s.begin()+2代码随想录算法训练营第8天|● 344.反转字符串● 541. 反转字符串II● 卡码网:54.替换数字● 151.翻转字符串里的单词● 卡码网:55.右旋转字符串_第1张图片

151.反转字符串里面的单词

要求其空间复杂度为O(1)

思路:1.删除多余空格 2.整个字符串反转 3.每个单词反转

1.删除多余空格指每个单词之间仅能保留一个空格,并且字符串的最前面和最后是没有空格的。删除空格可以看作是删除元素,该思路可以参考27.移除元素的双指针法,利用快指针寻找符合条件元素,慢指针用于存储元素。

2和3.一个单词反转两次就是其本身

步骤图解:代码随想录算法训练营第8天|● 344.反转字符串● 541. 反转字符串II● 卡码网:54.替换数字● 151.翻转字符串里的单词● 卡码网:55.右旋转字符串_第2张图片

void RemoveExtraSpaces(string &s){//删除多余空格,参考27.移除元素双指针法
        int slow = 0;//快指针找符合条件的元素,慢指针为元素存放的位置
        for(int fast = 0;fast < s.size();fast++){
            if(s[fast] != ' '){//快指针遇到非空格就跳过(删除) 
                if(slow != 0)   s[slow++] = ' ';//给单词之间添加空格,
                //只有经过下面的while(已经存在一个单词),且再次进入上面的if(本次又至少存在一个单词),该if才会执行(给上个单词和这个单词添加空格)
                while(fast < s.size() && s[fast] != ' '){//移动单词,如果遇到空格,则说明该单词结束
                    s[slow++] = s[fast++];
                }
            }
        }
        s.resize(slow);//重新定义s的大小,因为数组不能真正删除元素,只有覆盖,所以需要手动设置更新后的大小
    }

    void reverse(string &s,int start,int end){//左闭右开
        end = end-1;
        for(;start < end;start++,end--){
            swap(s[start],s[end]);
        }
    }

    string reverseWords(string s) {
        RemoveExtraSpaces(s);//第一步.删除空格
        reverse(s,0,s.size());//第二步,整体反转
        for(int start = 0;start < s.size();){//第三步,子数组(单词)反转
            int end = start;
            while(end < s.size() && s[end] != ' ')    end++;
            reverse(s,start,end);
            start = end+1;//更新下一个单词的起始位置
        }
        return s;
    }

删除空格的另外一个解法利用erase函数删除,由于数组元素是不能删除的,只能覆盖,所以该函数时间复杂度O(n),又因为该函数外套了层for循环(需要一个一个找空格),所以整体的时间复杂度会是O(n^2)。如果用双指针法,时间复杂度仅O(n)

 54.替换数字     55.右旋字符串 

这两题在卡码网,且网站解析和思路更详细。

你可能感兴趣的:(算法,数据结构)