344. 反转字符串 - 力扣(LeetCode)
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s
的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
示例 1:
输入:s = ["h","e","l","l","o"] 输出:["o","l","l","e","h"]
思路:直接两端元素依次交换就行,因为不能开辟新的空间。
解决:左右指针依次向中间移动,直到两个指针相遇。
代码:
class Solution {
public:
void reverseString(vector& s) {
int left=0;
int right=s.size()-1;
while(left<=right){
swap(s[left],s[right]);
++left;
--right;
}
}
};
541. 反转字符串 II - 力扣(LeetCode)
给定一个字符串 s
和一个整数 k
,从字符串开头算起,每计数至 2k
个字符,就反转这 2k
字符中的前 k
个字符。
k
个,则将剩余字符全部反转。2k
但大于或等于 k
个,则反转前 k
个字符,其余字符保持原样。示例 1:
输入:s = "abcdefg", k = 2 输出:"bacdfeg"
思路:这题只要按照题目给出的反转方式去写代码就可以。
解决:首先反转前k个元素,在比较2k之后剩余的元素个数,小于k剩下全部反转,小于2k但大于或等于k,依然反转前k个元素。这里要用到c++中库函数reverse,注意反转的起点和终点。这里有一个地方需要思考一下,如果剩余字符大于2k,应该继续反转步骤,从2k开始计数,因此循环每次增加的数应该是2k,并且要小于字符大小。
注意:以下两种情况都是反转前k个数,①2k里面前k个数反转;②剩余的数小于 2k
但大于或等于 k
个,也是反转前k个数。可以写成一条语句。
代码:
class Solution {
public:
string reverseStr(string s, int k) {
for(int i=0;i
LCR 122. 路径加密 - 力扣(LeetCode)
假定一段路径记作字符串 path
,其中以 ".
" 作为分隔符。现需将路径加密,加密方法为将 path
中的分隔符替换为空格 "
",请返回加密后的字符串。
示例 1:
输入:path = "a.aef.qerf.bb" 输出:"a aef qerf bb"
思路:替换.变成空格就行。
解决:定义一个新字符串,记录替换好的字符。
代码:
class Solution {
public:
string pathEncryption(string path) {
string str;
for(int i = 0;i
151. 反转字符串中的单词 - 力扣(LeetCode)
给你一个字符串 s
,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s
中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串 s
中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
示例 1:
输入:s = "the sky is blue" 输出:"blue is sky the"
示例 2:
输入:s = " hello world " 输出:"world hello" 解释:反转后的字符串中不能存在前导空格和尾随空格。
这里要考虑两个问题:①去掉多余空格,保留单词之间一个空格;②如何反转单词。
思路①:可以用快慢指针,快指针指向字母就加入慢指针,如果快指针遇到空格,慢指针就自己补充一个空格,再让快指针移动,遇到字母再加入。
解决①:一个循环让快指针移动,如果s[fast]!=' ',就s[slow]=s[fast],再移动slow和fast,s[fast]=' '停止,除了slow等于0时候,每次s[fast]!=' '时,都要先补充空格(s[slow]=' '),slow再向右移动一格,作为下次填充单词的起点。
代码:
void a(string s){//去空格
int slow=0;
for(int fast=0;fast
思路②:去完空格之后,需要反转单词,但是单词内字母顺序又不反转;这种情况肯定不能一个一个单词去反转,可以先全部反转字符串,再局部反转回单词。
解决②:先反转字符串,两端指针向里缩进,依次交换就可以;再局部反转回单词,从第一个字母开始到空格前一个字母,就是要反转的单词,再移动起点继续反转单词。
代码:
int start=0;//每次单词反转起点
for(int end=0;end<=s.size();++end){
if(s[end]==' '||end==s.size()){//遇到空格或者字符串末尾说明可以进行当前单词的局部反转
b(s, start, end - 1);
start=end+1;//局部反转起点更新
}
}
return s;
完整代码:
class Solution {
public:
void a(string& s){//去空格
int slow=0;
for(int fast=0;fast
LCR 182. 动态口令 - 力扣(LeetCode)
某公司门禁密码使用动态口令技术。初始密码为字符串 password
,密码更新均遵循以下步骤:
target
password
前 target
个字符按原顺序移动至字符串末尾请返回更新后的密码字符串。
示例 1:
输入: password = "s3cur1tyC0d3", target = 4 输出: "r1tyC0d3s3cu"
示例 2:
输入: password = "lrloseumgh", target = 6 输出: "umghlrlose"
这里方法有很多种,练习一下反转字符串来解决
思路:可以通过局部反转+整体反转
解决:①反转区间为前n的子串;②反转区间为n到末尾的子串;③反转整个字符串
代码:(c++就是快啊)
class Solution {
public:
string dynamicPassword(string password, int target) {
reverse(password.begin(), password.begin() + target);
reverse(password.begin() + target, password.end());
reverse(password.begin(), password.end());
return password;
}
};
收获:局部反转和整体反转的顺序不同用于处理不同情况,同时复习了一下双指针151. 反转字符串中的单词 - 力扣(LeetCode)这个题值得反复思考。