从C语言到C++_12(string相关OJ题)(leetcode力扣)

news/2025/2/7 13:05:24/

 上一篇已经讲了string类的接口函数,然后根据查文档刷了牛客和力扣58最后一个单词的长度,

还有力扣415字符串相加,这篇继续跟着查文档来刷力扣题,体会C++刷题的方便。

目录

917. 仅仅反转字母 - 力扣(LeetCode)

代码解析:

387. 字符串中的第一个唯一字符 - 力扣(LeetCode)

解析代码:

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

代码解析:

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

解析代码:

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

解析代码:

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

解析代码:

43. 字符串相乘 - 力扣(LeetCode)

解析代码:

本章完。


917. 仅仅反转字母 - 力扣(LeetCode)

难度简单

给你一个字符串 s ,根据下述规则反转字符串:

  • 所有非英文字母保留在原有位置。

  • 所有英文字母(小写或大写)位置反转。

返回反转后的 s 。

示例 1:

输入:s = "ab-cd"
输出:"dc-ba"

示例 2:

输入:s = "a-bC-dEf-ghIj"
输出:"j-Ih-gfE-dCba"

示例 3:

输入:s = "Test1ng-Leet=code-Q!"
输出:"Qedo1ct-eeLg=ntse-T!"

提示

  • 1 <= s.length <= 100

  • s 仅由 ASCII 值在范围 [33, 122] 的字符组成

  • s 不含 '\"' 或 '\\'

class Solution {
public:string reverseOnlyLetters(string s) {}
};

代码解析:

这道题和快排的思路很类似,swap不知道有没有讲过在algorithm这个头文件里有,和我们在函数模板实现的差不多,这种常用的肯定能想起来了,像判断是不是字母等函数,想不起来可以自己写,想起来不清楚可以查文档:

class Solution {
public:string reverseOnlyLetters(string s) {int left  = 0,right = s.size() - 1;while(left < right){while(left < right && !isalpha(s[left]))// 找字母,注意越界{++left;}while(left < right && !isalpha(s[right])){--right;}swap(s[left++],s[right--]);// 交换后往中间走,传引用,}return s;}
};

387. 字符串中的第一个唯一字符 - 力扣(LeetCode)

难度简单

给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1 。

示例 1:

输入: s = "leetcode"
输出: 0
示例 2:

输入: s = "loveleetcode"
输出: 2
示例 3:

输入: s = "aabb"
输出: -1

提示:

1 <= s.length <= 10^5
s 只包含小写字母

class Solution {
public:int firstUniqChar(string s) {}
};

解析代码:

可以暴力查找,是O(N^2),只有小写字母,可以用计数排序的思想:

class Solution {
public:int firstUniqChar(string s) {int countArr[26] = { 0 };for (auto e : s){countArr[e-'a']++;//相对映射到数组里++}for (int i = 0;i < s.size(); i++){if (countArr[(s[i]-'a')] == 1)//从原字符串遍历字符的相对映射{return i;//第一个相对映射为1的就返回其下标}}return -1;//没有出现一次的,输出-1}
};

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

难度简单

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

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

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

示例 1:

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

示例 2:

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

示例 3:

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

提示:

  • 1 <= s.length <= 2 * 10^5

  • s 仅由可打印的 ASCII 字符组成

class Solution {
public:bool isPalindrome(string s) {}
};

代码解析:

 此题和快排思路类似,从两边找字符,判断是否相等,这题可能刚看会有其它思路,但把全部大写字母转成小写字母,或者反过来都是很方便的,动手动手:

 

class Solution {
public:bool isPalindrome(string s) {for(auto& e : s){e = tolower(e);// 如果是大写就转小写,不是大写就不处理}int left = 0,right = s.size() - 1;while(left < right )//找字母数字字符后比较{while(left < right && !isalpha(s[left]) && !isdigit(s[left])){left++;}while(left < right && !isalpha(s[right]) && !isdigit(s[right])){right--;}if(s[left] != s[right]){return false;}else{left++;right--;}}return true;}
};

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"]

提示:

  • 1 <= s.length <= 10^5

  • s[i] 都是 ASCII 码表中的可打印字符

class Solution {
public:void reverseString(vector<char>& s) {}
};

解析代码:

可以说我们以前都实现过了,就是这里变成了vector,

这里的vector就是一个存char类型的数组,我们收尾交换,进行翻转:

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

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

难度简单

给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,

就反转这 2k 字符中的前 k 个字符。

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

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

示例 1:

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

示例 2:

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

提示:

  • 1 <= s.length <= 10^4

  • s 仅由小写英文组成

  • 1 <= k <= 10^4

class Solution {
public:string reverseStr(string s, int k) {}
};

解析代码:

题目确实有点难懂,人话:每隔k个反转k个,末尾不够k个时全部反转。

一顿试错后的代码:

class Solution {
public:void reverseString(string& s,int left,int right) {while(left < right){swap(s[left++],s[right--]);}}string reverseStr(string s, int k) {for(size_t i = 0; i < s.size(); i += 2*k){if(i + k > s.size()){reverseString(s,i,s.size() - 1);}else{reverseString(s,i,i + k - 1);}}return s;}
};

还可以用官方库里面的左闭右开(上面实现的是左闭右闭)的reverse函数:

class Solution {
public:void reverseString(string& s,int left,int right) {while(left < right){swap(s[left++],s[right--]);}}string reverseStr(string s, int k) {for(size_t i = 0; i < s.size(); i += 2*k){if(i + k > s.size()){//reverseString(s,i,s.size() - 1);reverse(&s[i],&s[s.size()]);}else{//reverseString(s,i,i + k - 1);reverse(&s[i],&s[i + k]);}}return s;}
};

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

难度简单

给定一个字符串 s ,你需要反转字符串中每个单词的字符顺序,

同时仍保留空格和单词的初始顺序。

示例 1:

输入:s = "Let's take LeetCode contest"
输出:"s'teL ekat edoCteeL tsetnoc"

示例 2:

输入: s = "God Ding"
输出:"doG gniD"

提示:

  • 1 <= s.length <= 5 * 10^4

  • s 包含可打印的 ASCII 字符。

  • s 不包含任何开头或结尾空格。

  • s 里 至少 有一个词。

  • s 中的所有单词都用一个空格隔开。

class Solution {
public:string reverseWords(string s) {}
};

解析代码:

(类似双指针的思想:)

class Solution {
public:string reverseWords(string s) {size_t left = 0,right = 0;while(left < s.size()){while(right < s.size() && s[right] != ' ')// 找空格/结尾,要先判断结尾,防止越界访问{++right;}reverse(&s[left],&s[right]);// 注意是左闭右开(反正我是服了)++right;//跳过空格,进行下一次判断left = right;}return s;}
};

43. 字符串相乘 - 力扣(LeetCode)

难度中等

给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,

它们的乘积也表示为字符串形式。

注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。

示例 1:

输入: num1 = "2", num2 = "3"
输出: "6"

示例 2:

输入: num1 = "123", num2 = "456"
输出: "56088"

提示:

  • 1 <= num1.length, num2.length <= 200

  • num1 和 num2 只能由数字组成。

  • num1 和 num2 都不包含任何前导零,除了数字0本身。

class Solution {
public:string multiply(string num1, string num2) {}
};

解析代码:

这题有点难就看题解了,这里用方法二:

class Solution {
public:string multiply(string num1, string num2) {int n = num1.size(), m = num2.size();vector<int> v(n + m, 0);//开n+m个0for (int i = 0; i < n; ++i){for (int j = 0; j < m; ++j){int a = num1[n - i - 1] - '0';int b = num2[m - j - 1] - '0';v[i + j] += a * b;}}for (int i = 0, carry = 0; i < v.size();++i)//carry进位{v[i] += carry;carry = v[i] / 10;v[i] %= 10;}string ret;for (int i = v.size() - 1;i >= 0;--i){if (ret.empty() && v[i] == 0)//如果ret是空的,并且v[i] == 0,就是前导0的情况{continue;}ret += (v[i] + '0');}return ret.empty() ? "0" : ret;//如果是空串就返回0,也可以在开头判断}
};

本章完。

下一篇:模拟实现string,深拷贝浅拷贝,拷贝构造和赋值重载的传统写法和现代写法。


http://www.ppmy.cn/news/77284.html

相关文章

想学渗透,如何入门?

首先 渗透是计算机技术应用的一种&#xff0c;脱离不了基础&#xff0c;您需要学会一门编程语言&#xff0c;任何与计算机相关的都是从学习编程语言开始的&#xff0c;让你对计算机有个初步的认识&#xff0c;将您认识的数字转化为用0和1表示的编码。这个阶段推荐学习Python&a…

【CocosCreator问题总结】MotionStreak效果显示异常

&#x1f4e2;博客主页&#xff1a;肩匣与橘&#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;本文由肩匣与橘编写&#xff0c;首发于CSDN&#x1f649;&#x1f4e2;生活依旧是美好而又温柔的&#xff0c;你也是✨ …

环信新鲜出炉的 React-UIKIT 库初体验,瞬间实现即时通讯功能!

一、前言 为了加快即时通讯需求产品开发速度&#xff0c;将更多的时间放在关系核心业务逻辑的处理上&#xff0c;环信正式推出可扩展&#xff0c;易使用的 React 版本的 UIKIT 库 此 UIKit 库 是基于 环信 Web SDK 开发的的 UI 组件库&#xff0c;它提供了常用的 UI 组件、包含…

jquery

目录 1. 概念 2. JQuery对象和JS对象 2.1 区别 2.2 转换 3. 选择器 3.1 基础操作 3.2 分类 4. DOM操作 4.1 内容操作 4.2 属性操作 4.3 CRUD操作 5. 动画 5.1 默认显示和隐藏方式 5.2 滑动显示和隐藏方式 5.3 淡入淡出显示和隐藏方式 6. 遍历 6.1 js的遍历方式 6…

测试2年,26岁大龄程序员面试13家公司,拿下25K,差点被面试官KO了···

前言 我大概面试了13家公司&#xff0c;简历包装的是两年半测试经验&#xff0c;因为我的年纪已经是26岁&#xff0c;所以必须进行包装&#xff0c;这也并不是我想欺骗别人&#xff0c;而是现在无论干什么工作都需要有工作经验的&#xff0c;就连找个销售都要有工作经验的&…

nodejs中获取时间戳、时间差

Nodejs中获取时间戳的方法有很多种&#xff0c;例如&#xff1a;new Date().getTime()Date.now()process.uptime()process.hrtime() 平时想获取一个时间戳的话&#xff0c;用这些方法都可以,那么这些方法有什么区别呢&#xff1f; new Date().getTime()和Date.now() 这些方法…

华为云网站备案操作流程

目录 一、官方指引二、操作步骤1.操作场景2.前提条件3.操作步骤&#xff08;1&#xff09;下载华为云 APP&#xff08;2&#xff09;登录华为云 APP&#xff0c;在 “控制台” 中单击 “网站备案”&#xff0c;进入 APP 备案操作入口&#xff08;3&#xff09;验证备案类型&…

2022级云曦实验室考试(一)pwn

讲真&#xff0c;俺都不知道pwn是啥&#xff0c;等俺搜搜&#xff01; pwn简介&#xff1a; CTF中的pwn指的是通过通过程序本身的漏洞&#xff0c;编写利用脚本破解程序拿到主机的权限&#xff0c;这就需要对程序进行分析&#xff0c;了解操作系统的特性和相关漏洞&#xff0…