目录
1、344. 反转字符串
2、2000. 反转单词前缀
3、345. 反转字符串中的元音字母
4、剑指 Offer 58 - I. 翻转单词顺序
5、151. 颠倒字符串中的单词
6、557. 反转字符串中的单词 III
7、541. 反转字符串 II
8、917. 仅仅反转字母
9、7. 整数反转
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组
s
的形式给出。不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
示例:
输入:s = ["h","e","l","l","o"] 输出:["o","l","l","e","h"]提示:
1 <= s.length <= 105
s[i]
都是 ASCII 码表中的可打印字符
思路:双指针,直接交换
void reverseString(char* s, int sSize){
int l = 0;
int r = sSize - 1;
while(l < r){
char t = s[l];
s[l] = s[r];
s[r] = t;
l++;
r--;
}
}
给你一个下标从 0 开始的字符串
word
和一个字符ch
。找出ch
第一次出现的下标i
,反转word
中从下标0
开始、直到下标i
结束(含下标i
)的那段字符。如果word
中不存在字符ch
,则无需进行任何操作。
- 例如,如果
word = "abcdefd"
且ch = "d"
,那么你应该 反转 从下标 0 开始、直到下标3
结束(含下标3
)。结果字符串将会是"dcbaefd"
。返回 结果字符串 。
示例:
输入:word = "abcdefd", ch = "d" 输出:"dcbaefd" 解释:"d" 第一次出现在下标 3 。 反转从下标 0 到下标 3(含下标 3)的这段字符,结果字符串是 "dcbaefd" 。提示:
1 <= word.length <= 250
word
由小写英文字母组成ch
是一个小写英文字母
思路:找到目标字符的下标,然后再双指针交换
char * reversePrefix(char * word, char ch){
int len = strlen(word);
int flag = 0;
// 找到下标
for(int i = 0; i < len; i++){
if(ch == word[i]){
flag = i;
break;
}
}
// 双指针交换
int l = 0;
while(l < flag){
char t = word[l];
word[l] = word[flag];
word[flag] = t;
l ++;
flag --;
}
return word;
}
给你一个字符串
s
,仅反转字符串中的所有元音字母,并返回结果字符串。元音字母包括
'a'
、'e'
、'i'
、'o'
、'u'
,且可能以大小写两种形式出现。示例:
输入:s = "hello" 输出:"holle"提示:
1 <= s.length <= 3 * 105
s
由 可打印的 ASCII 字符组成
思路:利用前后双指针,当两个指针都指向元音字母时进行交换。
bool isset(char a){
char s[] = {'a', 'e', 'i', 'o', 'u','A','E','I','O','U'};
for(int i = 0; i < 10; i++)
if(a == s[i])
return true;
return false;
}
char * reverseVowels(char * s){
int l = 0;
int r = strlen(s) - 1;
while(l < r){
bool ok1 = isset(s[l]);
bool ok2 = isset(s[r]);
if(ok1 && ok2){
s[l] ^= s[r];
s[r] ^= s[l];
s[l] ^= s[r];
l ++;
r --;
}
else if(ok1)
r --;
else if(ok2)
l ++;
else{
l ++;
r --;
}
}
return s;
}
输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. ",则输出"student. a am I"。
示例:
输入: "the sky is blue" 输出: "blue is sky the"说明:
- 无空格字符构成一个单词。
- 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
- 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
思路:以空格为单词间的分隔。
char* reverseWords(char* s){
int len = strlen(s);
// 处理空字符串
if(len == 0)
return s;
char* ans = (char*)malloc(sizeof(char) * (len + 1));
int top = 0;
int L = 0; // 左边界
// 处理空白字符串
while(s[L] == ' ')
L++;
if(L >= len)
return "";
int l = len - 1;
int r = len - 1;
while(l >= L){
while(r >= 0 && s[r] == ' ')
r--;
l = r;
while(l >= 0 && s[l] != ' ')
l--;
if(l < 0)
l = -1;
for(int i = l + 1; i <= r; i++)
ans[top++] = s[i];
ans[top++] = ' ';
r = l;
}
ans[--top] = '\0';
return ans;
}
给你一个字符串
s
,颠倒字符串中 单词 的顺序。单词 是由非空格字符组成的字符串。
s
中使用至少一个空格将字符串中的 单词 分隔开。返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串
s
中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。示例:
输入:s = "the sky is blue" 输出:"blue is sky the"提示:
1 <= s.length <= 104
s
包含英文大小写字母、数字和空格' '
s
中 至少存在一个 单词
思路:先去除空格,再从后往前遍历保存每个单词。
char * reverseWords(char * s){
// 去除首空格
while(*s == ' ')
s++;
int len = strlen(s);
char* ans = (char*)malloc(sizeof(char) * (len+1));
int top = 0;
int i = len - 1;
while(i >= 0){
while(i >= 0 && s[i] == ' ')
i--;
int j = i;
while(i >= 0 && s[i] != ' ')
i--;
for(int k = i + 1; k <= j; k++)
ans[top++] = s[k];
if(i >= 0)
ans[top++] = ' ';
}
ans[top] = '\0';
return ans;
}
给定一个字符串
s
,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。示例:
输入:s = "Let's take LeetCode contest" 输出:"s'teL ekat edoCteeL tsetnoc"提示:
1 <= s.length <= 5 * 104
s
包含可打印的 ASCII 字符。s
不包含任何开头或结尾空格。s
里 至少 有一个词。s
中的所有单词都用一个空格隔开。
思路:快慢双指针,从前往后遍历,碰到空格就反转。
void reverse(char* s, int l, int r){
r--; // 当前r位置是空格,所以减一
while(l < r){
char t = s[l];
s[l] = s[r];
s[r] = t;
l++;
r--;
}
}
char * reverseWords(char * s){
int len = strlen(s);
int l = 0;
int r = 0;
while(r < len){
while(s[r] != ' ' && r < len)
r++;
reverse(s, l, r);
l = ++r;
}
return s;
}
给定一个字符串
s
和一个整数k
,从字符串开头算起,每计数至2k
个字符,就反转这2k
字符中的前k
个字符。
- 如果剩余字符少于
k
个,则将剩余字符全部反转。- 如果剩余字符小于
2k
但大于或等于k
个,则反转前k
个字符,其余字符保持原样。示例:
输入:s = "abcdefg", k = 2 输出:"bacdfeg"提示:
1 <= s.length <= 104
s
仅由小写英文组成1 <= k <= 104
思路:计数,记下前后坐标,进行交换
void swap(char* s, int l, int r){
while(l < r){
char t = s[l];
s[l] = s[r];
s[r] = t;
l++, r--;
}
}
char * reverseStr(char * s, int k){
int len = strlen(s);
if(k == 1 || len == 1)
return s;
if(len < k){
swap(s, 0, len - 1);
return s;
}
int cnt = 0;
int L = 0;
for(int i = 0; i < len; i++){
cnt++;
if(cnt == 2 * k){
swap(s, L, L + k - 1);
cnt = 0;
L = i + 1;
}
}
if(cnt < k){
swap(s, L, len - 1);
}
else if(cnt < 2 * k && cnt >= k){
swap(s, L, L + k - 1);
}
return s;
}
给你一个字符串
s
,根据下述规则反转字符串:
- 所有非英文字母保留在原有位置。
- 所有英文字母(小写或大写)位置反转。
返回反转后的
s
。示例:
输入:s = "ab-cd" 输出:"dc-ba"提示:
1 <= s.length <= 100
s
仅由 ASCII 值在范围[33, 122]
的字符组成s
不含'\"'
或'\\'
思路:双指针,先判断是不是字母,如果都是字母就交换
bool check(char ch){
if((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
return true;
return false;
}
char * reverseOnlyLetters(char * s){
int len = strlen(s);
int l = 0;
int r = len - 1;
while(l < r){
bool ok1 = check(s[l]);
bool ok2 = check(s[r]);
if(ok1 && ok2){
char ch = s[l];
s[l] = s[r];
s[r] = ch;
l++;
r--;
}
else if(ok1){
r--;
}
else{
l++;
}
}
return s;
}
给你一个 32 位的有符号整数
x
,返回将x
中的数字部分反转后的结果。如果反转后整数超过 32 位的有符号整数的范围
[−231, 231 − 1]
,就返回 0。假设环境不允许存储 64 位整数(有符号或无符号)。
示例:
输入:x = 123 输出:321
思路:倒着乘再加。
int reverse(int x){
if(x <= INT_MIN || x >= INT_MAX) return 0;
long long ans = 0;
long long t = x;
while(t){
if(ans * 10 > INT_MAX || ans * 10 < INT_MIN) return 0;
ans = ans * 10 + t % 10;
t /= 10;
}
return ans;
}
文首图片素材取自博客:《算法零基础100讲》(第25讲) 字符串算法(五) - 字符串反转_英雄哪里出来的博客-CSDN博客