题号:1,2,3,5,6,7,8,9
1. Two Sum
遍历整个vector,利用两重循环找出所有的相加组合,如果相加符合条件,则将这两个数返回即可。
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> vec(2);
int i,j;
for(i=0;i<nums.size();++i){
for(j=i+1;j<nums.size();++j){
if(nums[i]+nums[j]==target){
vec[0]=i;
vec[1]=j;
return vec;
}
}
}
return vec;
}
2. Add Two Numbers
题目要求将两个链表的值相加,两个链表可能不一样长。
首先要设置进位变量carry表示进位,每一位的相加过程中:
- 和sum等于进位carry
- 如果l1链表此位有值,则相加,同时指针后移一位
- 如果l2链表此位有值,则相加,同时指针后移一位
- 如果sum大于9,则减10并置carry为1,否则carry为0
- 如果头指针beg为空,则为其申请空间将sum存储;否则给当前指针cur申请空间将sum存储,并将cur指向下一位
- 当l1,l2链表都使用完后,且carry为0时(无进位),退出循环返回头指针beg
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
int carry=0,sum=0;
ListNode *t1,*t2;
t1=l1,t2=l2;
ListNode *beg=NULL,*cur;
while(1){
sum=carry;
if(t1!=NULL){
sum+=t1->val;
t1=t1->next;
}
if(t2!=NULL){
sum+=t2->val;
t2=t2->next;
}
if(sum>9) carry=1,sum-=10;
else carry=0;
if(beg==NULL){
beg=new ListNode(sum);
cur=beg;
}
else{
cur->next=new ListNode(sum);
cur=cur->next;
}
if(t1==NULL&&t2==NULL&&carry==0) break;
}
return beg;
}
3. Longest Substring Without Repeating Characters
原始思路和解法:
- pos:当前扩展字符串的起点
- change:出现相同字符则为1,否则为0
- ans:最长长度
- res:当前选取的字符串的长度
我举个例子解释原理,就不解释代码了。
如字符串: abcdefcgh
- 从第0位a开始,一位一位扩展字符串,得到abcdef
- 扩展下一位c,产生重复,需要选取新的串进行扩展
- 为了提高效率,选取串 defc继续扩展。
关键在于提高效率,如果这样做,而是从b重新开始,会浪费大量的时间。
因为前面的字符串已经被计算过,并没有被重复计算的必要,因此选取新的串就可以直接选择前面重复的字符(c)后面的所有处理到的字符(defc)作为新的串
int lengthOfLongestSubstring(string s) {
int len=s.size();
if(len==0) return 0;
int ans=1,res=1;
int pos=0;
int change=0;
for(int i=0;i<len;++i){
if(i<pos) continue;
for(int j=pos+res;j<len;++j){
for(int k=i;k<j;++k){
if(s[k]==s[j]){
pos=k+1;
change=1;
break;
}
}
if(!change) res++;
else{
change=0;
res=j-pos;
break;
}
if(res>ans) ans=res;
}
}
return ans;
}
sliding window:
int lengthOfLongestSubstring(string s) {
int len=s.size();
if(len==0) return 0;
int ans=1;
int index[128]={0};
for(int i=0,j=0;j<len;++j){
i=index[s[j]]>i?index[s[j]]:i;
ans=(j-i+1)>ans?(j-i+1):ans;
index[s[j]]=j+1;
}
return ans;
}
5. Longest Palindromic Substring
要寻找最长的回文子串,可以从回文子串的中心向两边扩展。
注意事项:
- 回文串有两种类型:aba和abba,即中心是奇数个相同字母或中间是偶数个相同字母的
使用一层循环来选取中心。
- 假设该中心为奇数型中心,将当前选取的中心向两边扩展,如果得到更长的回文串,则记录下中心位置和回文串长度。
- 假设该中心为偶数型中心,将当前选取的中心向两边扩展,如果得到更长的回文串,则记录下中心位置和回文串长度。
最后根据中心位置和最长回文串长度返回最长回文串即可。
整体为 O(n^2)
string longestPalindrome(string s) {
int len=s.size();
if(len==0) return "";
int ans=1;
int res,length;
int center=0;
for(int i=0;i<len;++i){
//single center
length=res=1;
while(1){
if(i+res<len&&i-res>=0&&s[i+res]==s[i-res]) res++,length+=2;
else break;
}
if(length>ans) ans=length,center=i;
//double center
length=res=0;
while(1){
if(i-res>=0&&i+res+1<len&&s[i-res]==s[i+res+1]) res++,length+=2;
else break;
}
if(length>ans) ans=length,center=i;
}
if(ans%2==0) return s.substr(center-ans/2+1,ans);
return s.substr(center-ans/2,ans);
}
6. ZigZag Conversion
很简单,只是数学关系而已
- 第0行:初始为0,每次递增 2*numRows-2
- 第numRows-1行:初始为numRows-1,每次递增2*numRows-2
- 第i行:初始为i,依次递增2*numRows-2*i-2,2*i
string convert(string s, int numRows) {
if(numRows==1) return s;
string str="";
int len=s.size();
for(int i=0;i<numRows;++i){
int r=i;
int change=1;
while(1){
if(r<len){
str+=s[r];
if(i==numRows-1||i==0) r+=2*numRows-2;
else if(change) r+=2*numRows-2*i-2;
else r+=2*i;
change=!change;
}
else break;
}
}
return str;
}
7. Reverse Integer
很简单,关键在于C++会出现int溢出问题,需要进行对是否溢出进行判断,如果溢出了则返回0.
int reverse(int x) {
if(x==0) return x;
if(x<10&&x>-10) return x;
bool neg=false;
if(x<0){
neg=true;
x=-x;
}
long long ans=0;
while(x>0){
ans*=10;
ans+=x%10;
x/=10;
}
if(ans>std::numeric_limits<int>::max()) return 0;
if(neg) ans=-ans;
return ans;
}
8. String to Integer (atoi)
注意事项:
- 要处理好int溢出问题,如果溢出,则返回最大值或最小值
- 要忽略前导空格
- 如果出现多个正负符号,则返回0
- 如果中途出现非法字符,则停止运算,直接返回当前已有结果
int myAtoi(string str) {
if(str=="") return 0;
int len=str.size();
//space
int beg=0;
while(str[beg]==' '&&beg<len) beg++;
bool neg=false;
if(str[beg]=='-') neg=true,beg++;
else if(str[beg]=='+') beg++;
long long ans=0;
for(int i=beg;i<len;++i){
if(str[i]=='+'||str[i]=='-') return 0;
if(str[i]<'0'||str[i]>'9') break;
ans*=10;
ans+=str[i]-'0';
if(ans>std::numeric_limits<int>::max()) break;
}
if(neg) ans=-ans;
if(ans>std::numeric_limits<int>::max()) return std::numeric_limits<int>::max();
if(ans<std::numeric_limits<int>::min()) return std::numeric_limits<int>::min();
return ans;
}
9. Palindrome Number
首先注意int溢出问题,溢出直接返回false
如果是负数,直接返回false
然后将整数转换成字符串,进行判断即可。
bool isPalindrome(int x) {
if(x>std::numeric_limits<int>::max()) return false;
if(x<0) return false;
string s="";
if(x==0) return true;
while(x>0){
s+=x%10+'0';
x/=10;
}
int len=s.size();
for(int i=0;i<len;++i){
if(s[i]!=s[len-i-1]) return false;
if(i==len-i-1) break;
}
return true;
}