2.两数相加
模拟相加操作,递归实现
相加大于10时,记录进位数为1,反之为0
有任一链表为空时,新建0节点补上
都为空时,若进位数为1,则补上1节点。
class Solution {
public:
void addnum(ListNode* n1,ListNode* n2,int up){
if(n1->val+n2->val+up<10){
n1->val=n1->val+n2->val+up;
up=0;
}
else if(n1->val+n2->val+up>=10){
n1->val=(n1->val+n2->val+up)%10;
up=1;
}
if(n2->next==nullptr&&n1->next!=nullptr){
ListNode* temp=new ListNode();
n2->next=temp;
temp->val=0;
}
else if(n2->next!=nullptr&&n1->next==nullptr){
ListNode* temp=new ListNode();
n1->next=temp;
temp->val=0;
}
else if(n2->next==nullptr&&n1->next==nullptr){
if(up==0) return;
else if(up==1){
ListNode* temp=new ListNode();
temp->val=1;
n1->next=temp;
return;
}
}
addnum(n1->next,n2->next,up);
}
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
int up=0;
addnum(l1,l2,up);
return l1;
}
};
3.无重复字符的最长子串
用滑动窗口法完成
右指针向右扩张至出现重复字符,然后左指针向右收缩
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_map<char,int> window;
int left=0,right=0;
int res=0;
while(right<s.size()){
char c=s[right];
right++;
window[c]++;
while(window[c]>1){
char d=s[left];
left++;
window[d]--;
}
res=max(res,right-left);
}
return res;
}
};
5.最长回文子串
1.动态规划
k为字符串长度-1
i为字符串起始位置
j为字符串终止位置
dp记录之前的子串是否为回文子串
三种情况:
(1)k=0,全部为回文子串,置1
(2)k=1,检查左右两边是否相等,是置1否置0
(3)k>1,检查左右两边是否相等,同时检查中间部分是否回文
class Solution {
public:
string longestPalindrome(string s) {
int n = s.size();
int dp[n][n];
string ans;
for(int k=0;k<n;++k){
for(int i=0;i+k<n;++i){
int j=i+k;
if(k==0){
dp[i][j]=1;
}
else if(k==1){
dp[i][j]=(s[i]==s[j]);
}
else{
dp[i][j]=(s[i]==s[j]&&dp[i+1][j-1]);
}
if(dp[i][j]&&k+1>ans.size()){
ans=s.substr(i,k+1);
}
}
}
return ans;
}
};
2.中心扩散
i为中心点,分为奇偶扩散,分别计算长度,取最大位置
class Solution {
public:
pair<int,int> expandFromCenter(string &s,int left,int right){
while(left>=0&&s[left]==s[right]&&right<s.size()){
left--;
right++;
}
return {left+1,right-1};
}
string longestPalindrome(string s) {
int n = s.size();
int start=0,end=0;
for(int i=0;i<n-1;++i){
auto [left1,right1]=expandFromCenter(s,i,i);
auto [left2,right2]=expandFromCenter(s,i,i+1);
if(right1-left1>end-start){
start=left1;
end=right1;
}
if(right2-left2>end-start){
start=left2;
end=right2;
}
}
return s.substr(start,end-start+1);
}
};
11.盛最多水的容器
双指针法
哪边小收缩哪边
class Solution {
public:
int maxArea(vector<int>& height) {
int n=height.size();
int left=0,right=n-1;
int Max=(right-left)*min(height[left],height[right]);
while(left<right){
if(height[left]<height[right]){
left++;
}
else if(height[left]>=height[right]){
right--;
}
Max=max(Max,(right-left)*min(height[left],height[right]));
}
return Max;
}
};
15.三数之和
排序
从左到右先取一个数,然后化为两数之和
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int n=nums.size();
sort(nums.begin(),nums.end());
vector<vector<int>> ans;
for(int first=0;first<n;++first){
if(first>0&&nums[first]==nums[first-1]){
continue;
}
int target=-nums[first];
int third=n-1;
for(int second=first+1;second<n;++second){
if(second>first+1&& nums[second]==nums[second-1]){
continue;
}
while(second<third&&nums[second]+nums[third]>target){
third--;
}
if(second==third){
break;
}
if(nums[second]+nums[third]==target){
ans.push_back({nums[first],nums[second],nums[third]});
}
}
}
return ans;
}
};
17.电话号码的字母组合
回溯算法来做
class Solution {
public:
vector<string> letterCombinations(string digits) {
vector<string> res;
if(digits.size()==0){
return res;
}
unordered_map<char,string> tab{
{'2',"abc"},
{'3',"def"},
{'4',"ghi"},
{'5',"jkl"},
{'6',"mno"},
{'7',"pqrs"},
{'8',"tuv"},
{'9',"wxyz"}
};
string com;
backtrack(digits,res,com,tab,0);
return res;
}
void backtrack(const string &digits,vector<string> &combination,string &com,unordered_map<char,string> &tab,int index){
if(index==digits.size()){
combination.emplace_back(com);
}
else{
char digit=digits[index];
const string &phone=tab[digit];
for(char c:phone){
com.push_back(c);
backtrack(digits,combination,com,tab,index+1);
com.pop_back();
}
}
}
};