完全平方数

给你一个整数 n ,返回 和为 n 的完全平方数的最少数量 。

完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,149 和 16 都是完全平方数,而 3 和 11 不是。279. 完全平方数 - 力扣(LeetCode)

示例 1:

输入:n = 12
输出:3 
解释:12 = 4 + 4 + 4

示例 2:

输入:n = 13
输出:2
解释:13 = 4 + 9

解法

/*动态规划
状态dp[i]:和为i的完全平方数的最少数量
状态转移:dp[i] = min(dp[i-j^2] + 1), j^2 <= i
初始化:dp[0] = 0

接下来要确定存储结构:
一个vector<int>存储dp[i]
一个vector<int>存储平方数
*/


class Solution {
public:
    int numSquares(int n) {
        //存储dp[i]
        vector<int> dp(n+1, INT_MAX);
        //存储平方数
        vector<int> squares;
        for(int j = 1; j*j <= n; j++){
            squares.push_back(j*j);
        }

        //初始化dp
        dp[0] = 0;

        //开始状态转移,从小到大
        for(int i = 1; i <= n; i++){
            for(int sq: squares){
                if(sq > i){
                    break;
                }
                dp[i] = min(dp[i], dp[i-sq] + 1);
            }
        }
        return dp[n];
    }
};

零钱兑换

给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。

计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。

你可以认为每种硬币的数量是无限的。322. 零钱兑换 - 力扣(LeetCode)

示例 1:

输入:coins = [1, 2, 5], amount = 11
输出:3 
解释:11 = 5 + 5 + 1

示例 2:

输入:coins = [2], amount = 3
输出:-1

示例 3:

输入:coins = [1], amount = 0
输出:0

解法

/*跟完全平方数一样
状态dp[i]:能够凑成i的最少硬币数
状态转移:dp[i] = min(dp[i-coin]+1), coin <= i
初始化:dp[0] = 0*/

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        vector<int> dp(amount + 1, INT_MAX);
        dp[0] = 0;
        for(int i = 1; i <= amount; i++){
            for(int coin: coins){
                if(coin > i){
                    //零钱数组可能没排序
                    continue;
                }
                if(dp[i-coin] != INT_MAX){
                    dp[i] = min(dp[i], dp[i-coin] + 1);
                }
            }
        }

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

全排列——回溯

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。46. 全排列 - 力扣(LeetCode)

示例 1:

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

示例 2:

输入:nums = [0,1]
输出:[[0,1],[1,0]]

示例 3:

输入:nums = [1]
输出:[[1]]

解法

//深搜
class Solution {
public:
    vector<vector<int>> permute(vector<int>& nums) {
        vector<int> tmp;
        vector<vector<int>> result;
        dfs(nums, tmp, result);
        return result;
    }

    void dfs(vector<int>& nums, vector<int> tmp, vector<vector<int>>& result){
        //如果满足返回条件,将当前临时数组中的元素加入到结果集并返回
        if(tmp.size() == nums.size()){
            result.push_back(tmp);
            return;
        }

        //如果没有满足返回条件
        //遍历当前数组
        for(int i = 0; i < nums.size(); i++){
            int j;
            for(j = 0; j < tmp.size(); j++){
                //如果当前元素在tmp数组中,跳过这一层循环
                if(tmp[j] == nums[i]){
                    break;
                }
            }
            
            //如果当前元素和tmp数组中的元素都不相等
            if(j == tmp.size()){
                //将当前元素加入tmp数组中
                tmp.push_back(nums[i]);

                //递归
                dfs(nums, tmp, result);

                //递归返回后,要恢复tmp数组的状态
                tmp.pop_back();
            }
        }
    }
};

更多推荐