class Solution {
public:
string addStrings(string num1, string num2) {
int index1=num1.size()-1,index2=num2.size()-1;//找到最后一位
int next=0;//进位
string retStr;
while(index1>=0||index2>=0)//还有一个没完就要进来:有可能一直进位
{
int val1=0,val2=0;
if(index1>=0)
{
val1=num1[index1--]-'0';
}
if(index2>=0)
{
val2=num2[index2--]-'0';
}
int ret=next+val1+val2;//两者相加后加上进位数
next=ret/10;//需要进位就是1了,不需要就是0
ret%=10;
retStr.insert(0,1,'0'+ret);//头插到新string
}
//最后有可能有1+9的情况,现在只会有0
if(next==1)
{
retStr.insert(0,1,'1');
}
return retStr;
}
};
但此时还是有一个问题的,那就是效率低(因为头插时间复杂度O(N^2));
class Solution {
public:
string addStrings(string num1, string num2) {
int index1=num1.size()-1,index2=num2.size()-1;//找到最后一位
int next=0;//进位
string retStr;
while(index1>=0||index2>=0)//还有一个没完就要进来:有可能一直进位
{
int val1=0,val2=0;
if(index1>=0)
{
val1=num1[index1--]-'0';
}
if(index2>=0)
{
val2=num2[index2--]-'0';
}
int ret=next+val1+val2;//两者相加后加上进位数
next=ret/10;//需要进位就是1了,不需要就是0
ret%=10;
//使用尾插效率更好,尾插有append,这里我们使用+=
retStr+='0'+ret;
}
//最后有可能有1+9的情况,现在只会有0
if(next==1)
{
retStr+='1';
}
reverse(retStr.begin(),retStr.end());//尾插后,最后翻转一下
return retStr;
}
};
整体思路都是一样的,只不过有头插换成了尾插+翻转
class Solution {
public:
bool isPalindrome(string s) {
string re;
for(auto e:s)//按照要求修改好
{
if((e>='A'&&e<='Z')||(e>='a'&&e<='z')||(e>='0'&&e<='9'))
{
if(e>='A'&&e<='Z')
{
re+=(e+32);
}
else
{
re+=e;
}
}
}
string modified(re);
reverse(re.begin(),re.end());
//看看是否相同
for(int i=0;i<modified.size();i++)
{
if(re[i]!=modified[i])
{
return false;
}
}
return true;
}
遍历输入字符串 s 中的每个字符 e。
如果字符 e 是字母或数字,则根据题目要求将大写字母转换为小写字母,并将其添加到新的字符串 re 中。
创建一个新的字符串 modified,它是字符串 re 的一个副本。
反转字符串 re。
比较反转后的字符串 re 和副本字符串 modified,如果它们不相等,则返回 false,表示不是回文字符串;如果它们相等,则返回 true,表示是回文字符串
bool isLetterOrNumber(char ch)
{
return (ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')||(ch>='0'&&ch<='9');
}
class Solution {
public:
bool isPalindrome(string s) {
for(auto& e:s)//大的变小的
{
if(e>='A'&&e<='Z')
{
e+=32;
}
}
int begin=0;
int end=s.size()-1;
while(begin<end)
{
while(begin<end&&!isLetterOrNumber(s[begin]))
{
begin++;
}
while(begin<end&&!isLetterOrNumber(s[end]))
{
--end;
}
if(s[begin]!=s[end])
{
return false;
}
else
{
++begin;
--end;
}
}
return true;
}
};
class Solution {
public:
string reverseStr(string s, int k) {
int len=s.size();
for(int i=0;i<len;i+=2*k)
{
if(i+k<=len)//剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
//同时前面的2k区域不用管,直接满足,只有最后那个不够2k的区间才讨论
{
reverse(s.begin()+i,s.begin()+i+k);
}
else{
reverse(s.begin()+i,s.begin()+len);
}
}
return s;
}
};
利用每次要跳2k来处理:就直接i+=2k
,这样每次直接跳到下一个区间,前面够2k的不用管,直接满足i+k<=len
,只有那最后一个不够2k的需要讨论(毕竟s.begin()+len
是最后元素的下个位置)
class Solution {
public:
string reverseWords(string s) {
size_t pos=0;
int i=0;
while(i<s.size())
{
pos=s.find(' ',i);
if(pos==string::npos)//只有一个单词了
{
reverse(s.begin()+i,s.end());
break;
}
reverse(s.begin()+i,s.begin()+pos);
i=(pos+1);
}
return s;
}
};
总体思路是找到单词的左和右索引,在这个区间内进行翻转
i
对字符串进行遍历,pos来储存找到的' '
的下标reserve()函数
左闭右开的性质i=pos+1
(跳到空格后)i
到end()
进行翻转了class Solution {
public:
string reverseWords(string s) {
int i=0;
while(i<s.size())//直接进循环
{
int left=i;//存一下起始位置
while(i<s.size()&&s[i]!=' ')//找空格
{
i++;
}
//现在要么找到了,要么到size处了
int right=i-1;
while(left<right)//开始换
{
swap(s[left],s[right]);
left++;
right--;
}
if(s[i]==' ')
{
i++;
}
}
return s;
}
};
总体思路是一样的,不过自己找,没有利用find
今天就到这里啦!