二刷leetcode200题回顾

1、两数之和

在这里插入图片描述
使用unoredred_map进行存储,注意!map的申请形式是<int,int>

class Solution {
    
    
public:
    vector<int> twoSum(vector<int>& nums, int target) {
    
    
        int n=nums.size();
        unordered_map<int,int> map1;
        for(int i=0;i<n;i++){
    
    
            int x=target-nums[i];
            if(map1.find(x)!=map1.end()){
    
    
                return {
    
    map1[x],i};
            }
            else map1[nums[i]]=i;
        }
        return {
    
    -1,-1};

    }
};

2:两数相加

在这里插入图片描述
使用a记录进位,每次循环一定要将求和ans置零!!最后一定要加判断,是否最后a是1,如果是1,需要再加一个链表结点记录最高位!!

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
    
    
        if(l1==NULL) return l2;
        if(l2==NULL) return l1;
        ListNode* result=new ListNode(0);
        ListNode* re=result;
        int ans=0,a=0;
        while(l1!=NULL||l2!=NULL){
    
    
            ans=0;
            if(l1!=NULL){
    
    
                ans+=l1->val;
                l1=l1->next;
            }
            if(l2!=NULL){
    
    
                ans+=l2->val;
                l2=l2->next;
            }
            ans+=a;
            a=ans/10==0?0:1;
            re->next=new ListNode(ans%10);
            re=re->next;
        }
        if(a==1) re->next=new ListNode(a);
        return result->next;

    }
};

3:无重复字符的最长子串(再刷)

在这里插入图片描述
这个题的关键!!使用双指针,left到right所有字符与right判断,如果没有相等的,一步步右移right,有相等的,移动left指针。全程使用len记录当前长度。
注意:每更新一次left,需要重新设置len!!!

class Solution {
    
    
public:
    int lengthOfLongestSubstring(string s) {
    
    
        if(s.size()==0) return 0;
        int m=s.size();
        int len=0,re=0;
        int left=0,right=0;
        while(right<m){
    
    
            for(int i=left;i<right;i++){
    
    
                if(s[i]==s[right]){
    
    
                    left=i+1;
                    len=right-left;
                }
            }
            right++;
            len++;
            re=max(re,len);
        }
        return re;

    }
};

5:最长回文子串(再刷)

在这里插入图片描述
使用动态规划,但是需要注意:判断要使用==,而且substr用法,s.substr(开始截取位置坐标,截取长度)

class Solution {
    
    
public:
    string longestPalindrome(string s) {
    
    
        if(s.size()==0) return s;
        int m=s.size();
        vector<vector<int>> dp(m,vector<int>(m));
        int start=0,len=0;
        for(int i=0;i<s.size();i++){
    
    
            dp[i][i]=1;
            len=1;           
        }
        for(int j=0;j<m-1;j++){
    
    
            if(s[j]==s[j+1]){
    
    
                 dp[j][j+1]=1;
                 len=2;
                 start=j;
            }
        }
        for(int l=3;l<=m;l++){
    
    
            for(int i=0;i<=m-l;i++){
    
    
                int j=i+l-1;
                if(s[i]==s[j]&&dp[i+1][j-1]==1){
    
    
                    dp[i][j]=1;
                    len=l;
                    start=i;
                }

            }
        }
        return s.substr(start,len);

    }
};

7:整数反转

在这里插入图片描述
使用vector容器存储,判断是否超过存储大小!

class Solution {
    
    
public:
    int reverse(int x) {
    
    
        if(x==0) return x;
        vector<int> re;
        while(x){
    
    
            re.push_back(x%10);
            x=x/10;
        }
        long ans=0;
        for(int i=0;i<re.size();i++){
    
    
            ans=ans*10+re[i];
            if(ans>INT_MAX||ans<INT_MIN) 
                return 0;
            
        }
        return ans;

    }
};

9:回文数

在这里插入图片描述
使用vector存储,记录错误:x.size(),应该是re.size()。仔细检查!!!re[right]不是right

class Solution {
    
    
public:
    bool isPalindrome(int x) {
    
    
        if(x==0) return true;
        vector<int> re;
        if(x<0) return false;
        while(x){
    
    
            re.push_back(x%10);
            x=x/10;
        }
        int left=0,right=re.size()-1;
        while(left<right){
    
    
            if(re[left]!=re[right]) {
    
    
                return false;
            }
            left++;
            right--;
        }
        return true;
    }
};

11:盛最多水的容器

在这里插入图片描述
使用双指针!左指针小,那么所有以左指针为边界的组合都小于当前情况,因为左指针固定最低高度,而宽度减少。

class Solution {
    
    
public:
    int maxArea(vector<int>& height) {
    
    
        int m=height.size();
        if(m==0) return 0;
        int left=0,right=m-1;
        int ans=0,len=0;
        while(left<right){
    
    
            len=min(height[left],height[right])*(right-left);
            ans=max(ans,len);
            if(height[left]<height[right]) left++;
            else if(height[left]>=height[right]) right--;
        }
        return ans;
    }
};

14:最长公共前缀

在这里插入图片描述
想清楚,最长公共前缀,只要有不符合直接退出,输出前缀

class Solution {
    
    
public:
    string longestCommonPrefix(vector<string>& strs) {
    
    
        if(strs.size()==0) return "";
        if(strs[0].size()==0) return "";
        int m=strs[0].size();
        int n=strs.size();
        int a=0;
        string ans;
        for(int i=0;i<m;i++){
    
    
            for(int j=1;j<n;j++){
    
    
                if(strs[0][i]!=strs[j][i]){
    
    
                    a=1;
                }

            }
            if(a==0) ans+=strs[0][i];
            if(a==1) return ans;
        }
        return ans;
    }
};

15:三数之和(再刷一遍!)

在这里插入图片描述
再刷一遍!注意双指针用法以及去重,同时注意while判断

class Solution {
    
    
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
    
    
        vector<vector<int>> result;
        int m=nums.size();
        if(m==0) return result;
        sort(nums.begin(),nums.end());
        for(int i=0;i<m;i++){
    
    
            if(nums[i]>0) return result;
            if(i>0&&nums[i]==nums[i-1]) continue;
            int left=i+1,right=m-1;
            while(left<right){
    
    
                if(nums[i]+nums[left]+nums[right]>0) right--;
                else if(nums[i]+nums[left]+nums[right]<0) left++;
                else{
    
    
                    result.push_back(vector<int>{
    
    nums[i],nums[left],nums[right]});
                    while(left<right&&nums[left]==nums[left+1]) left++;
                    while(left<right&&nums[right]==nums[right-1]) right--;
                    left++;
                    right--;
                }
            }
        }
        return result;

    }
};

16:最接近的三数之和

在这里插入图片描述
还是使用双指针法进行判断,需要制定一个判断距离的变量

class Solution {
    
    
public:
    int threeSumClosest(vector<int>& nums, int target) {
    
    
        int m=nums.size();
        sort(nums.begin(),nums.end());
        if(m==0) return 0;
        int len=INT_MAX,ans=0;
        for(int i=0;i<m;i++){
    
    
            int left=i+1,right=m-1;
            while(left<right){
    
    
                if(nums[i]+nums[left]+nums[right]==target) return target;
                int x=nums[i]+nums[left]+nums[right];
                if(abs(x-target)<len) {
    
    
                    len=abs(x-target);
                    ans=x;
                }
                if(x>target) right--;
                else if(x<target) left++;
            }
        }
        return ans;

    }
};

17:电话号码的字母组合

在这里插入图片描述

class Solution {
    
    
public:
    string path;
    vector<string> result;
    string letter[10]={
    
    "","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
    void travel(string digits,int index){
    
    
        if(index==digits.size()) {
    
    
            result.push_back(path);
            return;
        }
        int digit=digits[index]-'0';
        string letters=letter[digit];
        for(int i=0;i<letters.size();i++){
    
    
            path.push_back(letters[i]);
            travel(digits,index+1);
            path.pop_back();
        }

    }
    vector<string> letterCombinations(string digits) {
    
            
        int m=digits.size();
        if(m==0) return result;
        travel(digits,0);
        return result;
    }
};

18:四数之和

在这里插入图片描述
使用双指针,同样必须关注括号类型,i–与i-1不同!
注意!!!left和right指针也需要循环,因此也需要使用while(left<right)判断

class Solution {
    
    
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
    
    
        int m=nums.size();
        sort(nums.begin(),nums.end());
        vector<vector<int>> result;
        if(m==0) return result;
        for(int i=0;i<m;i++){
    
    
            if(i>0&&nums[i]==nums[i-1]) continue;
            for(int j=i+1;j<m;j++){
    
    
                if(j>i+1&&nums[j]==nums[j-1]) continue;
                int left=j+1,right=m-1;
                while(left<right){
    
    
                int x=nums[i]+nums[j]+nums[left]+nums[right];
                if(x<target) left++;
                else if(x>target) right--;
                else{
    
    
                    result.push_back(vector<int>{
    
    nums[i],nums[j],nums[left],nums[right]});
                    while(left<right&&nums[left]==nums[left+1]) left++;
                    while(left<right&&nums[right]==nums[right-1]) right--;
                    left++;
                    right--;
                }
                }
            }
        }
        return result;

    }
};

19:删除链表的倒数第N个结点

在这里插入图片描述
使用双指针

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
    
    
        ListNode* dummy=new ListNode(0);
        dummy->next=head;
        ListNode* right=head;
        for(int i=0;i<n;i++){
    
    
            right=right->next;
        }
        ListNode* left=dummy;
        while(right!=NULL){
    
    
            left=left->next;
            right=right->next;
        }
        left->next=left->next->next;
        return dummy->next;

    }
};

20:有效的括号

在这里插入图片描述
注意栈是push,不是push_back!!!

class Solution {
    
    
public:
    bool isValid(string s) {
    
    
        int m=s.size();
        if(m==0) return true;
        stack<int> re;
        for(int i=0;i<m;i++){
    
    
            if(s[i]=='(') re.push(')');
            else if(s[i]=='{') re.push('}');
            else if(s[i]=='[') re.push(']');
            else if(!re.empty()&&s[i]==re.top()) re.pop();
            else if(re.empty()||s[i]!=re.top()) return false;
        }
        if(!re.empty()) return false;
        else return true;
    }
};

21:合并两个有序链表

在这里插入图片描述
一定要加else!!!不然l1->next会判断出界

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
    
    
        if(l1==NULL) return l2;
        if(l2==NULL) return l1;
        ListNode* result=new ListNode(0);
        ListNode* re=result;
        while(l1!=NULL||l2!=NULL){
    
    
            if(l1==NULL){
    
    
                re->next=l2;
                l2=l2->next;
            }
            else if(l2==NULL){
    
    
                re->next=l1;
                l1=l1->next;
            }
            else if(l1->val<l2->val){
    
    
                re->next=l1;
                l1=l1->next;
            }
            else if(l1->val>=l2->val){
    
    
                re->next=l2;
                l2=l2->next;
            }
            re=re->next;
        }
        return result->next;

    }
};

22:括号生成

在这里插入图片描述
使用回溯法!!!
认真,主函数变量名与子函数变量名不同!!!
left是左括号数量,right是右括号数量。注意不能使用引用,只在子函数里面处理输出就行

class Solution {
    
    
public:
    void travel(vector<string>& ans,string a,int left,int right,int max){
    
    
        if(a.size()==2*max) {
    
    
            ans.push_back(a);
            return;
        }
        if(left<max) travel(ans,a+'(',left+1,right,max);
        if(left>right&&right<max) travel(ans,a+')',left,right+1,max);

    }
    vector<string> generateParenthesis(int n) {
    
    
        vector<string> result;
        if(n==0) return result;
        travel(result,"",0,0,n);
        return result;
    }
};

24:两两交换链表中的结点

在这里插入图片描述
在一个循环中定义指针,想清楚每一步返回什么(返回交换后的第一个结点!!)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* swapPairs(ListNode* head) {
    
    
        if(head==NULL||head->next==NULL) return head;
        ListNode* cur=head->next;
        head->next=swapPairs(cur->next);
        cur->next=head;
        return cur;
    }
};

26:删除排序数组中的重复项

在这里插入图片描述
使用双指针法,nums[j]与nums[i]不断比较

class Solution {
    
    
public:
    int removeDuplicates(vector<int>& nums) {
    
    
        int m=nums.size();
        if(m==0) return 0;
        int i=0,j=0;
        for(int j=0;j<m;j++){
    
    
            if(nums[i]!=nums[j]){
    
    
                nums[i+1]=nums[j];
                i++;
            }
        }
        return i+1;
    }
};

31:下一个排列

在这里插入图片描述
本质上是将大的数字移到前面,但是由于必须按照顺序改变,因此尽量每次增大的最小。因此从后往前找到递增的nums[i],再找到nums[i]后最靠后的比他大的数,将两者交换,注意!同时需要将i后面排序。本质:升序变成降序!!!

class Solution {
    
    
public:
    void nextPermutation(vector<int>& nums) {
    
    
        int m=nums.size();
        if(m==0||m==1) return;
        int i=m-2;
        while(i>=0&&nums[i]>=nums[i+1]) i--;
        if(i>=0){
    
    
            int j=m-1;
            while(j>i&&nums[i]>=nums[j]) j--;
            swap(nums[i],nums[j]);
        }
        sort(nums.begin()+i+1,nums.end());        
    }
};

33:搜索旋转排序数组

在这里插入图片描述
一定有一半是有序数组,二分法分两种情况讨论
左闭右闭区间

class Solution {
    
    
public:
    int search(vector<int>& nums, int target) {
    
    
        int m=nums.size();
        if(m==0) return -1;
        if(m==1) return nums[0]==target?0:-1;
        int left=0;
        int right=m-1;
        while(left<=right){
    
    
            int mid=left+(right-left)/2;
            if(nums[mid]==target) return mid;
            if(nums[mid]>=nums[left]){
    
    
                if(nums[left]<=target&&nums[mid]>target) right=mid-1;
                else left=mid+1;
            }
            else{
    
    
                if(nums[mid]<target&&nums[right]>=target) left=mid+1;
                else right=mid-1;
            }
        }
        return -1;
    }
};

34:在排序数组中查找元素的第一个和最后一个位置

在这里插入图片描述
使用双指针法,但是一定要确定指针不能越界,比如加上i>=0

class Solution {
    
    
public:
    vector<int> searchRange(vector<int>& nums, int target) {
    
    
        int m=nums.size();
        if(m==0) return {
    
    -1,-1};
        int left=0,right=m-1,ans=-1;
        while(left<=right){
    
    
            int mid=left+(right-left)/2;
            if(nums[mid]==target) {
    
    
                ans=mid;
                break;
            }
            if(nums[mid]<target) left=mid+1;
            else right=mid-1;
        }
        if(ans==-1) return {
    
    -1,-1};
        int i=ans;
        while(i>=0&&nums[i]==target) i--;
        int j=ans;
        while(j<m&&nums[j]==target) j++;
        return {
    
    i+1,j-1};
    }
};

35:搜索插入位置

在这里插入图片描述
双指针法,注意最后是right+1

class Solution {
    
    
public:
    int searchInsert(vector<int>& nums, int target) {
    
    
        int m=nums.size();
        if(m==0) return 0;
        int left=0,right=m-1;
        while(left<=right){
    
    
            int mid=left+(right-left)/2;
            if(nums[mid]==target) return mid;
            if(nums[mid]<target) left=mid+1;
            if(nums[mid]>target) right=mid-1;
        }
        return right+1;
    }
};

38:外观数列(再刷一遍)

在这里插入图片描述
其实原理很简单,不要怕想,就是使用递归!!!一定要注意,每次其实需要i++

class Solution {
    
    
public:
    string countAndSay(int n) {
    
    
        if(n==1) return "1";
        string pre=countAndSay(n-1),ans;
        for(int i=0;i<pre.size();i++){
    
    
            int j=i;
            while(j<pre.size()&&pre[j]==pre[i]) j++;
            ans+=to_string(j-i);
            ans+=pre[i];
            i=j-1;
        }
        return ans;
    }
};

或者固定i,让j变化与i比较。注意j需要从与i相等的地方开始比较,否则无法遍历单数。最后一个数字需要比较,因此j要等于长度也可以

class Solution {
    
    
public:
    string countAndSay(int n) {
    
    
        if(n==1) return "1";
        string pre=countAndSay(n-1),ans;
        int i=0;
        for(int j=0;j<=pre.size();j++){
    
    
            if(pre[j]==pre[i]) continue;
            ans+=to_string(j-i);
            ans+=pre[i];
            i=j;
            j--;
        }
        return ans;
    }
};

39:组合总和

在这里插入图片描述
使用回溯!注意对于一个集合求组合,需要使用index,避免重复

class Solution {
    
    
public:
    vector<vector<int>> result;
    vector<int> path;
    void travel(vector<int> candidates,int ans,int index){
    
    
        if(ans==0) {
    
    
            result.push_back(path);
            return;
        }
        if(ans<0) return;
        for(int i=index;i<candidates.size();i++){
    
    
            path.push_back(candidates[i]);
            travel(candidates,ans-candidates[i],i);
            path.pop_back();
        }

    }
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
    
    
        int m=candidates.size();
        if(m==0) return result;
        travel(candidates,target,0);
        return result;
    }
};

进行剪枝,排序后可以直接判断需不需要进入下一递归

class Solution {
    
    
public:
    vector<vector<int>> result;
    vector<int> path;
    void travel(vector<int> candidates,int ans,int index){
    
    
        if(ans==0) {
    
    
            result.push_back(path);
            return;
        }
        if(ans<0) return;
        for(int i=index;i<candidates.size()&&ans-candidates[i]>=0;i++){
    
    
            path.push_back(candidates[i]);
            travel(candidates,ans-candidates[i],i);
            path.pop_back();
        }

    }
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
    
    
        int m=candidates.size();
        if(m==0) return result;
        sort(candidates.begin(),candidates.end());
        travel(candidates,target,0);
        return result;
    }
};

40:组合总和2

在这里插入图片描述
使用回溯,注意去重操作!同一层不能同时使用两次

class Solution {
    
    
public:
    vector<vector<int>> result;
    vector<int> path;
    void travel(vector<int> candidates,int ans,int index){
    
    
        if(ans==0) {
    
    
            result.push_back(path);
            return;
        }
        if(ans<0) return;
        for(int i=index;i<candidates.size()&&ans-candidates[i]>=0;i++){
    
    
            if(i>index&&candidates[i]==candidates[i-1]) continue;
            path.push_back(candidates[i]);
            travel(candidates,ans-candidates[i],i+1);
            path.pop_back();
        }

    }
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
    
    
        int m=candidates.size();
        if(m==0) return result;
        sort(candidates.begin(),candidates.end());
        travel(candidates,target,0);
        return result;
    }
};

46:全排列

在这里插入图片描述
排列问题需要使用use数组,记录使用次数,同时需要从0开始

class Solution {
    
    
public:
    vector<vector<int>> result;
    vector<int> path;
    void travel(vector<int>nums,vector<bool>& used){
    
    
        if(path.size()==nums.size()){
    
    
            result.push_back(path);
            return;
        }
        for(int i=0;i<nums.size();i++){
    
    
            if(used[i]==false) continue;
            path.push_back(nums[i]);
            used[i]=false;
            travel(nums,used);
            used[i]=true;
            path.pop_back();
        }
    }
    vector<vector<int>> permute(vector<int>& nums) {
    
    
        int m=nums.size();
        if(m==0) return result;
        vector<bool> used(nums.size(),true);
        travel(nums,used);
        return result;
    }
};

48:旋转图像

在这里插入图片描述
自外向内一共有不超过 n/2n/2 层,从外而内顺时针循环!使用for循环
i是层数,j是上下边界,下边界为m-i-1。其中j需要小于m-1-2*i
在这里插入图片描述

class Solution {
    
    
public:
    void rotate(vector<vector<int>>& matrix) {
    
    
        if(matrix.size()==0||matrix[0].size()==0) return;
        int m=matrix.size();
        int s=0;
        for(int i=0;m-2*i>1;i++){
    
         //或者i<m/2
            for(int j=0;j<m-1-2*i;j++){
    
       //或者j<n+1/2
                int s=matrix[i][i+j];
                matrix[i][i+j]=matrix[m-1-i-j][i];
                matrix[m-1-i-j][i]=matrix[m-1-i][m-1-i-j];
                matrix[m-1-i][m-1-i-j]=matrix[i+j][m-1-i];
                matrix[i+j][m-1-i]=s;
            }
        }

        
    }
};

后续加入直接翻转

class Solution {
    
    
public:
    void rotate(vector<vector<int>>& matrix) {
    
    
        int n = matrix.size();
        // 水平翻转
        for (int i = 0; i < n / 2; ++i) {
    
    
            for (int j = 0; j < n; ++j) {
    
    
                swap(matrix[i][j], matrix[n - i - 1][j]);
            }
        }
        // 主对角线翻转
        for (int i = 0; i < n; ++i) {
    
    
            for (int j = 0; j < i; ++j) {
    
    
                swap(matrix[i][j], matrix[j][i]);
            }
        }
    }
};


49:字母异位词分组

在这里插入图片描述
分类题,使用哈希表,第一遍分好类,第二遍取出即可。关键是如何分类,key值怎么取!
注意变量对应

class Solution {
    
    
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
    
    
        vector<vector<string>> result;
        if(strs.size()==0) return result;
        unordered_map<string,vector<string>> ans;
        for(int i=0;i<strs.size();i++){
    
    
            string s=strs[i];
            sort(s.begin(),s.end());
            ans[s].push_back(strs[i]);
        }
        for(auto l:ans){
    
    
            result.push_back(l.second);
        }
        return result;
    }
};

50:pow(x,n)

在这里插入图片描述
使用递归,考虑负号!!!本题有几个坑,首先r=i*n报错,必须使用long long型,输入负数转为正数会溢出。直接给long long赋值-2147483648会出错,问题不清楚!!!

class Solution {
    
    
public:
    double myPow1(double x, long long n) {
    
    
        if(n==1) return x;
        int w=n%2;
        double s=myPow(x,n/2);
        if(w==1) return s*s*x;
        else return s*s;
    }
    double myPow(double x, int n) {
    
    
        if(n==0) return 1;
        int i=1;
        if(n<0) i=-1;
        long long r=n;
        double s=myPow1(x,r*i);
        if(n<0) return 1/s;
        else return s;       
    }
};

53:最大子序和

在这里插入图片描述
使用动态规划,注意max1开始取值,避免只有一个数的情况

class Solution {
    
    
public:
    int maxSubArray(vector<int>& nums) {
    
    
        if(nums.size()==0) return 0;
        vector<int> dp(nums.size());
        dp[0]=nums[0];
        int max1=nums[0];
        for(int i=1;i<nums.size();i++){
    
    
            dp[i]=max(dp[i-1]+nums[i],nums[i]);
            max1=max(max1,dp[i]);
        }
        return max1;
    }
};

54:螺旋矩阵(再刷)

在这里插入图片描述
参考题解中大神答案:
1、首先设定上下左右边界
2、其次向右移动到最右,此时第一行因为已经使用过了,可以将其从图中删去,体现在代码中就是重新定义上边界
3、判断若重新定义后,上下边界交错,表明螺旋矩阵遍历结束,跳出循环,返回答案
4、若上下边界不交错,则遍历还未结束,接着向下向左向上移动,操作过程与第一,二步同理
5、不断循环以上步骤,直到某两条边界交错,跳出循环,返回答案

class Solution {
    
    
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
    
    
        vector<int> ans;
        int up=0,down=matrix.size()-1;
        int le=0,ri=matrix[0].size()-1;
        while(true){
    
    
            for(int j=le;j<=ri;j++) ans.push_back(matrix[up][j]);
            if(++up>down) break;
            for(int i=up;i<=down;i++) ans.push_back(matrix[i][ri]);
            if(--ri<le) break;
            for(int j=ri;j>=le;j--) ans.push_back(matrix[down][j]);
            if(--down<up) break;
            for(int i=down;i>=up;i--) ans.push_back(matrix[i][le]);
            if(++le>ri) break;
        }
        return ans;
    }
};

55:跳跃游戏

在这里插入图片描述每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到整体最大覆盖范围,看是否能到终点。关键是cover是一个整体变量,能多远到达。注意:必须要小于等于cover,能最远到达的位置

class Solution {
    
    
public:
    bool canJump(vector<int>& nums) {
    
    
        int cover=0;
        if(nums.size()==1) return true;
        for(int i=0;i<=cover;i++){
    
    
            cover=max(i+nums[i],cover);
            if(cover>=nums.size()-1) return true;
        }
        return false;
    }
};

45:跳跃游戏2

在这里插入图片描述
从覆盖范围出发,不管怎么跳,覆盖范围内一定是可以跳到的,以最小的步数增加覆盖范围,覆盖范围一旦覆盖了终点,得到的就是最小步数!
注意!一定要理解步数增加的条件,就是到了当前能跳到最大距离,但是没到最后,不论下一个最大距离是哪一步得到的,只要能跳到,加一就行

class Solution {
    
    
public:
    int jump(vector<int>& nums) {
    
    
        if (nums.size() == 1) return 0;
        int curDistance = 0;    // 当前覆盖最远距离下标
        int ans = 0;            // 记录走的最大步数
        int nextDistance = 0;   // 下一步覆盖最远距离下标
        for (int i = 0; i < nums.size(); i++) {
    
    
            nextDistance = max(nums[i] + i, nextDistance);  // 更新下一步覆盖最远距离下标
            if (i == curDistance) {
    
                             // 遇到当前覆盖最远距离下标
                if (curDistance != nums.size() - 1) {
    
           // 如果当前覆盖最远距离下标不是终点
                    ans++;                                  // 需要走下一步
                    curDistance = nextDistance;             // 更新当前覆盖最远距离下标(相当于加油了)
                    if (nextDistance >= nums.size() - 1) break; // 下一步的覆盖范围已经可以达到终点,结束循环
                } else break;                               // 当前覆盖最远距离下标是集合终点,不用做ans++操作了,直接结束
            }
        }
        return ans;
    }
};

56:合并区间

在这里插入图片描述
排序加双指针,关键在于判断左边第二个元素与右边第一个元素的大小

class Solution {
    
    
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
    
    
        int m=intervals.size();
        vector<vector<int>> ans;
        vector<int> s;
        sort(intervals.begin(),intervals.end());
        if(m==0) return ans;
        int j,l;
        for(int i=0;i<m;){
    
    
            j=i+1;;
            l=intervals[i][1];
            while(j<intervals.size()&&intervals[j][0]<=l){
    
    
                l=max(l,intervals[j][1]);
                j++;
            }
            ans.push_back(vector<int>{
    
    intervals[i][0],l});
            i=j;
        }
        return ans;
    }
};

61:旋转链表

在这里插入图片描述
各种特殊情况!!!k不一定小于size()
快慢指针

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* rotateRight(ListNode* head, int k) {
    
    
        if(head==NULL||head->next==NULL) return head;
        if(k==0) return head;
        ListNode* l1=head;
        int c=0;
        for(int i=0;i<k;i++){
    
    
            l1=l1->next;
            c++;
            if(l1==NULL) {
    
    
                l1=head;
                k=c+k%c;
            }
        }
        ListNode* l2=head;
        while(l1->next){
    
    
            l1=l1->next;
            l2=l2->next;
        }
        l1->next=head;
        ListNode* cur=new ListNode(0);
        cur->next=l2->next;
        l2->next=NULL;
        return cur->next;
    }
};

62:不同路径

在这里插入图片描述
动态规划

class Solution {
    
    
public:
    int uniquePaths(int m, int n) {
    
    
        if(m==0||n==0) return 0;
        vector<vector<int>> dp(m,vector<int>(n));
        for(int i=0;i<m;i++) dp[i][0]=1;
        for(int i=0;i<n;i++) dp[0][i]=1;
        for(int j=1;j<n;j++){
    
    
            for(int i=1;i<m;i++){
    
    
                dp[i][j]=dp[i-1][j]+dp[i][j-1];
            }
        }
        return dp[m-1][n-1];
    }
};

64:最小路径和

在这里插入图片描述
动态规划,注意!!!一定要返回m-1,n-1

class Solution {
    
    
public:
    int minPathSum(vector<vector<int>>& grid) {
    
    
        int m=grid.size(),n=grid[0].size();
        if(m==0||n==0) return -1;
        vector<vector<int>> dp(m,vector<int>(n));
        dp[0][0]=grid[0][0];
        for(int i=1;i<m;i++) dp[i][0]=dp[i-1][0]+grid[i][0];
        for(int i=1;i<n;i++) dp[0][i]=dp[0][i-1]+grid[0][i];
        for(int i=1;i<m;i++){
    
    
            for(int j=1;j<n;j++){
    
    
                dp[i][j]=min(dp[i-1][j]+grid[i][j],dp[i][j-1]+grid[i][j]);
            }
        }
        return dp[m-1][n-1];
    }
};

66:加一

在这里插入图片描述
逻辑很简单,但是需要想清楚,就是对每一位判断是否等于9

class Solution {
    
    
public:
    vector<int> plusOne(vector<int>& digits) {
    
    
        int a=0;
        if(digits[digits.size()-1]<9) {
    
    
            digits[digits.size()-1]++;
            return digits;
        }
        else {
    
    
            for(int i=digits.size()-1;i>=0;i--){
    
    
            if(digits[i]==9) {
    
    
                digits[i]=0;
            }
            else {
    
    
                digits[i]++;
                return digits;
            }
        }
        vector<int> result(digits.size()+1);
        result[0]=1;
        return result;
        }
    }
};

69:x的平方根

在这里插入图片描述
二分查找
注意类型,可能x值比较大,那么最开始迭代会出现超过Int型,使用long

class Solution {
    
    
public:
    int mySqrt(int x) {
    
    
        if(x==0||x==1) return x;
        int le=1,ri=x,ans=0;
        while(ri>=le){
    
    
            int mid=le+(ri-le)/2;
            if((long long)mid*mid==x) return mid;
            if((long long)mid*mid<x) {
    
    
                le=mid+1;
                ans=mid;
            }
            else ri=mid-1;
        }
        return ans;
    }
};

或者使用指数形式

class Solution {
    
    
public:
    int mySqrt(int x) {
    
    
        if (x == 0) {
    
    
            return 0;
        }
        int ans = exp(0.5 * log(x));
        return ((long long)(ans + 1) * (ans + 1) <= x ? ans + 1 : ans);
    }
};


70:爬楼梯

在这里插入图片描述
动态规划

class Solution {
    
    
public:
    int climbStairs(int n) {
    
    
        vector<int> dp(n+1);
        if(n==1) return 1;
        dp[1]=1;
        dp[2]=2;
        for(int i=3;i<=n;i++){
    
    
            dp[i]=dp[i-2]+dp[i-1];
        }
        return dp[n];
    }
};

简化:注意循环不能与变量使用一个参数!!!

class Solution {
    
    
public:
    int climbStairs(int n) {
    
    
        int i=0,j=1,a=0;
        for(int k=1;k<=n;k++){
    
    
            a=i+j;
            i=j;
            j=a;
        }
        return a;
    }
};

75:颜色分类

在这里插入图片描述
使用库函数

class Solution {
    
    
public:
    void sortColors(vector<int>& nums) {
    
    
        sort(nums.begin(),nums.end());
    }
};

使用两次循环求解

class Solution {
    
    
public:
    void sortColors(vector<int>& nums) {
    
    
        int i=0,j=0;
        while(j<nums.size()){
    
    
            if(nums[j]==0){
    
    
                swap(nums[i],nums[j]);
                i++;
            }
            j++;
        }
        j=i;
        while(j<nums.size()){
    
    
            if(nums[j]==1){
    
    
                swap(nums[i],nums[j]);
                i++;
            }
            j++;
        }
    }
};

78:子集

在这里插入图片描述
回溯法,记录所有节点,剩余集合为空则是叶子节点,可以返回。即index大于数组长度

class Solution {
    
    
public:
    vector<vector<int>> result;
    vector<int> path;
    void backtravel(vector<int>& nums,int index){
    
    
        result.push_back(path);
        if(index>nums.size()-1) return;
        for(int i=index;i<nums.size();i++){
    
    
            path.push_back(nums[i]);
            backtravel(nums,i+1);
            path.pop_back();
        }
    }
    vector<vector<int>> subsets(vector<int>& nums) {
    
    
        backtravel(nums,0);
        return result;
    }
};

79:单词搜索

在这里插入图片描述
使用递归回溯,注意使用数组判断是否使用过
注意vector初值赋值方式。注意:::可能有好几个第一个数值,一定要确定所有情况都考虑

class Solution {
    
    
public:
    bool exist(vector<vector<char>>& board, string word) {
    
    
        rows = board.size(), columns = board[0].size();
        for(int i = 0; i < rows; i++) {
    
    
            for (int j = 0; j < columns; j++) {
    
    
                if (backtrack(board, word, i, j, 0)) return true; // 每个格子都进行回溯判断
            }
        }
        return false;
    }

private:
    int rows, columns;
    bool backtrack(vector<vector<char>>& board, string& word, int x, int y, int index) {
    
    
        // 结束条件
        // 越界或者当前字母位不相等
        if (x >= rows || x < 0 || y >= columns || y < 0 || board[x][y] != word[index]) {
    
    
            return false;
        }
        // 最后一个字母也相等,返回成功
        if (index == word.size() - 1){
    
    
            return true;
        }
        // 避免重复使用
        board[x][y] = ' ';  
        // 回溯
        if (backtrack(board, word, x - 1, y, index + 1)
        || backtrack(board, word, x + 1, y, index + 1)
        || backtrack(board, word, x, y - 1, index + 1) 
        || backtrack(board, word, x, y + 1, index + 1)) 
        {
    
    
            return true;
        }
        // 如果不通,回溯至上一个状态
        board[x][y] = word[index];
        return false;
    }
};

83:删除排序链表中的重复元素

在这里插入图片描述
注意考虑情况!!!要判断

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* deleteDuplicates(ListNode* head) {
    
    
        if(head==NULL) return head;
        ListNode* slow=head;
        while(slow&&slow->next){
    
    
            if(slow->val==slow->next->val){
    
    
                slow->next=slow->next->next;
            }
            else slow=slow->next;
        }
        return head;
    }
};

86:分隔链表

在这里插入图片描述
两个头结点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* partition(ListNode* head, int x) {
    
    
        ListNode* small=new ListNode(0);
        ListNode* smallnode=small;
        ListNode* large=new ListNode(0);
        ListNode* largenode=large;
        while(head){
    
    
            if(head->val<x){
    
    
                smallnode->next=head;
                smallnode=smallnode->next;
            }
            else {
    
    
                largenode->next=head;
                largenode=largenode->next;
            }
            head=head->next;
        }
        smallnode->next=large->next;
        largenode->next=NULL;
        return small->next;
    }
};

88:合并两个有序数组

在这里插入图片描述

class Solution {
    
    
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
    
    
        int i=m-1;
        int j=n-1;
        int l=m+n-1;
        while(i>=0||j>=0){
    
    
            if(i==-1) {
    
    
                nums1[l]=nums2[j];
                j--;
            }
            else if(j==-1){
    
    
                nums1[l]=nums1[i];
                i--;
            }
            else if(nums1[i]>nums2[j]){
    
    
                nums1[l]=nums1[i];
                i--;
            }
            else if(nums1[i]<=nums2[j]){
    
    
                nums1[l]=nums2[j];
                j--;
            }
            l--;
        }


    }
};

92:反转链表

在这里插入图片描述
递归

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* travel(ListNode* pre1,ListNode* node){
    
    
        if(node==NULL) return pre1;
        ListNode* cur=node->next;
        node->next=pre1;
        return travel(node,cur);
    }
    ListNode* reverseBetween(ListNode* head, int left, int right) {
    
    
        if(head==NULL) return head;
        ListNode* dummy=new ListNode(0);
        dummy->next=head;
        ListNode* pre=dummy;
        int m=right-left+1;
        for(int i=1;i<left;i++){
    
    
            pre=pre->next;
        }
        ListNode* later=pre;
        for(int i=0;i<m;i++){
    
    
            later=later->next;
        }
        ListNode* l=pre->next;
        ListNode* curr=later->next;
        pre->next=NULL;
        later->next=NULL;
        pre->next=travel(NULL,l);
        l->next=curr;
        return dummy->next;
    }
};

迭代

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* reverseBetween(ListNode* head, int left, int right) {
    
    
        int m=right-left+1;
        ListNode *pre=NULL;
        ListNode* result=head;
        while(head&&--left){
    
    
            pre=head;
            head=head->next;
        }
        ListNode* tail=head;
        ListNode* new1=NULL;
        while(head&&m){
    
    
            ListNode* cur=head->next;
            head->next=new1;
            new1=head;
            head=cur;
            m--;
        }
        tail->next=head;
        if(pre) pre->next=new1;
        else result=new1;
        return result;

    }
};

141:环形链表

在这里插入图片描述
快慢指针

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    
    
public:
    bool hasCycle(ListNode *head) {
    
    
        if(head==NULL) return false;
        ListNode* fast=head;
        ListNode* slow=head;
        while(fast!=NULL&&fast->next!=NULL){
    
    
            fast=fast->next->next;
            slow=slow->next;
            if(fast==slow) return true;
        }
        return false;        
    }
};

96:不同的二叉搜索树

在这里插入图片描述
动态规划!dp[i]为i对应的二叉搜索树的数量,j为遍历头结点数量

class Solution {
    
    
public:
    int numTrees(int n) {
    
    
        vector<int> dp(n+1);
        dp[0]=1;
        for(int i=1;i<=n;i++){
    
    
            for(int j=1;j<=i;j++){
    
    
                dp[i]+=dp[j-1]*dp[i-j];
            }
        }
        return dp[n];
    }
};

142:环形链表2

在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    
    
public:
    ListNode *detectCycle(ListNode *head) {
    
    
        int pose=0;
        ListNode* fast=head;
        ListNode* slow=head;
        while(fast!=NULL&&fast->next!=NULL){
    
    
            slow=slow->next;
            fast=fast->next->next;
            if(slow==fast){
    
    
                ListNode* index1=fast;
                ListNode* index2=head;
                while(index1!=index2){
    
    
                    index1=index1->next;
                    index2=index2->next;
                }
                return index1;


            }
        }
        return NULL;
        
    }
};

144:前序遍历二叉树

在这里插入图片描述

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    
    
public:
    void travel(TreeNode* node,vector<int>& ans){
    
    
        if(node==NULL) return;
        ans.push_back(node->val);
        travel(node->left,ans);
        travel(node->right,ans);
    }
    vector<int> preorderTraversal(TreeNode* root) {
    
    
        vector<int> ans;
        if(root==NULL) return ans;
        travel(root,ans);
        return ans;

    }
};

160:相交链表

在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    
    
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    
    
        set<ListNode*> m;
        while(headA){
    
    
            m.insert(headA);
            headA=headA->next;
        }
        while(headB){
    
    
            if(m.find(headB)!=m.end()) return headB;
            headB=headB->next;
        }
        return NULL;        
    }
};

优化:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    
    
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    
    
        int a=0,b=0;
        ListNode* headA1=headA;
        ListNode* headB1=headB;
        while(headA1){
    
    
            headA1=headA1->next;
            a++;
        }
        while(headB1){
    
    
            headB1=headB1->next;
            b++;
        }
        if(a<b) {
    
    
            for(int i=0;i<b-a;i++) headB=headB->next;
        }
        else for(int i=0;i<a-b;i++) headA=headA->next;
        while(headA&&headB){
    
    
            if(headA==headB) return headA;
            headA=headA->next;
            headB=headB->next;
        }
        return NULL;
        
    }
};

206:反转链表

在这里插入图片描述
使用递归

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* travel(ListNode* pre,ListNode* cur){
    
    
        if(cur==NULL) return pre;
        ListNode* node=cur->next;
        cur->next=pre;
        return travel(cur,node);
    }
    ListNode* reverseList(ListNode* head) {
    
    
        if(head==NULL) return head;
        ListNode* node=travel(NULL,head);
        return node;
    }
};

使用迭代

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* reverseList(ListNode* head) {
    
    
        ListNode* pre=NULL;
        while(head){
    
    
            ListNode* node=head->next;
            head->next=pre;
            pre=head;
            head=node;
        }
        return pre;
    }
};

226:反转二叉树

在这里插入图片描述
也可以直接使用swap

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    
    
public:
    void travel(TreeNode* node){
    
    
        if(node==NULL) return ;
        TreeNode* cur=node->left;
        node->left=node->right;
        node->right=cur;
        travel(node->left);
        travel(node->right);

    }
    TreeNode* invertTree(TreeNode* root) {
    
    
        if(root==NULL) return root;
        travel(root);
        return root;
    }
};

239:滑动窗口最大值

在这里插入图片描述

class Solution {
    
    
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
    
    
        vector<int> ans;
        int s=INT_MIN;
        if(nums.size()==0) return ans;
        for(int i=0;i<=nums.size()-k;i++){
    
    
            s=INT_MIN;
            for(int j=0;j<k;j++){
    
    
                s=max(s,nums[i+j]);
            }
            ans.push_back(s);
        }
        return ans;
    }
};

使用优先队列,避免超过时间限制

class Solution {
    
    
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
    
    
        vector<int> ans;
        int m=nums.size();
        priority_queue<pair<int,int>> q;
        for(int i=0;i<k;i++){
    
    
            q.emplace(nums[i],i);
        }
        ans.push_back(q.top().first);
        for(int i=k;i<m;i++){
    
    
            q.emplace(nums[i],i);
            while(q.top().second<i-k+1){
    
    
                q.pop();
            }
            ans.push_back(q.top().first);
        }
        return ans;
    }
};

255:用队列实现栈

在这里插入图片描述

class MyStack {
    
    
public:
    queue<int> que1;
    queue<int> que2;
    /** Initialize your data structure here. */
    MyStack() {
    
    

    }
    
    /** Push element x onto stack. */
    void push(int x) {
    
    
        que1.push(x);
    }
    
    /** Removes the element on top of the stack and returns that element. */
    int pop() {
    
    
        if(que1.empty()) return -1;
        int m=que1.size();
        for(int i=0;i<m-1;i++){
    
    
            int x=que1.front();
            que1.pop();
            que2.push(x);
        }
        int x=que1.front();
        que1.pop();
        que1=que2;
        while(!que2.empty()){
    
    
            que2.pop();
        }
        return x;
    }
    
    /** Get the top element. */
    int top() {
    
    
        return que1.back();

    }
    
    /** Returns whether the stack is empty. */
    bool empty() {
    
    
        return que1.empty();

    }
};

/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack* obj = new MyStack();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->top();
 * bool param_4 = obj->empty();
 */

322:零钱兑换

在这里插入图片描述
动态规划问题

343:整数拆分

在这里插入图片描述
动态规划,注意!!!一定要观察,dp[i]是对i进行拆分的最大乘积,找到对应的递推关系

class Solution {
    
    
public:
    int integerBreak(int n) {
    
    
        vector<int> dp(n+1);
        dp[2]=1;
        for(int i=3;i<=n;i++){
    
    
            for(int j=1;j<i-1;j++){
    
    
                dp[i]=max(dp[i],max(j*(i-j),j*dp[i-j]));
            }
        }
        return dp[n];
    }
};

**

232:用栈实现队列

**
在这里插入图片描述

class MyQueue {
    
    
public:
    stack<int> stk1;
    stack<int> stk2;
    /** Initialize your data structure here. */
    MyQueue() {
    
    

    }
    
    /** Push element x to the back of queue. */
    void push(int x) {
    
    
        stk1.push(x);

    }
    
    /** Removes the element from in front of queue and returns that element. */
    int pop() {
    
    
        if(stk2.empty()) {
    
    
            while(!stk1.empty()){
    
    
                stk2.push(stk1.top());
                stk1.pop();
            }
        }
        int x=stk2.top();
        stk2.pop();
        return x;

    }
    
    /** Get the front element. */
    int peek() {
    
    
        if(stk2.empty()) {
    
    
            while(!stk1.empty()){
    
    
                stk2.push(stk1.top());
                stk1.pop();
            }
        }
        int x=stk2.top();
        return x;

    }
    
    /** Returns whether the queue is empty. */
    bool empty() {
    
    
        return stk1.empty()&&stk2.empty();

    }
};

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue* obj = new MyQueue();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->peek();
 * bool param_4 = obj->empty();
 */

509:斐波那契数

在这里插入图片描述
使用动态规划,注意一定要看边界,要么dp设置大点要么判断n为0情况

class Solution {
    
    
public:
    int fib(int n) {
    
    
        vector<int> dp(n+5);
        dp[0]=0;
        dp[1]=1;
        for(int i=2;i<=n;i++){
    
    
            dp[i]=dp[i-1]+dp[i-2];
        }
        return dp[n];
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_41169280/article/details/114777863