Leetcode刷题笔记12

HJ1 字符串最后一个单词的长度

字符串最后一个单词的长度_牛客题霸_牛客网

这里可以使用rfind(),rfind()函数从字符串的末尾向前查找第一个空格的位置。这个空格将是最后一个单词和前面的单词的分隔符。首先使用getline读取字符串,然后用rfind找到最后一个空格的位置,最后根据找到的位置,计算最后一个单词的长度并输出。getline 的作用是从标准输入(cin)中读取一行文本,并将其存储到 word 字符串中。getline 读取操作在遇到换行符(\n)时结束,但换行符本身不会被存储到 word 中

代码:C++

#include <iostream>
using namespace std;

int main() {
    
    string str;
    // cin>>str;
    getline(cin,str);
    size_t pos = str.rfind(' ');
    // size是最后一个字符的下一个位置
    // cin输入多个字符串的时候是空格或者换行来间隔的
    // 输入的这一行里面本身就有空格,cin就会认为这个空格是多个值之间的分割
    // 比如hello nowcoder,cin里面就只有hello,nowcoder在缓冲区

    if(pos != string::npos)
    {
        cout<<str.size()-pos-1<<endl;
    }
    // 如果找不到空格,那长度就是size
    else
    {
        cout<<str.size()<<endl;
    }

    return 0;
}

541. 反转字符串 II

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

  • 我们以 2k为一个处理单位,每次对前 k个字符进行反转。具体操作就是每次从第i个字符开始,找到前 k个字符的位置,然后反转这部分字符串。
  • 然后跳过下一个k个字符,继续处理下一个2k段。

下面是几个例子:

 

代码:C++

class Solution {
public:
    string reverseStr(string s, int k) 
    {
        int n = s.size();
        // 每次都是2k个2k个进行处理,所以+=2k
        for(int i=0; i<n; i += 2*k)
        {
            // reverse(s.begin() + i, s.begin() + min(i+k,n));
            // 每隔2k个字符的前k个字符进行反转
            // 剩余字符小于2k个但大于等于k个,则反转前k个字符
            if(i + k <= s.size())
            {
                reverse(s.begin() + i, s.begin() + i + k);
                continue;
            }
            // 剩余字符少于k个,则将剩余字符串全部反转
            reverse(s.begin() + i, s.begin() + s.size());
        }
        return s;
    }
};

557. 反转字符串中的单词 III

557. 反转字符串中的单词 III - 力扣(LeetCode)

解法一:双指针

使用一个 while 循环遍历整个字符串,直到 left 超过字符串长度。
在内部,使用另一个 while 循环找到当前单词的右边界,即找到下一个空格或者字符串的结尾 

  • 遍历字符串

    • 使用两个指针 leftright 来标记每个单词的起始和结束位置。
    • 从头到尾扫描字符串,当遇到空格或字符串末尾时,确定当前单词的范围。
  • 反转每个单词

    • 每找到一个完整的单词时(即从 leftright 之间的字符),使用 C++ STL 的 reverse 函数对该部分字符进行反转。
  • 跳过空格

    • 反转完成后,将 left 更新到下一个单词的起始位置,即跳过当前的空格。
  • 处理边界条件

    • 当遍历到字符串末尾时停止,保证最后一个单词能正确处理,不遗漏任何字符。

代码:C++

class Solution {
public:
    string reverseWords(string s) {
        int left = 0;
        int n = s.size();
        while(left < n)
        {
            // 找到单词右边界
            int right = left;
            while(right < n && s[right] != ' ')
            {
                right++;
            }
            // 反转
            reverse(s.begin() + left, s.begin() + right);

            // 移动left到下一个单词的开头
            left = right + 1;
        }
        return s;

    }
};

125. 验证回文串

125. 验证回文串 - 力扣(LeetCode)

解法一:双指针

  • 忽略非字母数字字符

    • 只需要关心字符串中的字母和数字字符,其余的字符(如标点符号、空格等)可以忽略。因此,需要一个辅助函数 isLetterOrNumber() 来判断当前字符是否是字母或数字。
  • 忽略大小写

    • 不区分大小写的方式是将所有大写字母转换为小写字母。可以通过 ASCII 码的转换来实现(大写字母的 ASCII 值比小写字母小 32)。
  • 双指针法

    • 可以用两个指针,一个从字符串的头部(begin)开始,另一个从尾部(end)开始,向中间移动,逐个字符进行比较。
    • 每次循环中:
      • 如果 begin 指针指向的字符不是字母或数字,则跳过该字符,继续向右移动。
      • 如果 end 指针指向的字符不是字母或数字,则跳过该字符,继续向左移动。
      • 如果 beginend 指针指向的字符都合法,比较它们是否相同。如果不相同,则返回 false,表示字符串不是回文。
      • 如果字符相同,则继续移动指针,直到 begin >= end,表示所有字符都匹配,则字符串是回文。
  • 结束条件

    • beginend 指针相遇或交错时,意味着所有字符已经比较完毕,如果没有发现不相同的字符,则可以判定字符串是回文。

代码:C++

class Solution {
public:
    // 判断是不是字母和数字
    bool isLetterOrNumber(char ch)
    {
        return (ch >= '0' && ch <= '9')
        || (ch >= 'a' && ch <= 'z');
    }
    bool isPalindrome(string s) {

        // 加了引用,所以可以把大写字符转小写
        for(auto& ch : s)
        {
            if(ch >= 'A' && ch <= 'Z')
            {
                ch += 32; // ASCII中,大写字母+32就是对应的小写字母
            }
        }

        int begin = 0, end = s.size()-1;
        while(begin < end)
        {
            while(begin < end && !isLetterOrNumber(s[begin])) // 如果是字母数字就停下来
            {
                // 如果不是字母数字就跳过
                ++begin;
            }
            while(begin < end && !isLetterOrNumber(s[end])) // 如果是字母数字就停下来
            {
                // 如果不是字母数字就跳过
                --end;
            }
            if(s[begin] == s[end])
            {
                // 相等就继续比较
                ++begin;
                --end;
            }
            else
            {
                return false;
            }
        }
        return true;
    }
    
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值