C++小白修仙记_LeetCode刷题_字符串
字符串(难度:easy)
520. 检测大写字母
我们定义,在以下情况时,单词的大写用法是正确的:
全部字母都是大写,比如 "USA" 。
所有字母都不是大写,比如 "leetcode" 。
只有首字母大写, 比如 "Google" 。
给你一个字符串 word 。如果大写用法正确,返回 true ;否则,返回 false 。
示例:
输入:word = "USA"
输出:true
解法:
-
如果 count = 0,说明所有字母均为小写,符合要求。
-
如果 count == word.size(),说明所有字母均为大写,符合要求。
-
如果 count = 1 且 word[0] 是大写字母,说明 word 只有首字母大写,符合要求。
class Solution {
public:
bool detectCapitalUse(string word) {
int count = 0;
for (char str : word) {
if (str >= 'A' && str <= 'Z') {
count++;
}
}
if(count == 0){
return true;
}else if(count == word.size()){
return true;
}else if(count == 1 && (word[0] >= 'A' && word[0] <= 'Z')){
return true;
}
return false;
}
};
125. 验证回文串
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 。
示例:
输入: s = "A man, a plan, a canal: Panama"
输出:true
解释:"amanaplanacanalpanama" 是回文串。
解法:
- 如果 s[i] 既不是字母也不是数字,右移左指针,也就是把 i 加一。
- 如果 s[j] 既不是字母也不是数字,左移右指针,也就是把 j 减一。
- 否则,如果 s[i] 和 s[j] 转成小写后相等,那么把 i 加一,把 j 减1,继续判断。
- 否则,s 不是回文串,返回 false。
class Solution {
public:
bool isPalindrome(string s) {
int n = s.size();
int i = 0, j = n - 1;
while (i < j) {
if (!isalnum(s[i])) {
i++;
} else if (!isalnum(s[j])) {
j--;
} // 使用tolower/toupper函数进行字符大小写转换的方法
//tolower 大写变小写 ; toupper 小写变大写
else if (tolower(s[i]) == tolower(s[j])){
i++;
j--;
}
else {
return false;
}
}
return true;
}
};
14. 最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""。
示例:
输入:strs = ["flower","flow","flight"]
输出:"fl"
解法:
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
string res = strs[0];
int n = res.size();
for (int j = 0; j < n; j++) { // 遍历字符串
for (string& s : strs) { // 遍历字符串数组
if (j == s.size() || s[j] != res[j]) {
// j等于n时,代表此时有字母缺失或者不全一样
return res.substr(0,j);//返回0到j位置上的字符
}
}
}
return res;//否则返回strs[0]的全部字符
}
};
434. 字符串中的单词数
统计字符串中的单词个数,这里的单词指的是连续的不是空格的字符。
请注意,你可以假定字符串里不包括任何不可打印的字符。
示例:
输入: "Hello, my name is John"
输出: 5
解释: 这里的单词是指连续的不是空格的字符,所以 "Hello," 算作 1 个单词。
解法:
class Solution {
public:
int countSegments(string s) {
int n = s.size(), count = 0, i = 0;
while (i < n) {
if(s[i] != ' ' && i == 0){
//判断第一个字符不是空格的情况
count++;
}
if (i + 1 < n && s[i] == ' ' && s[i + 1] != ' ') {
//如果当前字符是空格,下一个字符不是空格并且 i+1没有超过数组下标的情况
count++;
}
i++;
}
return count;
}
};
58. 最后一个单词的长度
给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。
单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。
示例:
输入:s = "Hello World"
输出:5
解释:最后一个单词是“World”,长度为 5。
解法:
class Solution {
public:
int lengthOfLastWord(string s) {
int n = s.size() - 1;
int word_length = 0;
while(s[n] == ' '){//跳过末尾空格
n--;
}
while(n >= 0 && s[n] != ' '){//从末尾第一个字母开始遍历
word_length++;
n--;
}
return word_length;
}
};
344. 反转字符串
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
示例:
输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"]
解法:双指针
class Solution {
public:
void reverseString(vector<char>& s) {
int n = s.size() - 1;
for(int i = 0, j = n; i < j; i++, j--){
char temp = s[i];
s[i] = s[j];
s[j] = temp;
}
}
};
541. 反转字符串 II
给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
示例:
输入:s = "abcdefg", k = 2
输出:"bacdfeg"
解法:
class Solution {
public:
string reverseStr(string s, int k) {
int n = s.size();
for(int i = 0; i < n; i += 2 * k){
int left = i,right = min(i + k,n) - 1;//min(i + k,n):如果i+k大于n代表剩余字符不足以K,即全部反转,如果i+k小于n则代表剩余字符还多于K,仅反转前K个字符
while(left < right){
char temp = s[left];
s[left] = s[right];
s[right] = temp;
left++;
right--;
}
}
return s;
}
};
557. 反转字符串中的单词 III
给定一个字符串 s ,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
示例:
输入:s = "Let's take LeetCode contest"
输出:"s'teL ekat edoCteeL tsetnoc"
class Solution {
public:
string reverseWords(string s) {
int n = s.size();
if (n == 0) {
return s;
}
int left = 0, right = 0;
while (right < n) {
while (right < n && s[right] != ' ') {
right++;
}
int next = right-- + 1;////next是翻转完这个单词之后,left和right接下来要反转的单词的开始;right-- 代表第一个单词的末尾
while (left < right) {
char temp = s[left];
s[left] = s[right];
s[right] = temp;
left++;
right--;
}
left = next;
right = next;
}
return s;
}
};