第一次做这道题的时候根据标签🏷很容易想到了BFS的解法,而第二次看的时候却想不起来了。将动态规划应用于这道题的时候,使用的小技巧「看似遍历但实则复杂度并不大」。
问题描述
Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, …) which sum to n.
Example:1
2
3Input: n = 13
Output: 2
Explanation: 13 = 4 + 9.
解法
BFS
这个我第二次遇到的时候已经想不起来的 BFS 确实很有意思。它将 0..n 作为树节点,将问题转化为求 n 到 0 的最短路径。而 BFS 的一类应用就是最短路径求解。以节点 0 为例,它的相邻边有 1, 4, 9, … 当然,过大的节点我们实际是不需要考虑的。
实际代码中,便利方向为 n -> 0。这样,当遍历到 i 时,只需考虑 1..sqrt(i),将它们加入队列即可。
1 | public int numSquares(int n) { |
动态规划
动态规划的思路是:dp[0..n] 中的 dp[i] 表示平方数之和为 i 的最小数目。也即,从 0 遍历到 n 后,dp[n] 即为所求结果,在这一过程中,每个步骤需要计算 dp[i] 都需要借助已经计算好的数字。例如,计算 dp[18] 时,需要找到 {dp[18 - 1], dp[18 - 4], dp[18 - 9], dp[18 - 16]} 中的最小值。
1 | class Solution { |