Leetcode 动态规划70 322 279 哈希表 454 383 15

动态规划--完全背包

70. Climbing Stairs

 

class Solution {
public:
    int climbStairs(int n) {
        vector<int> dp(n+1, 0);
        dp[0] = 1;

        for(int i=0; i<=n; i++){
            for(int j=1; j<=2; j++){
                if(i>=j)
                    dp[i] += dp[i-j];
            }
        }

        return dp[n];

    }
};

322. Coin Change

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        vector<int> dp(amount+1, INT_MAX);
        dp[0]=0;

        for(int i=0; i<coins.size(); i++){
            for(int j=coins[i]; j<=amount; j++){
                if(dp[j-coins[i]] != INT_MAX)
                    dp[j] = min(dp[j],dp[j-coins[i]]+1);
            }
        }

        if(dp[amount] == INT_MAX) return -1;
        return dp[amount];
    }
};

1.为了求得是最小值,dp数组初始化应为INT_MAX,dp[0] = 0 

2.要加上条件if 不等于最大值以及-1的情况

3.明确排列数和组合数的区别

排列数,在意顺序(不同顺序的算新一组),所以先背包,在物品

组合数,不在意顺序(比如(1,2)和(2,1)是同一组)所以先遍历物品,在遍历背包

279. Perfect Squares

1.先遍历物品,在遍历背包

class Solution {
public:
    int numSquares(int n) {
        vector<int> dp(n+1, INT_MAX);
        dp[0] = 0;
        int sq = sqrt(n);

        for(int i=1; i<= sq; i++){
            for(int j=i*i; j<=n; j++){
                if(dp[j-i*i] != INT_MAX){
                    dp[j] = min(dp[j], dp[j-i*i]+1);
                }
            }
        }
        return dp[n];
    }
};

2.先遍历背包,在遍历物品

class Solution {
public:
    int numSquares(int n) {
        vector<int> dp(n+1, INT_MAX);
        dp[0] = 0;

        for(int i=1; i<= n; i++){
            for(int j=1; j*j<=i; j++){
                dp[i] = min(dp[i], dp[i-j*j]+1);
            }
        }
        return dp[n];
    }
};

哈希表

454. 4Sum II

class Solution {
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
        unordered_map<int, int> record;
        for(int num1:nums1){
            for(int num2:nums2){
                record[num1+num2]++;
            }
        }

        int count = 0;

        for(int num3:nums3){
            for(int num4:nums4){
                if(record.find(-num3-num4) != record.end()){
                    count += record[-num3-num4];
                }
            }
        }

        return count;
    }
};

因为一种和肯能会出现多次,所以要用map-val记录出现的次数

383. Ransom Note

class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        int record[26]{0};

        for(char val:ransomNote){
            record[val- 'a']++;
        }

        for(char m:magazine){
            record[m-'a']--;
        }

        for(int i=0; i<26; i++){
            if(record[i] > 0)
                return false;
        }
        return true;
    }
};

15. 3Sum

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> res;
        sort(nums.begin(), nums.end());

        for(int i=0; i<nums.size(); i++){
            if(nums[i] > 0){
                return res;
            }
            if(i>0 && nums[i] == nums[i-1])
                continue;
            
            int left = i+1;
            int right = nums.size()-1;
            while(left < right){
                if(nums[i]+nums[left]+nums[right] > 0){
                    right --;
                }else if(nums[i]+nums[left]+nums[right] < 0){
                    left++;
                }else{
                    res.push_back(vector<int> {nums[i], nums[left], nums[right]});
                    while(left < right && nums[right] == nums[right-1]) right--;
                    while(left < right && nums[left] == nums[left+1]) left++;

                    right--;
                    left++;
                }
            }
        }

        return res;
    }
};

1.一定要注意去重

2.else里面要用while,因为有可能一直重复 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值