前言
这里的题目大多是用c++写的。
原题链接:仅仅反转字母
my version:
class Solution {
public:
string reverseOnlyLetters(string s) {
int begin = 0,end = s.size() - 1;
while(begin < end)
{
while(begin<end&&!isalpha(s[begin]))
{
begin++;
}
while(begin<end&&!isalpha(s[end]))
{
end--;
}
swap(s[begin],s[end]);
begin++;
end--;
}
return s;
}
};
原题链接:字符串中的第一个唯一字符
计数法:
class Solution {
public:
int firstUniqChar(string s) {
int arr[130] = {0};
for(auto x : s)
{
arr[x-'0']++;
}
int i = 0;
for(auto x : s)
{
if(arr[x-'0'] == 1)
return i;
i++;
}
return -1;
}
};
原题链接: 翻转字符串
版本一:
class Solution {
public:
void reverseString(vector<char>& s) {
int left = 0,right = s.size() -1;
while(left<right)
{
char tmp = s[left];
s[left] = s[right];
s[right] = tmp;
// swap(s[left],s[right]);这边交换可以直接用c++给的swap
left++;
right--;
}
}
};
这里不能用指针
版本二:
class Solution {
public:
void reverseString(vector<char>& s) {
reverse(s.begin(),s.end());
}
};
原题链接:验证回文串
自己做的:
class Solution {
public:
bool isPalindrome(string s) {
string s1(s.size(),'\0');
string::iterator it = s.begin();
int i = 0;
while (it != s.end())
{
if (isalnum(*it))
{
s1[i++] = *it;
}
it++;
}
transform(s1.begin(), s1.end(), s1.begin(), ::tolower);
int sz = 0;
while (s1[sz] != '\0')
{
sz++;
}
string s2(s1,0,sz);
s1 = s2;
reverse(s2.begin(), s2.end());
if (s1.compare(s2) == 0)
return true;
else
return false;
}
};
做这道题,让我深刻意识到以下几点:
那么如果有’\0’存在,我们该怎么求有效字符的长度呢?
我们可以用到string类的一个函数:c_str()
void Test2()
{
string s(10,'\0');
//s.reserve(10);
s[0] = 'a';
int lenth = strlen(s.c_str());//
cout << s << endl;
cout << s.size() << endl;
cout << lenth << endl;
//cout << s.capacity() << endl;
//s.reserve(200);
//cout << s.capacity() << endl;
}
官方版本:
方法一:筛选 + 判断
class Solution {
public:
bool isPalindrome(string s) {
string sgood;
for (char ch: s) {
if (isalnum(ch)) {
sgood += tolower(ch);//可以用运算符重载+=
}
}
string sgood_rev(sgood.rbegin(), sgood.rend());//直接用rbegin反转
return sgood == sgood_rev;//运算符重载==判断是否相等
}
};
方法二:双指针
class Solution {
public:
bool isPalindrome(string s) {
string sgood;
for (char ch: s) {
if (isalnum(ch)) {
sgood += tolower(ch);
}
}
int n = sgood.size();
int left = 0, right = n - 1;
while (left < right) {
if (sgood[left] != sgood[right]) {
return false;
}
++left;
--right;
}
return true;
}
};
方法三:在原字符串上直接判断
我们直接在原字符串 sss 上使用双指针。在移动任意一个指针时,需要不断地向另一指针的方向移动,直到遇到一个字母或数字字符,或者两指针重合为止。也就是说,我们每次将指针移到下一个字母字符或数字字符,再判断这两个指针指向的字符是否相同
class Solution {
public:
bool isPalindrome(string s) {
int n = s.size();
int left = 0, right = n - 1;
while (left < right) {
while (left < right && !isalnum(s[left])) {
++left;
}
while (left < right && !isalnum(s[right])) {
--right;
}
if (left < right) {
if (tolower(s[left]) != tolower(s[right])) {
return false;
}
++left;
--right;
}
}
return true;
}
};
原题链接:把字符串转换成整数
my version:
class Solution {
public:
bool IsLegal(string str)
{
for(auto ch : str)
{
if((ch>'9'||ch<'0'))
return false;
}
return true;
}
int StrToInt(string str) {
if(str.size() == 0)
return 0;
if(((str[0]!='+'&&str[0]!='-')&&(str[0]>'9'||str[0]<'0')))
return 0;
string s1(str,1);
if(IsLegal(s1) == false )
return 0;
int lenth = str.size();
if(str[0]=='+'||str[0]=='-')
lenth--;
int sum = 0;
string s2 = (str[0]<='9'&&str[0]>='0') ? str:s1;
for(auto ch : s2)
{
int x = ch - '0';
sum+=x*pow(10,lenth - 1);
lenth--;
}
if(str[0]=='-')
sum = -sum;
return sum;
}
};
other version:
class Solution {
public:
int StrToInt(string str) {
int ans = 0;int isplus = 1;
for(char ch:str){
if(isalpha(ch))
{
return 0;
}if (ch == '+' || ch =='-')
{
isplus = (ch == '+') ? 1 : -1;
}
if(isdigit(ch))
{
ans = ans*10+ch-'0';
}
}return isplus*ans;
}
};
这个版本厉害!
原题链接:字符串最后一个单词的长度
my version:
#include
using namespace std;
int main() {
string s;
getline(cin,s);//这样可以输入空格
int len;
if(s.rfind(' ')==string::npos)
len = s.size();
else
len = s.size()-s.rfind(' ') - 1;
cout<<len;
}
原题链接: 字符串相加
my version:
class Solution {
public:
string addStrings(string num1, string num2) {
//假设num1的长度最小
string s;
if(num1.size()>num2.size())
{
swap(num1,num2);//交换一下
}
int end1 = num1.size() - 1,end2 = num2.size() - 1;//end1<=end2
int tmp = 0,next = 0;
char ch;
while(end2>=0)
{
if(end1>=0)
{
tmp = num1[end1]-'0'+num2[end2] - '0'+next;
next = 0;
if(tmp>9)
next = 1;
tmp%=10;
ch = tmp+'0';
s+=ch;
}
else
{
tmp = num2[end2] - '0' + next ;
next = 0;
if(tmp>9)
next = 1;
tmp%=10;
ch = tmp+'0';
s+=ch;
}
end1--;
end2--;
if(end2==-1&&next==1)
{
s+='1';
}
}
reverse(s.begin(),s.end());
return s;
}
};
优化一下:
class Solution {
public:
string addStrings(string num1, string num2) {
//假设num1的长度最小
string s;
if(num1.size()>num2.size())
{
swap(num1,num2);//交换一下
}
int end1 = num1.size() - 1,end2 = num2.size() - 1;//end1<=end2
int tmp = 0,next = 0;
int _num1;
char ch;
while(end2>=0)
{
if(end1>=0)
_num1 = num1[end1]-'0';
else
_num1 = 0;
tmp = _num1+num2[end2] - '0'+next;
next = 0;
if(tmp>9)
next = 1;
tmp%=10;
ch = tmp+'0';
s+=ch;
end1--;
end2--;
if(end2==-1&&next==1)
{
s+='1';
}
}
reverse(s.begin(),s.end());
return s;
}
};
其实这里while的判断条件改为二者都>=0就行了。
这样就不用可以去比较num1和num2的长度
原题链接: 反转字符串 II
my version:
class Solution {
public:
string reverseStr(string s, int k) {
int left = 0, right = k - 1;
int count = 0;
for (int i = 0;i<s.size(); i++)
{
count++;
if (count == 2 * k)
{
int tmp1 = left,tmp2 = right;
while (tmp1 < tmp2)
{
swap(s[tmp1++], s[tmp2--]);
}
left+=2*k;
right = left + k - 1;
count = 0;
}
int len = s.size() - left;
if (len < k)
{
right = s.size() - 1;
while (left < right)
{
swap(s[left], s[right]);
left++;
right--;
}
break;
}
if(len<2*k&&len>=k)
{
while (left < right)
{
swap(s[left], s[right]);
left++;
right--;
}
break;
}
}
return s;
}
};
official version:
class Solution {
public:
string reverseStr(string s, int k) {
int n = s.length();
for (int i = 0; i < n; i += 2 * k) {
reverse(s.begin() + i, s.begin() + min(i + k, n));
}
return s;
}
};
看完后感觉自己的作法简直是猿古人
原题链接:反转字符串中的单词 III
my version:
lass Solution {
public:
string reverseWords(string s) {
size_t begin = 0,end = s.find(' ');
while(string::npos!=end)
{
reverse(s.begin()+begin,s.begin()+end);
begin = end+1;
end = s.find(' ',end+1);
}
reverse(s.begin()+begin,s.end());
return s;
}
};
原题链接:字符串相乘
my version:
class Add {
public:
string addStrings(string num1, string num2) {
//假设num1的长度最小
string s;
if (num1.size() > num2.size())
{
swap(num1, num2);//交换一下
}
int end1 = num1.size() - 1, end2 = num2.size() - 1;//end1<=end2
int tmp = 0, next = 0;
int _num1;
char ch;
while (end2 >= 0)
{
if (end1 >= 0)
_num1 = num1[end1] - '0';
else
_num1 = 0;
tmp = _num1 + num2[end2] - '0' + next;
next = 0;
if (tmp > 9)
next = 1;
tmp %= 10;
ch = tmp + '0';
s += ch;
end1--;
end2--;
if (end2 == -1 && next == 1)
{
s += '1';
}
}
reverse(s.begin(), s.end());
return s;
}
};
class Solution {
public:
string multiply(string num1, string num2) {
int end1 = num1.size() - 1, end2 = num2.size() - 1;
string sum("");
Add add;
for (int i = end1,mu = 0; i >= 0; i--,mu++)
{
string s("");
int next = 0;
for (int j = end2; j >= 0; j--)
{
int x1 = num1[i] - '0';
int x2 = num2[j] - '0';
int ref = ((x1 * x2) + next)%10;//要插入stirng的数字
next = ((x1 * x2) + next) / 10;//下回合要加的
s += ref + '0';
}
if (next != 0)
s += next + '0';
reverse(s.begin(), s.end());
//接下来要追加0
for (int k = 0;k < mu; k++)
{
s += '0';
}
sum = add.addStrings(sum, s);
}
if(sum[0]=='0')
sum = '0';
return sum;
}
};