leetcode279.完全平方数

题目大意:

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

示例 1:

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

示例 2:

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

解题思路:

方法一:

四平方定理(不太了解emmm)。

class Solution {
public:
    int numSquares(int n) {
        while (0 == n % 4) n /= 4;
        if (7 == n % 8) return 4;
        for (int i = 0; i * i < n; ++i) {
            int j = pow(n - i * i, 0.5);
            if (n == i * i + j * j) return !!i + !!j;
        }
        return 3;
    }
};
方法二:

可以看做是背包问题进行求解:假设n=13,则找到小于等于n的完全平方数,分别是1,4,9。这三个数可以看作是货物的价值,货物的重量是1.
因此题目转化为:给定货物价值和重量,求当背包装满时的最小重量。

class Solution {
public:
    int numSquares(int n) {
    	if (n < 4)
    		return n;
    	sqrtNum = int(sqrt(n));
    	vector<int> squareNums;
    	for (int i = 1; i <= sqrtNum; ++i)
    		squareNums.push_back(i * i);

    	vector<int> dp(n + 1, 0);
    	for (int i = 0; i < dp.size(); ++i){
    		dp[i] = i;
    	}

    	for (int i = 1; i < squareNums.size(); ++i){
    		for(int j = 1; j < dp.size(); ++j){
    			if (squareNums[i] - j >= 0){
    				dp[j] = min(dp[j], dp[squareNums[i] - j] + 1);
    			}
    		}
    	}
    	return dp.back();
    }
};
方法三:

改进上述版本,不需要显式地求出每个n包含的完全平方数。

class Solution {
public:
    int numSquares(int n) {
    	if (n < 4)
    		return n;

    	vector<int> nums(n + 1, INT_MAX);
    	nums[0] = 0;
    	nums[1] = 1;

    	for (int i = 0; i < nums.size(); ++i){
    		for(int j = 1; j * j <= i; ++j){
    			nums[i] = min(nums[i], nums[i - j * j] + 1);
    		}
    	}

    	return nums.back();
    }
};

猜你喜欢

转载自blog.csdn.net/qq_41092190/article/details/105965099