目录
一、反转字符串 II
二、反转字符串中的单词 III
三、找出字符串中第一个只出现一次的字符
四、字符串相乘
五、把字符串转换成整数
一、反转字符串 II
给定一个字符串 s
和一个整数 k
,从字符串开头算起,每计数至 2k
个字符,就反转这 2k
字符中的前 k
个字符。
- 如果剩余字符少于
k
个,则将剩余字符全部反转。 - 如果剩余字符小于
2k
但大于或等于k
个,则反转前k
个字符,其余字符保持原样。
示例 1:
输入:s = "abcdefg", k = 2
输出:"bacdfeg"
示例 2:
输入:s = "abcd", k = 2
输出:"bacd"
提示:
1 <= s.length <= 10^4
s
仅由小写英文组成1 <= k <= 10^4
代码实现:
class Solution {
public:
string reverseStr(string s, int k) {
size_t pos = 0; // pos 为每次计数的起点
while (pos < s.size())
{
if (pos + k <= s.size()) // 剩余字符大于等于 k
reverse(s.begin() + pos, s.begin() + pos + k);
else // 剩余字符小于 k
reverse(s.begin() + pos, s.end());
pos += 2 * k;
}
return s;
}
};
二、反转字符串中的单词 III
给定一个字符串 s
,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
示例 1:
输入:s = "Let's take LeetCode contest"
输出:"s'teL ekat edoCteeL tsetnoc"
示例 2:
输入: s = "God Ding"
输出:"doG gniD"
提示:
1 <= s.length <= 5 * 10^4
s
包含可打印的 ASCII 字符。s
不包含任何开头或结尾空格。s
里 至少 有一个词。s
中的所有单词都用一个空格隔开。
代码实现:
class Solution {
public:
string reverseWords(string s) {
size_t pos = 0; // pos 为每个待反转的单词的起点
size_t found = s.find(' ', pos); // found 为每个待反转的单词的终点的下一个位置
while (found != string::npos)
{
reverse(s.begin() + pos, s.begin() + found);
pos = found + 1;
found = s.find(' ', pos);
}
reverse(s.begin() + pos, s.end()); // 反转最后一个单词
return s;
}
};
三、找出字符串中第一个只出现一次的字符
描述:
找出字符串中第一个只出现一次的字符
数据范围:
输入的字符串长度满足 1≤ n ≤1000
输入描述:
输入一个非空字符串
输出描述:
输出第一个只出现一次的字符,如果不存在输出 -1
示例 1:
输入:asdfasdfo
输出:o
代码实现:
#include <iostream>
using namespace std;
int main()
{
string s;
cin >> s;
// 统计 s 中的每个字符出现的次数
int count[256] = { 0 };
for (size_t i = 0; i < s.size(); ++i)
{
count[s[i]] += 1;
}
// 找出字符串中第一个只出现一次的字符
bool flag = false; // 假设字符串中不存在只出现一次的字符
for (size_t i = 0; i < s.size(); ++i)
{
if (count[s[i]] == 1)
{
flag = true;
cout << s[i] << endl;
break;
}
}
if (flag == false)
cout << -1 <<endl;
return 0;
}
四、字符串相乘
给定两个以字符串形式表示的非负整数 num1
和 num2
,返回 num1
和 num2
的乘积,它们的乘积也表示为字符串形式。
注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。
示例 1:
输入: num1 = "2", num2 = "3"
输出: "6"
示例 2:
输入: num1 = "123", num2 = "456"
输出: "56088"
提示:
1 <= num1.length, num2.length <= 200
num1
和num2
只能由数字组成。num1
和num2
都不包含任何前导零,除了数字0本身。
代码实现:
class Solution {
public:
// 字符串相加
string add(string num1, string num2) {
string ans;
int end1 = num1.size() - 1, end2 = num2.size() - 1;
size_t carry = 0; // 进位
while (end1 >= 0 || end2 >= 0 || carry > 0)
{
size_t val1 = end1 >= 0 ? (num1[end1--] - '0') : 0;
size_t val2 = end2 >= 0 ? (num2[end2--] - '0') : 0;
size_t sum = val1 + val2 + carry;
ans.insert(ans.begin(), sum % 10 + '0'); // 头插
carry = sum / 10;
}
return ans;
}
// 字符串相乘
string multiply(string num1, string num2) {
if (num1 == "0" || num2 == "0") // 特殊情况
{
return string("0");
}
// 思路:
// 123 * 456
// = 123 * (400 + 50 + 6)
// = [(123 * 4) * 100] + [(123 * 5) * 10] + (123 * 6)
// 所以首先考虑计算出 123 * 6/5/4,然后在其后面添加适当的 '0',最后再将所有的积相加
string ans;
int end2 = num2.size() - 1;
size_t count = 0; // 需要添加的 '0' 的数量
while (end2 >= 0)
{
size_t val2 = num2[end2--] - '0';
string product;
size_t carry = 0;
int end1 = num1.size() - 1;
while (end1 >= 0 || carry > 0)
{
size_t val1 = end1 >= 0 ? (num1[end1--] - '0') : 0;
size_t sum = val1 * val2 + carry;
product += sum % 10 + '0';
carry = sum / 10;
}
reverse(product.begin(), product.end());
product.append(count++, '0');
ans = add(ans, product);
}
return ans;
}
};
五、把字符串转换成整数
描述:
将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为 0 或者字符串不是一个合法的数值则返回 0
数据范围:
字符串长度满足 0≤ n ≤100
进阶:
空间复杂度 O(1) ,时间复杂度 O(n)
注意:
① 字符串中可能出现任意符号,出现除 +/- 以外符号时直接输出 0
② 字符串中可能出现 +/- 且仅可能出现在字符串首位。
输入描述:
输入一个字符串,包括数字字母符号,可以为空
返回值描述:
如果是合法的数值表达则返回该数字,否则返回0
示例 1:
输入:"+2147483647"
返回值:2147483647
示例 2:
输入:"1a33"
返回值:0
代码实现:
class Solution {
public:
int StrToInt(string str) {
// 如果是空字符串,则直接返回 0
size_t sz = str.size();
if (sz == 0)
return 0;
// 确定正负号
size_t i = 0;
int sign = 1; // 默认为正号
if (str[0] == '+')
{
++i;
}
else if (str[0] == '-')
{
++i;
sign = -1;
}
// 确定绝对值
int res = 0;
while (i < sz)
{
if (str[i] >= '0' && str[i] <= '9')
res = res * 10 + (str[i] - '0');
else
return 0;
++i;
}
return sign * res;
}
};