力扣hot100 完全平方数 完全背包 滚动数组 四平方和定理

本文介绍了如何使用完全背包和滚动数组优化策略来解决完全平方数问题,展示了两种不同的解决方案,并分析了它们的时间复杂度。最后提及了四平方和定理在判断特定整数表示为两个平方数和的最少项数的应用。
摘要由CSDN通过智能技术生成

Problem: 279. 完全平方数
在这里插入图片描述

思路

👨‍🏫 三叶神解

👨‍🏫 数学解法

💖 完全背包

⏰ 时间复杂度: O ( n 2 n ) O(n^2 \sqrt{n}) O(n2n )

class Solution {
    int INF = 0x3f3f3f3f;
	public int numSquares(int n)
	{
		List<Integer> list = new ArrayList<>();
		int t = 1;
		while (t * t <= n)
		{
			list.add(t * t);
			t++;
		}
		int m = list.size();
		int[][] f = new int[m + 1][n + 1];// f[i][j] 表示考虑前 i 个物品,凑出 j 所使用的最小元素个数
		Arrays.fill(f[0], INF);// 在 0 个物品中选,除了价值 0 外都是非法情况
		f[0][0] = 0;

		for (int i = 1; i <= m; i++)
		{
			int x = list.get(i - 1);// x 表示当前物品的 价值
			for (int j = 0; j <= n; j++)
			{
				f[i][j] = f[i - 1][j];// 不选当前物品
				for (int k = 1; k * x <= j; k++)// 选取 k 个当前物品
					if (f[i - 1][j - k * x] != INF)
						f[i][j] = Math.min(f[i][j], f[i - 1][j - k * x] + k);
			}
		}
		return f[m][n];
	}
}

💖 滚动数组优化

⏰ 时间复杂度: O ( n n ) O(n\sqrt{n}) O(nn )在这里插入图片描述

class Solution {
	public int numSquares(int n)
	{
		int[] f = new int[n + 1];//f[i] 表示和为 i 的最小完全平方数和 的数量
		Arrays.fill(f, 0x3f3f3f3);
		f[0] = 0;
		for (int t = 1; t * t <= n; t++)
		{
			int x = t * t;
			for (int j = x; j <= n; j++)
				f[j] = Math.min(f[j], f[j - x] + 1);
		}
		return f[n];
	}
}

💖 四平方和定理

class Solution {
    public int numSquares(int n) {
        //判断是否是 1
        if (isSquare(n)) {
            return 1;
        }
        
        //判断是否是 4
        int temp = n;
        while (temp % 4 == 0) {
            temp /= 4;
        }
        if (temp % 8 == 7) {
            return 4;
        }

        //判断是否是 2
        for (int i = 1; i * i < n; i++) {
            if (isSquare(n - i * i)) {
                return 2;
            }
        }

        return 3;
    }

    //判断是否是平方数
    private boolean isSquare(int n) {
        int sqrt = (int) Math.sqrt(n);
        return sqrt * sqrt == n;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值