class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
left = 0
right = len(s) - 1
while left < right:
tmp = s[left]
s[left] = s[right]
s[right] = tmp
left += 1
right -= 1
1)python不可通过索引修改字符串string[index],需要先转为list,返回结果时再转回str。
2)注意区间开闭。这里用左闭右开,则相应的边界判断是left < len(s)、right <= len(s)...;更新left和right时也容易出错。
class Solution:
def reverseStr(self, s: str, k: int) -> str:
n = len(s)
slist = [c for c in s]
#[left, right)
left = 0
right = 2 * k
while right <= n:
slist = self.reverse(slist, left, left + k)
left = right
right += 2 * k
if left < n and left + k >= n:
slist = self.reverse(slist, left, n)
elif left + k < n:
slist = self.reverse(slist, left, left + k)
return "".join(c for c in slist)
def reverse(self, s, l: int, r: int):
i = l
j = r - 1
while i < j:
s[i], s[j] = s[j], s[i]
i += 1
j -= 1
return s
54. 替换数字(第八期模拟笔试) (kamacoder.com)
def change(s):
sl = [c for c in s] # s list
for i in range(len(sl)):
code = ord(sl[i]) - ord('a')
if code >= 0 and code < 26:
continue
sl[i] = "number"
return "".join(c for c in sl)
if __name__ == "__main__":
s = input()
res = change(s)
print(res)
1)直接的解法是用python的split()和strip()方法。
class Solution:
def reverseWords(self, s: str) -> str:
s = s.split()
l, r = 0, len(s) - 1
while l < r:
s[l], s[r] = s[r], s[l]
l += 1
r -= 1
res = ""
for w in s:
res += w + " "
return res.strip()
(又漏掉了 l += 1 和 r -= 1...
2)由于python的字符串不可变,不能在空间O(1)下解决此题。C++在空间O(1)限制下的解法:
2.1)用removeBlank处理头尾的空格和单词间多余的空格。使用快慢指针,fast遍历原字符串,slow指向新字符串的后一个位置,即新字符串是[0, slow),其长度==slow。遍历结束,新字符串末尾还有一个多余空格,记得将其移除。
2.2)可以用自己定义的reverse函数,也可以#include <algorithm>然后使用reverse(s.begin(), s.end())。注意后者是左闭右开的。
2.3)首先将整个字符串反转,接着用快慢指针找到每个单词的头和尾,将单词反转回来。因为最后一个单词右边没有空格,需要单独处理。
#include <iostream>
using namespace std;
class Solution {
public:
void removeBlank(string& s){
int slow = 0;
for (int fast = 0; fast < s.size(); fast++){
if (s[fast] != ' ') {
s[slow++] = s[fast];
}
if (s[fast] == ' ' && slow > 0) {
if (s[slow-1] != ' ') {
s[slow++] = ' ';
}
}
}
if (s[slow-1] == ' ') {
slow--;
}
s.resize(slow);
}
void reverse(string& s, int left, int right){
while (left < right) {
swap(s[left++], s[right--]);
}
}
string reverseWords(string s) {
removeBlank(s);
reverse(s, 0, s.size()-1);
int slow = 0;
int fast = 0;
while (fast < s.size()) {
if (s[fast] == ' ') {
reverse(s, slow, fast-1);
slow = fast + 1;
}
fast++;
}
reverse(s, slow, fast-1);
return s;
}
};
55. 右旋字符串(第八期模拟笔试) (kamacoder.com)
C++在空间O(1)限制下的解法:思路类似上题,先反转整个字符串,然后将两部分各自反转回来。
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int k;
string s;
cin >> k;
cin >> s;
reverse(s.begin(), s.end());
reverse(s.begin()+k, s.end());
reverse(s.begin(), s.begin()+k);
cout << s << endl;
}