首页 > 编程语言 >算法训练营Day08-LeetCode344. 反转字符串 && 541. 反转字符串 II && 151. 反转字符串中的单词 && KamaCoder54. 替换数字

算法训练营Day08-LeetCode344. 反转字符串 && 541. 反转字符串 II && 151. 反转字符串中的单词 && KamaCoder54. 替换数字

时间:2024-04-11 13:58:05浏览次数:26  
标签:字符 int 反转 单词 && 字符串 size

344. 反转字符串

题目链接:LeetCode344. 反转字符串

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

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

思路:字符串首尾字符交换即可完成反转。定义首尾双指针同样可以。

code:

class Solution {
public:
    void reverseString(vector<char>& s) {
        int n = s.size();
        for(int i = 0; i < n / 2; i++){
            // 交换数值法
            // char temp = s[i];
            // s[i] = s[n - i - 1];
            // s[n - i - 1] = temp;

            // 通过位运算交换
            s[i] ^= s[n - i - 1];
            s[n - i - 1] ^= s[i];
            s[i] ^= s[n - i - 1];
        }
    }
};

总结:学习到了位运算交换法。


541. 反转字符串 II

题目链接:LeetCode541. 反转字符串 II

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

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

思路:遍历下标步长设置为 2k ,除非剩余字符少于 k 个,进行直接反转,否则反转前 k 个字符。

code:

class Solution {
public:
    void reverse(string& s, int start, int end){
        for(int i = start, j = end; i < j; i++, j--){
            swap(s[i], s[j]);
        }
    }

    string reverseStr(string s, int k) {
        for(int i = 0; i < s.size(); i += 2 * k){
            if(i + k <= s.size()){
                reverse(s, i, i + k -1);
                continue;
            }
            reverse(s, i, s.size() - 1);
        }
        return s;
    }
};

总结:当需要以固定规律一段一段去处理字符串的时候,可以调整遍历下标步长,满足要求。


KamaCoder54. 替换数字

题目链接:KamaCoder54. 替换数字

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

思考过程:暴力法,遍历字符串,统计数字字符出现次数;开辟新数组,数组长度为 小写字母个数 + 数字字符个数 * 6;然后填充新数组。但是占用空间较大。

调整思路:遍历字符串,统计数字字符出现次数;扩充原有数组,扩充后数组长度为 s.size() + 数字字符个数 * 5;使用双指针法,从后向前填充。

code:

#include <iostream>

using namespace std;

int main(){
    int cnt = 0;
    string s;
    cin >> s;
    int sOldIndex = s.size() - 1;
    for(int i = 0; i < s.size(); i++){
        if(s[i] <= '9' && s[i] >= '0'){
            cnt++;
        }
    }
    
    s.resize(sOldIndex + 1 + cnt * 5);
    int sNewIndex = s.size() - 1;
    
    while(sOldIndex >= 0){
        if(s[sOldIndex] <= '9' && s[sOldIndex] >= '0'){
            s[sNewIndex--] = 'r';
            s[sNewIndex--] = 'e';
            s[sNewIndex--] = 'b';
            s[sNewIndex--] = 'm';
            s[sNewIndex--] = 'u';
            s[sNewIndex--] = 'n';
        }else{
            s[sNewIndex--] = s[sOldIndex];
        }
        sOldIndex--;
    }
    cout << s << endl;
}

总结:为什么要从后向前填充,从前向后填充不行么?

从前向后填充就是O(n^2)的算法了,因为每次添加元素都要将添加元素之后的所有元素整体向后移动。

其实很多数组填充类的问题,其做法都是先预先给数组扩容带填充后的大小,然后在从后向前进行操作。

这么做有两个好处:

  1. 不用申请新数组。
  2. 从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。

151. 反转字符串中的单词

题目链接:LeetCode151. 反转字符串中的单词

给你一个字符串 s ,请你反转字符串中 单词 的顺序。

单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。

返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。

注意:输入字符串 s 中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。

分析:题目要求将单词顺序反转,单词字母构成顺序不变。因此可以先将字符串整体反转,然后遇到单词再次反转即可达到要求。重点在于如何去除额外空格。这里先将空格元素全部移除,然后在相邻单词中间添加一个空格。

code:

class Solution {
public:
    void reverse(string& s, int start, int end){
        for(int i = start, j = end; i < j; i++, j--){
            swap(s[i], s[j]);
        }
    }

    void removeExtraSpace(string& s){
        int slow = 0;
        for(int fast = 0; fast < s.size();){
            if(s[fast] != ' '){
                if(slow > 0){
                    s[slow++] = ' ';
                }
                while(s[fast] != ' ' && fast < s.size()){
                    s[slow++] = s[fast++];
                }
            }else{
                fast++;
            }
        }
        s.resize(slow);
    }

    string reverseWords(string s) {
        removeExtraSpace(s);
        reverse(s, 0, s.size() - 1);
        for(int i = 0, j = 0; i < s.size(); i++){
            while(s[i] != ' ' && i < s.size()) i++; // 统计每个单词字母个数
            reverse(s, j, i - 1);
            j = i + 1; // 记录下一个单词反转起始下标
        }
        return s;
    }
};

KamaCoder54. 替换数字

题目链接:KamaCoder54. 替换数字

字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字符移到字符串的前面,实现字符串的右旋转操作。

例如,对于输入字符串 “abcdefg” 和整数 2,函数应该将其转换为 “fgabcde”。

思路:题目和 LeetCode151. 反转字符串中的单词 类似,甚至更简单。这里可以将由输入 k 得到的两部分子串,看成两个单词,依然是单词内部顺序不变,单词顺序反转。可通过先整体再局部反转实现。

code:

#include<iostream>
#include<algorithm>

using namespace std;

int main() {
    int k;
    string s;
    cin >> k;
    cin >> s;
    int length = s.size();

    reverse(s.begin(), s.end());
    reverse(s.begin(), s.begin() + k);
    reverse(s.begin() + k, s.end());
    
    cout << s << endl;
} 

总结:同样可以先局部反转再整体反转,注意下标变化。


参考文章:

代码随想录-字符串-541. 反转字符串> II
代码随想录-字符串-KamaCoder54. 替换数字
代码随想录-字符串-151. 反转字符串中的单词

标签:字符,int,反转,单词,&&,字符串,size
From: https://blog.csdn.net/weixin_45601033/article/details/137608121

相关文章

  • 输入流和字符串互转InputStream2String和String2InputStream
    输入流转字符串12345678910111213141516171819public static StringInputStream2String(InputStreamin){    InputStreamReaderreader= null;    try {        reader= new InputStreamReader(in, "UTF-8");   ......
  • java代码将16进制字符串转换为图片,jdbc入库blob字段,解决ORA-01704,PLS-00172,ORA-06550,
    从Oracle导出SQL文件中的insert语句包含blob字段,语句HEXTORAW函数将16进制的字符串入库,由于字符串太长,insert失败下面的代码读取完整的insert语句,将HEXTORAW函数连同16进制的字符串替换为NULL,先将字段置空插入记录,然后使用PreparedStatement对图片文件读流更新入库importorg.......
  • Java中将字符串转换成数字的方法
    转换为整数(int)你可以使用Integer.parseInt()方法或Integer.valueOf()方法将字符串转换为int类型。javaStringstr="123";intnumber=Integer.parseInt(str);//使用parseInt//或者intnumberValue=Integer.valueOf(str);//使用valueOfSystem.out.println(number);//......
  • 两个纯数字字符串相加Python实现版
    """两个字符串相加模拟两个大整数相加,但是不能直接相加,采用每一位相加的方式"""defadd_large_numbers(num1,num2):#反转字符串,方便从低位开始相加num1=num1[::-1]num2=num2[::-1]#初始化结果列表和进位result=[]carry=0#......
  • C语言: 字符串函数(下)
    片头在上一篇中,我们介绍了字符串函数。在这一篇章中,我们将继续学习字符串函数,准备好了吗?开始咯!1.strncpy函数1.1strncpy函数的用法strncpy是C语言中的一个字符串处理函数,它用于将一个字符串的一部分内容复制到另一个字符串中。其函数原型为:char*strncpy(char*dest......
  • leedcode-反转字符串中的元音字母
    自己写的,双指针,一次通过classSolution:defreverseVowels(self,s:str)->str:#将输入的字符串转换为列表s_list=list(s)#定义元音字母列表vowels=['a','e','i','o','u','A&......
  • JZ24-反转链表
    /***structListNode{* intval;* structListNode*next;* ListNode(intx):val(x),next(nullptr){}*};*/#include<cstddef>classSolution{public:/***代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可*......
  • 后缀数组--SA--字符串
    SA(SuffixArray)--后缀数组简介这里明白两个定义:\(SA_i\):按字典序排列后大小为\(i\)的后缀的后缀头的下标。\(Rank_i\):后缀头的下标为\(i\)按字典序排列后的排名。一个显而易见却很重要的结论:\[SA[Rank[i]]=Rank[SA[i]]=i\]如何进行后缀排序?暂且挂oi......
  • Leetcode反转字串541/翻转字串的单词151/实现 strStr方法28/重复的子字符串459
    前言Leetcode541/151/28一、541题(反转字符串)题目描述:给定一个字符串s和一个整数k,从字符串开头算起,每计数至2k个字符,就反转这2k字符中的前k个字符。如果剩余字符少于k个,则将剩余字符全部反转。如果剩余字符小于2k但大于或等于k个,则反转前k个字符,其余......
  • Python基础--python数据结构(字符串、列表和元组)
    前言!!!注意:本系列所写的文章全部是学习笔记,来自于观看视频的笔记记录,防止丢失。观看的视频笔记来自于:哔哩哔哩武沛齐老师的视频:2022Python的web开发(完整版)入门全套教程,零基础入门到项目实战数据结构1.字符串类型str1.1定义上个文件找1.2独有功能大写upper......