完全平方数--力扣

Posted 穿迷彩服的鲨鱼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了完全平方数--力扣相关的知识,希望对你有一定的参考价值。


前言

给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, …)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
给你一个整数 n ,返回和为 n 的完全平方数的 最少数量 。
完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。


一、示例

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

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

提示:
1 <= n <= 104

二、代码解析

1.动态规划

代码如下(示例):

int numSquares(int n)
{
	vector<int> nums(n + 1, 0);// 默认初始化值都为0
	for (int i = 1; i <= n; i++)
	{
		// 最长的情况就是每次都为1相加
		nums[i] = i;
		// 对其更新
		for (int j = 1; j * j <= i; ++j)
		{
			nums[i] = min(nums[i], nums[i - j * j] + 1);//动态转移方程
		}
	}
	return nums[n];
}

结果

在这里插入图片描述

2.四平方和定理

代码如下(示例):

int numSquares(int n)
{
	//四平方定理。
	/*
	* 四平方定理讲的就是任何一个正整数都可以表示成不超过四个整数的平方之和。
	* 也就是说,这道题的答案只有 1,2 ,3,4 这四种可能。
	* 同时,还有一个非常重要的推论满足四数平方和定理的数n必定满足 n = 4a * (8b + 7)
	* 根据这个重要的推论来解决此题,首先将输入的n迅速缩小。
	* 然后再判断,这个缩小后的数是否可以通过两个平方数的和或一个平方数组成,
	* 不能的话我们返回3,能的话我们返回平方数的个数。
	*/
	
	while (n % 4 == 0)//首先将输入的n迅速缩小。
	{
		n /= 4;
	}
	if (n % 8 == 7)/*此处计算四数平方和定理 n = 4a * (8b + 7)*/
	{
		return 4;
	}

	int a = 0;
	while ((a * a) <= n)
	{
		int b = (int)pow((n - a * a), 0.5);
		if (a * a + b * b == n)
		{
			if (a != 0 && b != 0)
			{
				return 2;
			}
			else
			{
				return 1;
			}
		}
		a++;
	}
	return 3;
}

结果

在这里插入图片描述

测试

代码如下(示例):

#include<vector>
#include <iostream>
using namespace std;

int numSquares(int n)
{
	//vector<int> nums(n + 1, n + 1);
	//nums[0] = 0;  // 方便计算自己是平方数的情况
	//for (int i = 1; i <= n; ++i)
	//{
	//	for (int j = 1; j * j <= i; ++j)
	//	{  // j*j==i 为自己是平方数的情况
	//		nums[i] = min(nums[i], nums[i - j * j] + 1);
	//	}
	//}
	//return nums[n];

	// 动态规划
	//vector<int> nums(n + 1, 0);// 默认初始化值都为0
	//for (int i = 1; i <= n; i++)
	//{
	//	// 最长的情况就是每次都为1相加
	//	nums[i] = i;
	//	// 对其更新
	//	for (int j = 1; j * j <= i; ++j)
	//	{
	//		nums[i] = min(nums[i], nums[i - j * j] + 1);//动态转移方程
	//	}
	//}
	//return nums[n];

	//四平方定理。
	/*
	* 四平方定理讲的就是任何一个正整数都可以表示成不超过四个整数的平方之和。
	* 也就是说,这道题的答案只有 1,2 ,3,4 这四种可能。
	* 同时,还有一个非常重要的推论满足四数平方和定理的数n必定满足 n = 4a * (8b + 7)
	* 根据这个重要的推论来解决此题,首先将输入的n迅速缩小。
	* 然后再判断,这个缩小后的数是否可以通过两个平方数的和或一个平方数组成,
	* 不能的话我们返回3,能的话我们返回平方数的个数。
	*/
	
	while (n % 4 == 0)//首先将输入的n迅速缩小。
	{
		n /= 4;
	}
	if (n % 8 == 7)/*此处计算四数平方和定理 n = 4a * (8b + 7)*/
	{
		return 4;
	}

	int a = 0;
	while ((a * a) <= n)
	{
		int b = (int)pow((n - a * a), 0.5);
		if (a * a + b * b == n)
		{
			if (a != 0 && b != 0)
			{
				return 2;
			}
			else
			{
				return 1;
			}
		}
		a++;
	}
	return 3;
}

int main()
{
	cout << numSquares(12);
	return 0;
}

结果

在这里插入图片描述


总结

在这里插入图片描述

以上是关于完全平方数--力扣的主要内容,如果未能解决你的问题,请参考以下文章

再论力扣第279题--完全平方数

有效的完全平方数(力扣第367题)

有效的完全平方数(力扣第367题)

完全平方数

LeetCode试炼之路之:完全平方数

力扣(LeetCode)平方数之和 个人题解