Day7 | 344.反转字符串 541. 反转字符串II 卡码网54.替换数字

37 阅读3分钟

344. 反转字符串 - 力扣(LeetCode)

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用O(1)O(1)的额外空间解决这一问题。

左右指针

class Solution {
public:
    void reverseString(vector<char>& s) {
        int size = s.size();
        char temp;//O(1)的额外空间
        int left = 0;
        int right = size-1;
        while(left<right){
        //如果是奇数长度,会出现left=right,但共同指向一个元素,且该元素本就在中间位置,不用动
        //如果是偶数长度,最后一次满足left<right时,left+1=right,完成中间两个元素的互换,left和right各走一步
        //此时left>right(left=right+1),退出循环,已完全全部元素互换
            temp = s[left];
            s[left]=s[right];
            s[right] = temp;
            left++;
            right--;
        }
    }
};

541. 反转字符串 II - 力扣(LeetCode)

给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。

  • 如果剩余字符少于 k 个,则将剩余字符全部反转。
  • 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
class Solution {
public:
    string reverseStr(string s, int k) {
        int size = s.size();
        int loop = size/(2*k);//整除2k,代表除最后一次外,需要反转的次数
        int rest = size%(2*k);//对2k求余,不足2k个的需特殊处理
        int left = 0;
        int right = size-1;
        char temp;
        while(loop){//
            left = (loop-1)*2*k;   //从后往前处理
            right = left+k-1;      //反转k个,右边界=左边界+(k-1)
            
            //swap实现
            while(left<right){
                temp = s[left];
                s[left] = s[right];
                s[right] = temp;
                left++;
                right--;
            }
            
            loop--;//完成一次循环,自减
        }

        int max = size/(2*k);  //也是循环次数
        left = max*2*k;        //剩下的不足2k个的子串的起始位置
        right = (rest<k)?size-1:left+k-1;  //根据题目要求决定翻转多少个元素
        
        //swap实现
        while(left<right){
            temp = s[left];
            s[left] = s[right];
            s[right] = temp;
            left++;
            right--;
        }
        return s;
    }
};

54. 替换数字(第八期模拟笔试)

题目描述

给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。 例如,对于输入字符串 "a1b2c3",函数应该将其转换为 "anumberbnumbercnumber"。

输入描述

输入一个字符串 s,s 仅包含小写字母和数字字符。

输出描述

打印一个新的字符串,其中每个数字字符都被替换为了number

输入示例
a1b2c3
输出示例
anumberbnumbercnumber
提示信息

数据范围:
1 <= s.length < 10000。

遍历字符串,确定数字字符的个数,从而计算替换后的字符串的大小

替换要从尾部开始,如果从头部,每次遇到数字字符,都要在当前元素后面插入5个元素

【'1'】→【'n'】【'u''m''b''e''r'】,这样每次都涉及后面元素的搬移,时间复杂度变为O(N2)O(N^2)

#include<iostream>

int main(){
    std::string s;  //输入的字符串
    int size;  //字符数
    int num_count;

    int cur;

    while(std::cin>>s){
        size = s.size();
        num_count = 0;//记录数字的个数
        for(int i = 0;i < size;i++){
            if(s[i]>='0' && s[i]<='9') num_count++;
        }

        s.resize(size+num_count*5);  //增加number6位,去掉数字1位,所以有一个数字就要扩5
        cur = s.size();//扩容后,从最后开始填充
        for(int j = size;j >= 0;j--){
            if(s[j]>='0' && s[j]<='9'){
                s[cur] = 'r';
                s[--cur] = 'e';
                s[--cur] = 'b';
                s[--cur] = 'm';
                s[--cur] = 'u';
                s[--cur] = 'n';
                cur--;
            }
            else s[cur--] = s[j];
        }

        std::cout<<s<<std::endl;
    }

    return 0; 
}

swap实现

temp

int tmp = s[i];
s[i] = s[j];
s[j] = tmp;

异或

位运算:若相同,异或结果为0;若不同,结果为1

A0=AA⊕0=A

s[i] ^= s[j];  //s[i] = s[i]⊕s[j]
s[j] ^= s[i];  //s[j] = s[j]⊕(s[i]⊕s[j])=(s[i]⊕s[j])⊕s[j](交换律)=s[i]⊕s[j]⊕s[j]=s[i]0(结合律)=s[i]
s[i] ^= s[j];  //s[i] = s[i]⊕s[j]⊕s[i] = s[j](同上)