题目要求:编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。
双指针法,两边的指针同时向中间移动,交换双指针指向的元素。
C++:
class Solution {
public:
void swapchar(char& a, char& b){
char tmp = a;
a = b;
b = tmp;
}
void reverseString(vector& s) {
for (int left = 0, right = s.size()-1; left < s.size()/2; left++, right--){
swapchar(s[left],s[right]);
}
}
};
Python:
class Solution(object):
def reverseString(self, s):
"""
:type s: List[str]
:rtype: None Do not return anything, modify s in-place instead.
"""
# 使用了一个堆栈来反转一个字符串或字符列表
stack = []
for char in s:
stack.append(char)
for i in range(len(s)):
# (.pop() 方法会返回并删除列表末尾的元素)
s[i] = stack.pop()
题目要求:给定一个字符串 s 和一个整数 k,从字符串开头算起, 每计数至 2k 个字符,就反转这 2k 个字符中的前 k 个字符。如果剩余字符少于 k 个,则将剩余字符全部反转。如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
遍历时只需要让i每次前进2*k步,判断是否有需要反转的空间即可。
C++:
class Solution {
public:
void reverse(string& s, int start, int end){
for (int i = start, j = end; i < j; i++, j--){
swap(s[i], s[j]);
}
}
string reverseStr(string s, int k) {
for (int i = 0; i < s.size(); i += (2 * k)){
if (i + k <= s.size()){
reverse(s, i, i + k - 1);
continue;
}
reverse(s, i, s.size() - 1);
}
return s;
}
};
Python:
class Solution(object):
def reverseStr(self, s, k):
"""
:type s: str
:type k: int
:rtype: str
"""
def reverse_substring(text):
left, right = 0, len(text) - 1
while left < right:
text[left], text[right] = text[right], text[left]
left += 1
right -= 1
return text
res = list(s)
for cur in range(0, len(s), 2*k):
# 如果cur+k超过res长度则会返回至字符串最后一个值。
res[cur: cur+k] = reverse_substring(res[cur: cur+k])
return ''.join(res)
题目要求:把给定字符串中的'.',替换成空格 。
C++:
class Solution {
public:
string pathEncryption(string path) {
for (int i = path.size() - 1; i >= 0; i--){
if (path[i] == '.'){
path[i] = ' ';
}
}
return path;
}
};
Python:
class Solution(object):
def pathEncryption(self, path):
"""
:type path: str
:rtype: str
"""
return path.replace('.', ' ')
题目要求:给定一个字符串,逐个翻转字符串中的每个单词。
不要使用辅助空间,空间复杂度要求为O(1)。
思路:
举个例子,源字符串为:"the sky is blue "
C++:
class Solution {
public:
void reverse(string& s, int start, int end){
for (int i = start, j = end; i < j; i++, j--){
swap(s[i], s[j]);
}
}
void removeExtraSpaces(string& s){
int slow = 0;
for (int i = 0; i < s.size(); i++){
if (s[i] != ' '){
if (slow!=0) s[slow++] = ' '; // 给单次之间加上空格
while (i < s.size() && s[i] != ' '){
// 不上单次,遇到空格说明单次结束
s[slow++] = s[i++];
}
}
}
s.resize(slow);
}
string reverseWords(string s) {
removeExtraSpaces(s);
reverse(s, 0, s.size() - 1);
int start = 0;
for (int i = 0; i <= s.size(); ++i){
// 翻转遇到的单词(此处的单次已经前后颠倒)
if (i == s.size() || s[i] == ' '){
// 如果到达结尾或遇到空格就翻转
reverse(s, start, i - 1);
start = i + 1;
}
}
return s;
}
};
Python:
class Solution(object):
def reverseWords(self, s):
"""
:type s: str
:rtype: str
"""
# 删除空格
s = s.strip()
# 反转整个字符串
s = s[::-1]
# 将字符串拆分成单词,并反转每个单词
return ' '.join(word[::-1] for word in s.split())
题目要求:字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
不能申请额外空间,只能在本串上操作。
可以通过局部反转+整体反转,达到左旋转的目的。
具体步骤为:
最后就可以达到左旋n的目的,而不用定义新的字符串,完全在本串上操作。
例如 :示例1中 输入:字符串abcdefg,n=2
C++:
class Solution {
public:
void reverse(string& s, int start, int end){
for (int i = start, j = end; i < j; i++, j--){
swap(s[i], s[j]);
}
}
string dynamicPassword(string password, int target) {
reverse(password, 0, target-1);
reverse(password, target, password.size()-1);
reverse(password, 0, password.size()-1);
return password;
}
};
Python(使用切片):
class Solution(object):
def dynamicPassword(self, password, target):
"""
:type password: str
:type target: int
:rtype: str
"""
return password[target:] + password[:target]
学会双指针,局部反转+全局反转的方法。局部反转+局部反转+全局反转可以完成字符串旋转的操作。这种操作可以不申请额外的空间,在O(n)的时间复杂度和O(1)的空间复杂度下可以完成字符串旋转操作。