LeetCode之二 动态规划

39.组合总和
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的数字可以无限制重复被选取。

说明:

所有数字(包括 target)都是正整数。
解集不能包含重复的组合。
示例 1:

输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]
思路:深度优先遍历

class Solution {
public:
    void backtrade(vector<int> candidates,int start,int target,vector<int> item,vector<vector<int>>& res)
    {
        if(target<0)
            return;
        if(target == 0)
        {
            res.push_back(item);
            return;
        }
        for (int i = start; i < candidates.size(); i++)
        {
            item.push_back(candidates[i]);
            backtrade(candidates, i, target - candidates[i], item, res);
            item.pop_back();
        }    
    }
    
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<vector<int>> res;
        vector<int> item;
        backtrade(candidates,0,target,item,res);
        return res;
    }
};

40.组合总和II
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用一次。

说明:

所有数字(包括目标数)都是正整数。
解集不能包含重复的组合。
示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]

class Solution {
public:
    void backtrade(vector<int> candidates,int start,int target,vector<int> item,vector<vector<int>>& res)
    {
        if(target<0)
            return;
        if(target == 0)
        {
            res.push_back(item);
            return;
        }
        for (int i = start; i < candidates.size(); i++)
        {
            //vector<int>::iterator it;
            //it=candidates.begin()+i;
            //while(i < candidates.size()-1 && candidates[i] == candidates[i-1])
             //       i++;
            item.push_back(candidates[i]);
            //candidates.erase(it);
            backtrade(candidates, i+1, target - candidates[i], item, res);
            item.pop_back();
            while(i < candidates.size()-1 && candidates[i] == candidates[i+1])
                i = i + 1;
        }    
    }
    
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        vector<vector<int>> res;
        vector<int> item;
        sort(candidates.begin(),candidates.end());
        backtrade(candidates,0,target,item,res);
        return res;
    }
};

70.爬楼梯
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 是一个正整数。
输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。

  1. 1 阶 + 1 阶 + 1 阶
  2. 1 阶 + 2 阶
  3. 2 阶 + 1 阶
    思路:动态规划斐波那契数列 另外别用递归一定超时
class Solution {
public:
    int climbStairs(int n) {
        int* a = new int[n+1];
        a[0] = 1;
        a[1] = 2;
        for(int i = 2;i < n;i++){
            a[i] = a[i - 1] + a[i - 2];
        }
       return a[n-1]; 
    }
};

121.买卖股票的最佳时机
示例 1:

输入: [7, 1, 5, 3, 6, 4]
输出: 5

最大利润 = 6-1 = 5(不是 7-1 = 6, 因为卖出价格需要大于买入价格)
思路1:遍历价格遇到最小的数便存下来(buy)与之后的价格做差与(result)比较
思路2:写一个相邻两数差的数组 找到最大子序和(未验证)

class Solution {
public:
	int maxProfit(vector<int>& prices) {
		int result = 0;
		int buy = INT_MAX;
		for (int price : prices) {
			buy = min(buy, price);
			result = max(result, price - buy);
		}
		return result;   
    }
};

198.打家劫舍
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。
思路:类似斐波那契数列,当前位置的最大是前一个与前二个位置加当前值中的最大

class Solution {
public:
    int rob(vector<int>& nums) {
        int n = nums.size();
        if(n < 1)
            return 0;
        int* a = new int[n];
        a[0] = nums[0];
        a[1] = max(nums[0], nums[1]);
        int i = 2;
        while(i < n){
            a[i] = max(a[i-1], a[i-2] + nums[i]);
            i++;
        }
        return a[n-1];
    }
    
    int max(int a, int b){
        int max = 0;
        max = a>b?a:b;
        return max;
    }
};

204.计数质数
统计所有小于非负整数 n 的质数的数量。

示例:

输入: 10
输出: 4
解释: 小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。
思路:声明一个全为1的数组,然后以2为因子遍历数组,3, 4(已经被2遍历了)5……

class Solution {
public:
    int countPrimes(int n) {
    if (n < 0)
        return 0;
	int* a = new int[n];
	int num = 0, sum = 0;
	for (int i = 0; i < n; i++)
		a[i] = 1; 
	a[0] = 0;
	for (int j = 0; j < n; j++) {
		if (a[j] == 1) {
			int end_num = j;
			while (end_num + j + 1 < n){
				a[end_num + j + 1] = 0;
				end_num = end_num + j + 1;
			}
		}
	}

	while (num < n - 1) {
		sum = sum + a[num];
		num++;
	}
	return sum;
}
};

279.完全平方数
给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, …)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。

示例 1:

输入: n = 12
输出: 3
解释: 12 = 4 + 4 + 4.
思路:动态规划

class Solution {
public:
    int numSquares(int n) {
    	//前n+1个用 max赋值
        vector<int> dp(n + 1, INT_MAX);
        for(int i = 1; i * i <= n; i++)
            dp[i * i] = 1;
        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];
    }
};

263.丑数

编写一个程序判断给定的数是否为丑数。

丑数就是只包含质因数 2, 3, 5 的正整数。

示例 1:

输入: 6
输出: true
解释: 6 = 2 × 3
把一个数除到不包含2再去除3这样

class Solution {
public:
    bool isUgly(int num) {
        if (num <= 0)
            return false;
        while(num % 2 == 0)
            num = num / 2;
        while(num % 3 == 0)
            num = num / 3;
        while(num % 5 == 0)
            num = num / 5;
        if (num == 1)
            return true;
        return false;    
    }
};

264.丑数II
编写一个程序,找出第 n 个丑数。

丑数就是只包含质因数 2, 3, 5 的正整数。
示例:

输入: n = 10
输出: 12
解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 个丑数。

1.声明长度为n的数组
2.a[0] = 1
3.动态规划每个因子都乘当前所对应数i,j,k
4.如果是得出是最小则对应的数+1

class Solution {
public:
    int minNum(int i, int j, int k){
        int temp=0;
        temp = i > j ? j:i;
        temp = temp > k ? k:temp;
        return temp;
    }
    
    int nthUglyNumber(int n) {
        int* a=new int[n];
        int i=0,j=0,k=0;
        a[0] = 1;
        for(int q=1;q<n;q++){
            a[q] = minNum(a[i]*2, a[j]*3, a[k]*5);
            if(a[q]==a[i]*2)i++;
            if(a[q]==a[j]*3)j++;
            if(a[q]==a[k]*5)k++;
        }
        return a[n-1];
    }
};

313.超级丑数

编写一段程序来查找第 n 个超级丑数。

超级丑数是指其所有质因数都是长度为 k 的质数列表 primes 中的正整数。

示例:

输入: n = 12, primes = [2,7,13,19]
输出: 32
解释: 给定长度为 4 的质数列表 primes = [2,7,13,19],前 12 个超级丑数序列为:[1,2,4,7,8,13,14,16,19,26,28,32] 。

class Solution {
public:    
    int nthSuperUglyNumber(int n, vector<int>& primes) {
        int* a = new int[n];
        int len = primes.size();
        int* index = new int[len];
        int i=0;
        while(i<len){
            index[i]=0;
            i++;
        }
        a[0] = 1;
        for(int q=1;q<n;q++){
            int min = INT_MAX;
            for(int p=0;p<len;p++){
                min = primes[p]*a[index[p]] < min ? primes[p]*a[index[p]]:min;
            }
            a[q] = min;
            for(int p=0;p<len;p++){
                if(min == primes[p]*a[index[p]])index[p]++;
            }
        }
        return a[n-1];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值