LeetCode 中等 2,3,5,11,15,17

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();
            }
        }
    }
    

};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值