经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » 编程经验 » 查看文章
代码随想录Day8
来源:cnblogs  作者:Murder!sans  时间:2024/8/7 11:43:57  对本文有异议

344.反转字符串

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

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

示例 1:

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

示例 2:

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

提示:

1 <= s.length <= 105
s[i] 都是 ASCII 码表中的可打印字符


正解(双指针)

思路

上代码(●'?'●)
  1. class Solution {
  2. public:
  3. void reverseString(vector<char>& s) {
  4. for (int i = 0, j = s.size() - 1; i < s.size()/2; i++, j--) {
  5. swap(s[i],s[j]);
  6. }
  7. }
  8. };

541. 反转字符串II

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

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

示例 1:

  1. 输入:s = "abcdefg", k = 2
  2. 输出:"bacdfeg"

示例 2:

  1. 输入:s = "abcd", k = 2
  2. 输出:"bacd"

提示:

1 <= s.length <= 104
s 仅由小写英文组成
1 <= k <= 104


正解(模拟+STL)

这道题目其实也是模拟,实现题目中规定的反转规则就可以了。
其实在遍历字符串的过程中,只要让 i += (2 * k),i 每次移动 2 * k 就可以了,然后判断是否需要有反转的区间。
因为要找的也就是每2 * k 区间的起点,这样写,程序会高效很多。
所以当需要固定规律一段一段去处理字符串的时候,要想想在在for循环的表达式上做做文章。

上代码(●'?'●)
  1. class Solution {
  2. public:
  3. string reverseStr(string s, int k) {
  4. for (int i = 0; i < s.size(); i += (2 * k)) {
  5. // 1. 每隔 2k 个字符的前 k 个字符进行反转
  6. // 2. 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
  7. if (i + k <= s.size()) {
  8. reverse(s.begin() + i, s.begin() + i + k );
  9. } else {
  10. // 3. 剩余字符少于 k 个,则将剩余字符全部反转。
  11. reverse(s.begin() + i, s.end());
  12. }
  13. }
  14. return s;
  15. }
  16. };

卡码网:54.替换数字

题目描述
给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。 例如,对于输入字符串 "a1b2c3",函数应该将其转换为 "anumberbnumbercnumber"。
输入描述
输入一个字符串 s,s 仅包含小写字母和数字字符。
输出描述
打印一个新的字符串,其中每个数字字符都被替换为了number
输入示例

  1. a1b2c3

输出示例

  1. anumberbnumbercnumber

提示信息
数据范围:
1 <= s.length < 104


正解(双指针)

首先扩充数组到每个数字字符替换成 "number" 之后的大小。
例如:字符串 "a5b" 的长度为3,那么将数字字符变成字符串 "number" 之后的字符串为 "anumberb" 长度为 8。
然后从后向前替换数字字符,也就是双指针法,过程如下:i指向新长度的末尾,j指向旧长度的末尾。
思路
其实很多数组填充类的问题,其做法都是先预先给数组扩容带填充后的大小,然后在从后向前进行操作。
这么做有两个好处:

  1. 不用申请新数组。
  2. 从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。
上代码(●'?'●)
  1. #include <iostream>
  2. using namespace std;
  3. int main() {
  4. string s;
  5. while (cin >> s) {
  6. int sOldIndex = s.size() - 1;
  7. int count = 0; // 统计数字的个数
  8. for (int i = 0; i < s.size(); i++) {
  9. if (s[i] >= '0' && s[i] <= '9') {
  10. count++;
  11. }
  12. }
  13. // 扩充字符串s的大小,也就是将每个数字替换成"number"之后的大小
  14. s.resize(s.size() + count * 5);
  15. int sNewIndex = s.size() - 1;
  16. // 从后往前将数字替换为"number"
  17. while (sOldIndex >= 0) {
  18. if (s[sOldIndex] >= '0' && s[sOldIndex] <= '9') {
  19. s[sNewIndex--] = 'r';
  20. s[sNewIndex--] = 'e';
  21. s[sNewIndex--] = 'b';
  22. s[sNewIndex--] = 'm';
  23. s[sNewIndex--] = 'u';
  24. s[sNewIndex--] = 'n';
  25. } else {
  26. s[sNewIndex--] = s[sOldIndex];
  27. }
  28. sOldIndex--;
  29. }
  30. cout << s << endl;
  31. }
  32. }

这种做法时间复杂度为\(O(n)\)
相比之下,从前向后填充的方法时间复杂度为\(O(n^2)\)
双指针大法好( ̄︶ ̄)↗ 

写博不易,请大佬点赞支持一下8~

原文链接:https://www.cnblogs.com/Murder-sans/p/18346760/dmsxl_Day8

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号