• 【string题解 C++】翻转字符串II:区间部分翻转 | 验证回文串


    目录

    翻转字符串II:区间部分翻转

    思路

    实现

    更好的解决方式

    验证回文串

    思路

    实现

    更好的解决方式


    翻转字符串II:区间部分翻转

    力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

    难度:简单

    给定一个字符串 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"

    思路

    其实这道题难点在于理解题目到底想干嘛,get到它的意图以后,实现起来就不难了。

    而理解题意,最好的办法是画图:

    画出这几种情况后,我们发现,题意实际为:反转每个 下标从 2k 的倍数开始的,长度为 k 的子串。若该子串长度不足 k,则反转整个子串。(理解题意真的很重要!!)

    可以对string实现分组,每k个为一组,然后组与组之间间隔着反转(第一组反转,第二组不反转,第三组反转……)。

    实现

    1. class Solution {
    2. public:
    3.   string reverseStr(string s, int k) {
    4.       int num=s.size();
    5.       int i=0;
    6.       int multiple=0;   //left的下标是成倍增长的,所以我们引入multiple
    7.       while(i
    8.           int left=2k*multiple;
    9.           if(left//能进说明有left存在,也就是说有可被反转的组
    10.               if(left+k
    11.                   int right=left+k;
    12.                   reverse(s.begin()+left,s.begin()+right);
    13.               }
    14.               else{   //能进这里说明:到字符串的末尾了
    15.                   reverse(s.begin()+left,s.end());
    16.                   break;
    17.               }
    18.               multiple++;
    19.               i=left;
    20.           }
    21.           else{
    22.               break;
    23.           }
    24.       }
    25.       return s;
    26.   }
    27. };

    更好的解决方式

    遍历一遍string,下标为2k倍数的都拿去reverse。注意看这里对于末尾的处理,巧妙地运用了min函数:

    1. class Solution {
    2. public:
    3.   string reverseStr(string s, int k) {
    4.       int num=s.size();
    5.       for(int i=0;i2*k){
    6.           reverse(s.begin()+i,s.begin()+min(i+k,num));
    7.       }
    8.       return s;
    9.   }
    10. };

    验证回文串

    力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

    难度:简单

    如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串

    字母和数字都属于字母数字字符。

    给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false

    示例 1:

    1. 输入: s = "A man, a plan, a canal: Panama"
    2. 输出:true
    3. 解释:"amanaplanacanalpanama" 是回文串。

    示例 2:

    1. 输入:s = "race a car"
    2. 输出:false
    3. 解释:"raceacar" 不是回文串。

    示例 3:

    1. 输入:s = " "
    2. 输出:true
    3. 解释:在移除非字母数字字符之后,s 是一个空字符串 ""
    4. 由于空字符串正着反着读都一样,所以是回文串。

    思路

    我们可以实例化出两个string变量:str1、str2。

    首先,遍历字符串 ,将其过滤出来的数字字符 正着放进str1。

    然后,遍历str1 ,将其反着放进str2。

    最后,遍历str1和str2,对比两者。

    实现

    1. class Solution {
    2. public:
    3.   bool isPalindrome(string s) {
    4.       if(s==" "){
    5.           return true;
    6.       }
    7.       int num=s.size();
    8.       string str1,str2;
    9.       for(int i=0;i
    10.           if(s[i]>='0'&&s[i]<='9'
    11.           ||s[i]>='A'&&s[i]<='Z'
    12.           ||s[i]>='a'&&s[i]<='z'){
    13.               if(s[i]>='A'&&s[i]<='Z'){   //大写转小写
    14.                   s[i]+='a'-'A';
    15.               }
    16.               str1.push_back(s[i]);   //正着插入str1  
    17.           }
    18.       }
    19.        
    20.       string::reverse_iterator rit=str1.rbegin(); //反着插入str2
    21.       while(rit!=str1.rend()){
    22.           str2.push_back(*rit);
    23.           rit++;
    24.       }
    25.       for(int i=0;isize();i++){   //遍历str1、str2,对比两者
    26.           if(str1[i]!=str2[i]){
    27.               return false;
    28.           }
    29.       }
    30.       return true;
    31.   }
    32. };

    更好的解决方式

    同样的思路,怎么实现才能优化上面的代码?

    1.用库里的函数!多用才能熟练。目前我们不知道有哪些函数可以为我所用,不要紧,看题解,它用的函数我们没用过,那我就自己再写一遍,把这个函数拿出来多用用。

    2.字符串的比较不需要再遍历的。直接用str1==str2。

    1. class Solution {
    2. public:
    3.   bool isPalindrome(string s) {
    4.       string str1;
    5.       for(auto ch:s){
    6.           if(isalnum(ch)){
    7.               if(ch>='A'&&ch<='Z'){
    8.                   ch+='a'-'A';
    9.               }
    10.               str1+=ch;
    11.           }
    12.       }
    13.       string str2(str1.rbegin(),str1.rend());
    14.       return str1==str2;
    15.   }
    16. };

    这种写法的时间复杂度为O(n)(n为字符串的长度)。空间复杂度为O(n)。

    关于函数isalnum:

    用于判断是否是数字or字符串。

    只有在函数isdigit()(判断是否为数字的)和isalpha()(判读是否为字母的)都返回true时,isalnum才会返回true。

  • 相关阅读:
    视频剪辑教程:批量修改视频尺寸的简单方法
    tensorflow模型训练图片
    RK3568笔记四:基于TensorFlow花卉图像分类部署
    Bazzite:专为 Steam Deck 和 PC 上的 Linux 游戏打造的发行版
    当transcational遇上synchronized
    Python多线程方案
    Linux命令(二)(文件相关)
    【MYSQL】 三大范式 表的关系 外键 ER图
    数字增益和模拟增益理解和示例
    ChatGPT模型api的python调用
  • 原文地址:https://blog.csdn.net/2301_76540463/article/details/133841644