题目:344.反转字符串

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

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

示例 1:

输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"]

示例 2:

输入:s = ["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]

思路:这道题考察的是reverse函数的实现,因此不能直接使用reverse,可以使用双指针的方式来实现。

class Solution {
public:
    void reverseString(vector<char>& s) {
        int left = 0;
        int right = s.size() -1;
        while(left<right){
            swap(s[left],s[right]);
            left++;
            right--;
        }
    }
};

swap函数的实现有以下两种:

一种就是常见的交换数值:

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

一种就是通过位运算:

s[i] ^= s[j];
s[j] ^= s[i];
s[i] ^= s[j];

位运算异或运算(XOR)的例子:

“两个输入不同时,结果为 1;否则为 0

异或运算的真值表

A

B

A XOR B

0

0

0

0

1

1

1

0

1

1

1

0

假设 s[i] = 5s[j] = 3(二进制 5 = 1013 = 011):

  1. s[i] ^= s[j]5 ^ 3 = 6110

    • s[i] = 6, s[j] = 3

  2. s[j] ^= s[i]3 ^ 6 = 5101

    • s[i] = 6, s[j] = 5

  3. s[i] ^= s[j]6 ^ 5 = 3011

    • s[i] = 3, s[j] = 5

最终 s[i]s[j] 的值互换。

题目:541. 反转字符串II

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

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

  • 如果剩余字符少于 k 个,则将剩余字符全部反转。

  • 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。

思路:这道题目可以跟着题目的要求走,是一个模拟的过程,将滑动的窗口长度定为2k,每次的操作都在这个窗口中进行

class Solution {
public:
    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() + i+k);
            }else{
                reverse(s.begin() + i,s.end());
            }
        }
        return s;
    }
};

题目: 替换数字

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

题目描述

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

输入描述

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

输出描述

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

输入示例
a1b2c3
输出示例
anumberbnumbercnumber

思路:这道题目可以在不创建新的字符串的前提下进行实现,只需要对元字符串的大小进行修改后,运用双指针的方法从后往前遍历,其中一个指针指向的是修改大小后新字符串的末尾,一个指针指向的是原字符串的末尾。

需要注意的是在找到字符串中的数字个数后,在resize元字符串大小时只需要乘以5

#include <iostream>
using namespace std;
​
int main() {
  string s;
  while (cin >> s) {
    int s_index = s.size() - 1;
    int count = 0;
    for (int i = 0; i < s.size(); i++) {
      if (s[i] >= '0' && s[i] <= '9') {
        count++;
      }
    }
    //注意此处是乘以5,因为是替换有一个位置被原来的数字所占用,因此每多一个数字就多5个空
    s.resize(s.size() + count * 5);
​
    int last_index = s.size() - 1; // reseize后的s的末尾位置
    while (s_index >= 0) {
      if (s[s_index] >= '0' && s[s_index] <= '9') {
        s[last_index--] = 'r';
        s[last_index--] = 'e';
        s[last_index--] = 'b';
        s[last_index--] = 'm';
        s[last_index--] = 'u';
        s[last_index--] = 'n';
      } else {
        s[last_index--] = s[s_index];
      }
      s_index--;
    }
    cout << s;
  }
}