344.反转字符串
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组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"]
class Solution:
def reverseString(self, s) -> None:
"""
Do not return anything, modify s in-place instead.
"""
left, right = 0, len(s)-1
while left < right:
s[left], s[right] = s[right], s[left]
left += 1
right -= 1
if __name__ == '__main__':
s = ["h", "e", "l", "l", "o"]
tmp = Solution()
res = tmp.reverseString(s)
print(s)
C++
class Solution {
public:
void reverseString(vector<char>& s) {
int start = 0;
int end = s.size()- 1;
while(start < end){
char t = s[start];
s[start] = s[end];
s[end] = t;
start++;
end--;
}
}
};
541.反转字符串II
给定一个字符串s和一个整数k,从字符串开头算起,每计数至2k个字符,就反转这2k字符中的前k个字符。 如果剩余字符少于k个,则将剩余字符全部反转。 如果剩余字符小于2k但大于或等于k个,则反转前k个字符,其余字符保持原样。
class Solution:
# 两个月之前的写法
def reverseStr(self, s: str, k: int) -> str:
long = len(s)
res = ""
for i in range(0, long, 2 * k):
if len(s[i:]) > 2 * k:
res += s[i:i+k][::-1] + s[i+k:i+2*k]
elif len(s[i:]) > k:
res += s[i:i+k][::-1] + s[i+k:]
else:
res += s[i:][::-1]
return res
# 今天的写法
def reverseStr2(self, s: str, k: int) -> str:
res = ""
while len(s) > 0:
if len(s) > 2 * k:
res += s[:k][::-1] + s[k:2*k]
s = s[2*k:]
elif len(s) > k:
res += s[:k][::-1] + s[k:]
s = []
else:
res += s[:k][::-1]
s = []
return res
# 参考卡哥视频的写法,是比我的要简洁
def reverseStr3(self, s: str, k: int) -> str:
count = len(s)
res = ""
for i in range(0,count,2*k):
if i + k <= count:
res += s[i:i+k][::-1] + s[i+k:i+2*k]
else:
res += s[i:][::-1]
return res
# 24年4月的写法,已经有点味道了
def reverseStr(self, s: str, k: int) -> str:
st = list(s)
for i in range(0, len(s), k * 2):
st[i:i+k] = reversed(st[i:i+k])
# while i < i + 2 * k - 1:
# st[i], st[i + k - 1] = st[i + k - 1], st[i]
# i += 1
res = "".join(st)
return res
if __name__ == '__main__':
s = "abcdefg"
# s = "abcd"
k = 2
temp = Solution()
res = temp.reverseStr3(s,k)
print(res)
C++
class Solution {
public:
string reverseStr(string s, int k) {
int count = s.size();
for(int i = 0; i < count;i+=2*k){
if(count - i > k){
reverse(s.begin()+i,s.begin()+i+k);
}
else{
reverse(s.begin()+i,s.end());
}
}
return s;
}
};
//没想到我之前还会用函数啊
class Solution {
public:
string reverseStr(string s, int k) {
int k2 = 2 * k;
int cnt = s.size();
string res = "";
for(int i = 0; i < cnt; i+=k2){
if(cnt - i > k){
int st = i;
int end = i+k-1;
while(st < end){
char a = s[st];
s[st] = s[end];
s[end] = a;
st++;
end--;
}
}
else{
int end = cnt-1;
while(i < end){
char a = s[i];
s[i] = s[end];
s[end] = a;
i++;
end--;
}
}
}
return s;
}
};
剑指Offer05.替换空格
请实现一个函数,把字符串s中的每个空格替换成"%20"。 示例1: 输入:s = "We are happy." 输出:"We%20are%20happy."
class Solution:
def replaceSpace(self, s: str) -> str:
addlen = s.count(' ')
list_s = list(s)
list_s.extend(' ' * addlen * 2)
s_len = len(s)-1
right = len(list_s)-1
while s_len:
if s[s_len] != ' ':
list_s[right] = s[s_len]
s_len -= 1
right -= 1
else:
list_s[right] = '0'
right -= 1
list_s[right] = '2'
right -= 1
list_s[right] = '%'
right -= 1
s_len -= 1
if s_len == 0 and s[0] == ' ':
list_s[right] = '0'
right -= 1
list_s[right] = '2'
right -= 1
list_s[right] = '%'
res = "".join(list_s)
return res
if __name__ == '__main__':
s = "We are happy."
s = " "
s = " 0 "
# ll = len(s)
# print(ll)
# addlen = s.count(' ')
# ls = list(s)
# ls.extend(' '*addlen*2)
# print(len(ls))
tmp = Solution()
res =tmp.replaceSpace(s)
print(res)
s = ""
print(len(s))
这里追加一下解释,如果按照python本来的思维,可以直接用replace函数,将空格替换成“%20”,但是感觉背离了本题的初衷 这里把字符串转换成列表,然后追加空间的写法,挺有意思 这里我看了一下随想录的python解法,可以把while条件设置为>=0,这样就可以照顾到首字符是空格的情况,不必在加一个if判断了,挺厉害的 追加一下24年4月的写法,这个就不是leetcode的写法,而是卡码网的54. 替换数字(第八期模拟笔试),先追加空格,然后再转成list的写法好像是要简洁一些。
s = input()
cnt = len(s)
add = 0
for i in s:
if not i.isalpha():
add += 1
add *= (len("number") - 1)
s += " " * add
new_cnt = len(s) - 1
s = list(s)
for i in range(cnt-1,-1,-1):
if s[i].isalpha():
s[new_cnt] = s[i]
new_cnt -= 1
else:
s[new_cnt-0] = "r"
s[new_cnt-1] = "e"
s[new_cnt-2] = "b"
s[new_cnt-3] = "m"
s[new_cnt-4] = "u"
s[new_cnt-5] = "n"
new_cnt -= 6
print("".join(s))
C++
class Solution {
public:
string replaceSpace(string s) {
string res;
for(char a:s){
if(a == ' '){
res += "%20";
}
else{
res += a;
}
}
return res;
}
};
class Solution {
public:
string replaceSpace(string s) {
int cnt = 0;
for(char a:s){
if(a == ' '){
cnt++;
}
}
int old = s.size() - 1;
for(int i = 0; i < cnt; i++){
s += " ";
}
cnt = s.size() - 1;
for(int i = old; i >= 0; i--){
if(s[i] != ' '){
s[cnt] = s[i];
cnt--;
}
else{
s[cnt--] = '0';
s[cnt--] = '2';
s[cnt--] = '%';
}
}
return s;
}
};
151.反转字符串中的单词
给你一个字符串s ,请你反转字符串中单词的顺序。 单词是由非空格字符组成的字符串。s中使用至少一个空格将字符串中的单词分隔开。 返回单词顺序颠倒且单词之间用单个空格连接的结果字符串。 注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。 示例1: 输入:s = "the sky is blue" 输出:"blue is sky the" 示例2: 输入:s = " hello world " 输出:"world hello" 解释:反转后的字符串中不能存在前导空格和尾随空格。 示例3: 输入:s = "a good example" 输出:"example good a" 解释:如果两个单词间有多余的空格,反转后的字符串需要将单词间的空格减少到仅有一个。
class Solution:
def reverseWords(self, s: str) -> str:
# 1.去除多余空格
s = s.strip()#[::-1].strip()[::-1]
list_s = list(s)
left = 0
while left < len(list_s):
if list_s[left] == " " and list_s[left+1] == " ":
list_s.pop(left+1)
continue
left += 1
# 2.反转字符串
left, right = 0, len(list_s)-1
while left < right:
list_s[left], list_s[right] = list_s[right], list_s[left]
left += 1
right -= 1
# 3.反转单词
list_s.append(" ")
left, right = 0, len(list_s) - 1
index = 0
while index < len(list_s):
if list_s[index] != " ":
index += 1
else:
right = index - 1
while left < right:
list_s[left], list_s[right] = list_s[right], list_s[left]
left += 1
right -= 1
left = index + 1
index += 1
res = "".join(list_s)
res = res[:-1]
return res
if __name__ == '__main__':
s = " hello world "
s = "the sky is blue"
s = "a good example"
tmp = Solution()
res = tmp.reverseWords(s)
print(res)
这里是只看了那三个步骤,没有看具体代码写出来的,执行用时非常高,感觉是最后第三步的时候处理的不是很便利,容我来看看答案
C++
class Solution {
public:
string reverseWords(string s) {
string tmp = "";
string ss = "";
int flag = 1;
//删除前面的空格
for(char a:s){
if(a == ' ' and flag == 1){
continue;
}
else{
ss += a;
flag = 0;
}
}
s = ss;
//删除中间后面的空格
for(int i = 0; i < s.size(); i++){
if(s[i] == ' ' && s[i-1] == ' '){
continue;
}
tmp += s[i];
}
//删除末尾最后一个空格
if(tmp[tmp.size()-1] == ' '){
tmp.erase(tmp.end()-1);
}
string res = "";
string tt = "";
for(char c:tmp){
if(c != ' '){
tt += c;
}
else{
res = ' ' + tt + res;
tt = "";
}
}
res = tt + res;
return res;
}
};
剑指Offer58-II.旋转字符串
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2, 该函数将返回左旋转两位得到的结果"cdefgab"。 示例1: 输入: s = "abcdefg", k = 2 输出: "cdefgab" 示例2: 输入: s = "lrloseumgh", k = 6 输出: "umghlrlose"
class Solution:
def reverseLeftWords(self, s: str, n: int) -> str:
ls = list(s)
a = ls[:n]
b = ls[n:]
res = ''.join(b) + ''.join(a)
return res
这里看了一下卡哥的视频解释,大晚上急着睡觉,还是大意了,直接调用方法还是不可取的
C++
可以通过局部反转+整体反转 达到左旋转的目的。
具体步骤为:
- 反转区间为前n的子串
- 反转区间为n到末尾的子串
- 反转整个字符串
class Solution {
public:
string reverseLeftWords(string s, int k) {
for(int i = 0; i < k; i++){
s += s[i];
}
string res = "";
for(int i = k; i < s.size(); i++){
res += s[i];
}
return res;
}
};
//卡哥的实现方法,很有意思
class Solution {
public:
string reverseLeftWords(string s, int n) {
reverse(s.begin(), s.begin() + n);
reverse(s.begin() + n, s.end());
reverse(s.begin(), s.end());
return s;
}
};