📜  总和等于给定数 n 的最小平方数

📅  最后修改于: 2021-09-22 10:26:03             🧑  作者: Mango

一个数总是可以表示为其他数的平方和。请注意,1 是一个正方形,我们总是可以将数字分解为 (1*1 + 1*1 + 1*1 + …)。给定一个数 n,求和为 X 的最小平方数。

例子 :

想法很简单,我们从 1 开始,找到一个平方小于或等于 n 的数字。对于每个数字 x,我们重复 nx。下面是递归公式。

If n = 1 and x*x <= n

下面是基于上述递归公式的简单递归解决方案。

C++
// A naive recursive C++
// program to find minimum
// number of squares whose sum
// is equal to a given number
#include 
using namespace std;
 
// Returns count of minimum
// squares that sum to n
int getMinSquares(unsigned int n)
{
    // base cases
    // if n is perfect square then
    // Minimum squares required is 1
    // (144 = 12^2)
    if (sqrt(n) - floor(sqrt(n)) == 0)
        return 1;
    if (n <= 3)
        return n;
 
    // getMinSquares rest of the
    // table using recursive
    // formula
    // Maximum squares required
    // is n (1*1 + 1*1 + ..)
    int res = n;
 
    // Go through all smaller numbers
    // to recursively find minimum
    for (int x = 1; x <= n; x++)
    {
        int temp = x * x;
        if (temp > n)
            break;
        else
            res = min(res, 1 + getMinSquares
                                  (n - temp));
    }
    return res;
}
 
// Driver code
int main()
{
    cout << getMinSquares(6);
    return 0;
}


Java
// A naive recursive JAVA
// program to find minimum
// number of squares whose
// sum is equal to a given number
class squares
{
     
    // Returns count of minimum
    // squares that sum to n
    static int getMinSquares(int n)
    {
         
        // base cases
        if (n <= 3)
            return n;
 
        // getMinSquares rest of the
        // table using recursive
        // formula
        // Maximum squares required is
        int res = n;
        // n (1*1 + 1*1 + ..)
 
        // Go through all smaller numbers
        // to recursively find minimum
        for (int x = 1; x <= n; x++)
        {
            int temp = x * x;
            if (temp > n)
                break;
            else
                res = Math.min(res, 1 +
                          getMinSquares(n - temp));
        }
        return res;
    }
   
    // Driver code
    public static void main(String args[])
    {
        System.out.println(getMinSquares(6));
    }
}
/* This code is contributed by Rajat Mishra */


Python
# A naive recursive Python program to
# find minimum number of squares whose
# sum is equal to a given number
 
# Returns count of minimum squares
# that sum to n
def getMinSquares(n):
 
    # base cases
    if n <= 3:
        return n;
 
    # getMinSquares rest of the table
    # using recursive formula
    # Maximum squares required
    # is n (1 * 1 + 1 * 1 + ..)
    res = n
 
    # Go through all smaller numbers
    # to recursively find minimum
    for x in range(1, n + 1):
        temp = x * x;
        if temp > n:
            break
        else:
            res = min(res, 1 + getMinSquares(n
                                  - temp))
     
    return res;
 
# Driver code
print(getMinSquares(6))
 
# This code is contributed by nuclode


C#
// A naive recursive C# program
// to find minimum number of
// squares whose sum is equal
// to a given number
using System;
 
class GFG
{
 
    // Returns count of minimum
    // squares that sum to n
    static int getMinSquares(int n)
    {
 
        // base cases
        if (n <= 3)
            return n;
 
        // getMinSquares rest of the
        // table using recursive
        // formula
 
        // Maximum squares required is
        // n (1*1 + 1*1 + ..)
        int res = n;
 
        // Go through all smaller numbers
        // to recursively find minimum
        for (int x = 1; x <= n; x++)
        {
            int temp = x * x;
            if (temp > n)
                break;
            else
                res = Math.Min(res, 1 +
                      getMinSquares(n - temp));
        }
        return res;
    }
 
    // Driver Code
    public static void Main()
    {
        Console.Write(getMinSquares(6));
    }
}
 
// This code is contributed by nitin mittal


PHP
 $n)
            break;
        else
            $res = min($res, 1 +
                       getMinSquares($n -
                                     $temp));
    }
    return $res;
}
 
// Driver Code
echo getMinSquares(6);
 
// This code is contributed
// by nitin mittal.
?>


Javascript


C++
// A dynamic programming based
// C++ program to find minimum
// number of squares whose sum
// is equal to a given number
#include 
using namespace std;
 
// Returns count of minimum
// squares that sum to n
int getMinSquares(int n)
{
    // We need to check base case
    // for n i.e. 0,1,2
    // the below array creation
    // will go OutOfBounds.
    if(n<=3)
      return n;
     
    // Create a dynamic
    // programming table
    // to store sq
    int* dp = new int[n + 1];
 
    // getMinSquares table
    // for base case entries
    dp[0] = 0;
    dp[1] = 1;
    dp[2] = 2;
    dp[3] = 3;
 
    // getMinSquares rest of the
    // table using recursive
    // formula
    for (int i = 4; i <= n; i++)
    {
         
        // max value is i as i can
        // always be represented
        // as 1*1 + 1*1 + ...
        dp[i] = i;
 
        // Go through all smaller numbers to
        // to recursively find minimum
        for (int x = 1; x <= ceil(sqrt(i)); x++)
        {
            int temp = x * x;
            if (temp > i)
                break;
            else
                dp[i] = min(dp[i], 1 +
                                  dp[i - temp]);
        }
    }
 
    // Store result and free dp[]
    int res = dp[n];
    delete[] dp;
 
    return res;
}
 
// Driver code
int main()
{
    cout << getMinSquares(6);
    return 0;
}


Java
// A dynamic programming based
// JAVA program to find minimum
// number of squares whose sum
// is equal to a given number
class squares
{
 
    // Returns count of minimum
    // squares that sum to n
    static int getMinSquares(int n)
    {
 
        // We need to add a check
        // here for n. If user enters
        // 0 or 1 or 2
        // the below array creation
        // will go OutOfBounds.
        if (n <= 3)
            return n;
 
        // Create a dynamic programming
        // table
        // to store sq
        int dp[] = new int[n + 1];
 
        // getMinSquares table for
        // base case entries
        dp[0] = 0;
        dp[1] = 1;
        dp[2] = 2;
        dp[3] = 3;
 
        // getMinSquares rest of the
        // table using recursive
        // formula
        for (int i = 4; i <= n; i++)
        {
         
            // max value is i as i can
            // always be represented
            // as 1*1 + 1*1 + ...
            dp[i] = i;
 
            // Go through all smaller numbers to
            // to recursively find minimum
            for (int x = 1; x <= Math.ceil(
                              Math.sqrt(i)); x++)
            {
                int temp = x * x;
                if (temp > i)
                    break;
                else
                    dp[i] = Math.min(dp[i], 1
                                  + dp[i - temp]);
            }
        }
 
        // Store result and free dp[]
        int res = dp[n];
 
        return res;
    }
   
    // Driver Code
    public static void main(String args[])
    {
        System.out.println(getMinSquares(6));
    }
} /* This code is contributed by Rajat Mishra */


Python3
# A dynamic programming based Python
# program to find minimum number of
# squares whose sum is equal to a
# given number
from math import ceil, sqrt
 
# Returns count of minimum squares
# that sum to n
def getMinSquares(n):
 
    # Create a dynamic programming table
    # to store sq and getMinSquares table
    # for base case entries
    dp = [0, 1, 2, 3]
 
    # getMinSquares rest of the table
    # using recursive formula
    for i in range(4, n + 1):
         
        # max value is i as i can always
        # be represented as 1 * 1 + 1 * 1 + ...
        dp.append(i)
 
        # Go through all smaller numbers
        # to recursively find minimum
        for x in range(1, int(ceil(sqrt(i))) + 1):
            temp = x * x;
            if temp > i:
                break
            else:
                dp[i] = min(dp[i], 1 + dp[i-temp])
 
    # Store result
    return dp[n]
 
# Driver code
print(getMinSquares(6))
 
# This code is contributed by nuclode


C#
// A dynamic programming based
// C# program to find minimum
// number of squares whose sum
// is equal to a given number
using System;
 
class squares
{
 
    // Returns count of minimum
    // squares that sum to n
    static int getMinSquares(int n)
    {
 
        // We need to add a check here
        // for n. If user enters 0 or 1 or 2
        // the below array creation will go
        // OutOfBounds.
 
        if (n <= 3)
            return n;
 
        // Create a dynamic programming
        // table to store sq
        int[] dp = new int[n + 1];
 
        // getMinSquares table for base
        // case entries
        dp[0] = 0;
        dp[1] = 1;
        dp[2] = 2;
        dp[3] = 3;
 
        // getMinSquares for rest of the
        // table using recursive formula
        for (int i = 4; i <= n; i++)
        {
         
            // max value is i as i can
            // always be represented
            // as 1 * 1 + 1 * 1 + ...
            dp[i] = i;
 
            // Go through all smaller numbers to
            // to recursively find minimum
            for (int x = 1; x <= Math.Ceiling(
                              Math.Sqrt(i)); x++)
            {
                int temp = x * x;
                if (temp > i)
                    break;
                else
                    dp[i] = Math.Min(dp[i], 1 +
                                    dp[i - temp]);
            }
        }
 
        // Store result and free dp[]
        int res = dp[n];
 
        return res;
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        Console.Write(getMinSquares(6));
    }
}
 
// This code is contributed by Nitin Mittal.


PHP
 $i)
                break;
            else $dp[$i] = min($dp[$i],
                       (1 + $dp[$i - $temp]));
        }
    }
 
    // Store result
    // and free dp[]
    $res = $dp[$n];
 
    // delete $dp;
    return $res;
}
 
// Driver Code
echo getMinSquares(6);
     
// This code is contributed
// by shiv_bhakt.
?>


Javascript


C++
#include 
using namespace std;
 
int minCount(int n)
 
{
 
    int* minSquaresRequired = new int[n + 1];
 
    minSquaresRequired[0] = 0;
 
    minSquaresRequired[1] = 1;
 
    for (int i = 2; i <= n; ++i)
 
    {
 
        minSquaresRequired[i] = INT_MAX;
 
        for (int j = 1; i - (j * j) >= 0; ++j)
 
        {
 
            minSquaresRequired[i]
                = min(minSquaresRequired[i],
                      minSquaresRequired[i - (j * j)]);
        }
 
        minSquaresRequired[i] += 1;
    }
 
    int result = minSquaresRequired[n];
 
    delete[] minSquaresRequired;
 
    return result;
}
 
// Driver code
int main()
{
    cout << minCount(6);
    return 0;
}


C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to count minimum
// squares that sum to n
int numSquares(int n)
{
  
  // Creating visited vector
  // of size n + 1
  vector visited(n + 1,0);
   
  // Queue of pair to store node
  // and number of steps
  queue< pair >q;
   
  // Initially ans variable is
  // initialized with inf
  int ans = INT_MAX;
   
  // Push starting node with 0
  // 0 indicate current number
  // of step to reach n
  q.push({n,0});
   
  // Mark starting node visited
  visited[n] = 1;
  while(!q.empty())
  {
    pair p;
    p = q.front();
    q.pop();
 
    // If node reaches its destination
    // 0 update it with answer
    if(p.first == 0)
      ans=min(ans, p.second);
 
    // Loop for all possible path from
    // 1 to i*i <= current node(p.first)
    for(int i = 1; i * i <= p.first; i++)
    {
       
      // If we are standing at some node
      // then next node it can jump to will
      // be current node-
      // (some square less than or equal n)
      int path=(p.first - (i*i));
 
      // Check if it is valid and
      // not visited yet
      if(path >= 0 && ( !visited[path]
                             || path == 0))
      {
         
        // Mark visited
        visited[path]=1;
         
        // Push it it Queue
        q.push({path,p.second + 1});
      }
    }
  }
   
  // Return ans to calling function
  return ans;
}
 
// Driver code
int main()
{
  cout << numSquares(12);
  return 0;
}


Java
// Java program for the above approach
import java.util.*;
import java.awt.Point;
class GFG
{
  // Function to count minimum
  // squares that sum to n
  public static int numSquares(int n)
  {
 
    // Creating visited vector
    // of size n + 1
    int visited[] = new int[n + 1];
 
    // Queue of pair to store node
    // and number of steps
    Queue q = new LinkedList<>();
 
    // Initially ans variable is
    // initialized with inf
    int ans = Integer.MAX_VALUE;
 
    // Push starting node with 0
    // 0 indicate current number
    // of step to reach n
    q.add(new Point(n, 0));
 
    // Mark starting node visited
    visited[n] = 1;
    while(q.size() != 0)
    {
      Point p = q.peek();
      q.poll();
 
      // If node reaches its destination
      // 0 update it with answer
      if(p.x == 0)
        ans = Math.min(ans, p.y);
 
      // Loop for all possible path from
      // 1 to i*i <= current node(p.first)
      for(int i = 1; i * i <= p.x; i++)
      {
 
        // If we are standing at some node
        // then next node it can jump to will
        // be current node-
        // (some square less than or equal n)
        int path = (p.x - (i * i));
 
        // Check if it is valid and
        // not visited yet
        if(path >= 0 && (visited[path] == 0 || path == 0))
        {
 
          // Mark visited
          visited[path] = 1;
 
          // Push it it Queue
          q.add(new Point(path, p.y + 1));
        }
      }
    }
 
    // Return ans to calling function
    return ans;
  }
 
  // Driver code
  public static void main(String[] args)
  {
    System.out.println(numSquares(12));
  }
}
 
// This code is contributed by divyesh072019


Python3
# Python3 program for the above approach
import sys
 
# Function to count minimum
# squares that sum to n
def numSquares(n) :
 
    # Creating visited vector
    # of size n + 1
    visited = [0]*(n + 1)
     
    # Queue of pair to store node
    # and number of steps
    q = []
     
    # Initially ans variable is
    # initialized with inf
    ans = sys.maxsize
     
    # Push starting node with 0
    # 0 indicate current number
    # of step to reach n
    q.append([n, 0])
     
    # Mark starting node visited
    visited[n] = 1
    while(len(q) > 0) :
         
        p = q[0]
        q.pop(0)
     
        # If node reaches its destination
        # 0 update it with answer
        if(p[0] == 0) :
            ans = min(ans, p[1])
     
        # Loop for all possible path from
        # 1 to i*i <= current node(p.first)
        i = 1
        while i * i <= p[0] :
           
            # If we are standing at some node
            # then next node it can jump to will
            # be current node-
            # (some square less than or equal n)
            path = p[0] - i * i
         
            # Check if it is valid and
            # not visited yet
            if path >= 0 and (visited[path] == 0 or path == 0) :
             
                # Mark visited
                visited[path] = 1 
                 
                # Push it it Queue
                q.append([path,p[1] + 1])
             
            i += 1
     
    # Return ans to calling function
    return ans
 
print(numSquares(12))
 
# This code is contributed by divyeshrabadiya07


C#
// C# program for the above approach
using System;
using System.Collections;
using System.Collections.Generic;
 
class GFG{
   
public class Point
{
    public int x, y;
     
    public Point(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
}
 
// Function to count minimum
// squares that sum to n
public static int numSquares(int n)
{
     
    // Creating visited vector
    // of size n + 1
    int []visited = new int[n + 1];
     
    // Queue of pair to store node
    // and number of steps
    Queue q = new Queue();
     
    // Initially ans variable is
    // initialized with inf
    int ans = 1000000000;
     
    // Push starting node with 0
    // 0 indicate current number
    // of step to reach n
    q.Enqueue(new Point(n, 0));
     
    // Mark starting node visited
    visited[n] = 1;
     
    while(q.Count != 0)
    {
        Point p = (Point)q.Dequeue();
         
        // If node reaches its destination
        // 0 update it with answer
        if (p.x == 0)
            ans = Math.Min(ans, p.y);
         
        // Loop for all possible path from
        // 1 to i*i <= current node(p.first)
        for(int i = 1; i * i <= p.x; i++)
        {
             
            // If we are standing at some node
            // then next node it can jump to will
            // be current node-
            // (some square less than or equal n)
            int path = (p.x - (i * i));
             
            // Check if it is valid and
            // not visited yet
            if (path >= 0 && (visited[path] == 0 ||
                                       path == 0))
            {
                 
                // Mark visited
                visited[path] = 1;
                 
                // Push it it Queue
                q.Enqueue(new Point(path, p.y + 1));
            }
        }
    }
     
    // Return ans to calling function
    return ans;
}
 
// Driver code
public static void Main(string[] args)
{
    Console.Write(numSquares(12));
}
}
 
// This code is contributed by rutvik_56


输出
3

上述解决方案的时间复杂度是指数级的。如果我们画递归树,我们可以观察到很多子问题被一次又一次地解决了。例如,当我们从n = 6开始时,我们可以通过2次减1和1次减2达到4。所以 4 的子问题被调用了两次。

由于再次调用相同的子问题,此问题具有重叠子问题的属性。所以最小平方和问题具有动态规划问题的两个属性(见this和this)。与其他典型的动态规划 (DP) 问题一样,可以通过以自底向上的方式构造临时数组 table[][] 来避免对相同子问题的重新计算。下面是一个基于动态编程的解决方案。

C++

// A dynamic programming based
// C++ program to find minimum
// number of squares whose sum
// is equal to a given number
#include 
using namespace std;
 
// Returns count of minimum
// squares that sum to n
int getMinSquares(int n)
{
    // We need to check base case
    // for n i.e. 0,1,2
    // the below array creation
    // will go OutOfBounds.
    if(n<=3)
      return n;
     
    // Create a dynamic
    // programming table
    // to store sq
    int* dp = new int[n + 1];
 
    // getMinSquares table
    // for base case entries
    dp[0] = 0;
    dp[1] = 1;
    dp[2] = 2;
    dp[3] = 3;
 
    // getMinSquares rest of the
    // table using recursive
    // formula
    for (int i = 4; i <= n; i++)
    {
         
        // max value is i as i can
        // always be represented
        // as 1*1 + 1*1 + ...
        dp[i] = i;
 
        // Go through all smaller numbers to
        // to recursively find minimum
        for (int x = 1; x <= ceil(sqrt(i)); x++)
        {
            int temp = x * x;
            if (temp > i)
                break;
            else
                dp[i] = min(dp[i], 1 +
                                  dp[i - temp]);
        }
    }
 
    // Store result and free dp[]
    int res = dp[n];
    delete[] dp;
 
    return res;
}
 
// Driver code
int main()
{
    cout << getMinSquares(6);
    return 0;
}

Java

// A dynamic programming based
// JAVA program to find minimum
// number of squares whose sum
// is equal to a given number
class squares
{
 
    // Returns count of minimum
    // squares that sum to n
    static int getMinSquares(int n)
    {
 
        // We need to add a check
        // here for n. If user enters
        // 0 or 1 or 2
        // the below array creation
        // will go OutOfBounds.
        if (n <= 3)
            return n;
 
        // Create a dynamic programming
        // table
        // to store sq
        int dp[] = new int[n + 1];
 
        // getMinSquares table for
        // base case entries
        dp[0] = 0;
        dp[1] = 1;
        dp[2] = 2;
        dp[3] = 3;
 
        // getMinSquares rest of the
        // table using recursive
        // formula
        for (int i = 4; i <= n; i++)
        {
         
            // max value is i as i can
            // always be represented
            // as 1*1 + 1*1 + ...
            dp[i] = i;
 
            // Go through all smaller numbers to
            // to recursively find minimum
            for (int x = 1; x <= Math.ceil(
                              Math.sqrt(i)); x++)
            {
                int temp = x * x;
                if (temp > i)
                    break;
                else
                    dp[i] = Math.min(dp[i], 1
                                  + dp[i - temp]);
            }
        }
 
        // Store result and free dp[]
        int res = dp[n];
 
        return res;
    }
   
    // Driver Code
    public static void main(String args[])
    {
        System.out.println(getMinSquares(6));
    }
} /* This code is contributed by Rajat Mishra */

蟒蛇3

# A dynamic programming based Python
# program to find minimum number of
# squares whose sum is equal to a
# given number
from math import ceil, sqrt
 
# Returns count of minimum squares
# that sum to n
def getMinSquares(n):
 
    # Create a dynamic programming table
    # to store sq and getMinSquares table
    # for base case entries
    dp = [0, 1, 2, 3]
 
    # getMinSquares rest of the table
    # using recursive formula
    for i in range(4, n + 1):
         
        # max value is i as i can always
        # be represented as 1 * 1 + 1 * 1 + ...
        dp.append(i)
 
        # Go through all smaller numbers
        # to recursively find minimum
        for x in range(1, int(ceil(sqrt(i))) + 1):
            temp = x * x;
            if temp > i:
                break
            else:
                dp[i] = min(dp[i], 1 + dp[i-temp])
 
    # Store result
    return dp[n]
 
# Driver code
print(getMinSquares(6))
 
# This code is contributed by nuclode

C#

// A dynamic programming based
// C# program to find minimum
// number of squares whose sum
// is equal to a given number
using System;
 
class squares
{
 
    // Returns count of minimum
    // squares that sum to n
    static int getMinSquares(int n)
    {
 
        // We need to add a check here
        // for n. If user enters 0 or 1 or 2
        // the below array creation will go
        // OutOfBounds.
 
        if (n <= 3)
            return n;
 
        // Create a dynamic programming
        // table to store sq
        int[] dp = new int[n + 1];
 
        // getMinSquares table for base
        // case entries
        dp[0] = 0;
        dp[1] = 1;
        dp[2] = 2;
        dp[3] = 3;
 
        // getMinSquares for rest of the
        // table using recursive formula
        for (int i = 4; i <= n; i++)
        {
         
            // max value is i as i can
            // always be represented
            // as 1 * 1 + 1 * 1 + ...
            dp[i] = i;
 
            // Go through all smaller numbers to
            // to recursively find minimum
            for (int x = 1; x <= Math.Ceiling(
                              Math.Sqrt(i)); x++)
            {
                int temp = x * x;
                if (temp > i)
                    break;
                else
                    dp[i] = Math.Min(dp[i], 1 +
                                    dp[i - temp]);
            }
        }
 
        // Store result and free dp[]
        int res = dp[n];
 
        return res;
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        Console.Write(getMinSquares(6));
    }
}
 
// This code is contributed by Nitin Mittal.

PHP

 $i)
                break;
            else $dp[$i] = min($dp[$i],
                       (1 + $dp[$i - $temp]));
        }
    }
 
    // Store result
    // and free dp[]
    $res = $dp[$n];
 
    // delete $dp;
    return $res;
}
 
// Driver Code
echo getMinSquares(6);
     
// This code is contributed
// by shiv_bhakt.
?>

Javascript


输出
3

感谢 Gaurav Ahirwar 提出这个解决方案。

另一种方法:(使用 MEMOIZATION)

这个问题也可以使用记忆方法(动态规划)来解决。

下面是实现:

C++

#include 
using namespace std;
 
int minCount(int n)
 
{
 
    int* minSquaresRequired = new int[n + 1];
 
    minSquaresRequired[0] = 0;
 
    minSquaresRequired[1] = 1;
 
    for (int i = 2; i <= n; ++i)
 
    {
 
        minSquaresRequired[i] = INT_MAX;
 
        for (int j = 1; i - (j * j) >= 0; ++j)
 
        {
 
            minSquaresRequired[i]
                = min(minSquaresRequired[i],
                      minSquaresRequired[i - (j * j)]);
        }
 
        minSquaresRequired[i] += 1;
    }
 
    int result = minSquaresRequired[n];
 
    delete[] minSquaresRequired;
 
    return result;
}
 
// Driver code
int main()
{
    cout << minCount(6);
    return 0;
}
输出
3

另一种方法:
这个问题也可以用图来解决。这是如何完成的基本思想。
我们将使用 BFS(广度优先搜索)来找到从给定的 n 值到 0 的最小步数。
因此,对于每个节点,我们会将尚未访问的下一个可能的有效路径推送到队列中,并且,
如果它到达节点 0,如果它小于答案,我们将更新我们的答案。

下面是上述方法的实现:

C++

// C++ program for the above approach
#include 
using namespace std;
 
// Function to count minimum
// squares that sum to n
int numSquares(int n)
{
  
  // Creating visited vector
  // of size n + 1
  vector visited(n + 1,0);
   
  // Queue of pair to store node
  // and number of steps
  queue< pair >q;
   
  // Initially ans variable is
  // initialized with inf
  int ans = INT_MAX;
   
  // Push starting node with 0
  // 0 indicate current number
  // of step to reach n
  q.push({n,0});
   
  // Mark starting node visited
  visited[n] = 1;
  while(!q.empty())
  {
    pair p;
    p = q.front();
    q.pop();
 
    // If node reaches its destination
    // 0 update it with answer
    if(p.first == 0)
      ans=min(ans, p.second);
 
    // Loop for all possible path from
    // 1 to i*i <= current node(p.first)
    for(int i = 1; i * i <= p.first; i++)
    {
       
      // If we are standing at some node
      // then next node it can jump to will
      // be current node-
      // (some square less than or equal n)
      int path=(p.first - (i*i));
 
      // Check if it is valid and
      // not visited yet
      if(path >= 0 && ( !visited[path]
                             || path == 0))
      {
         
        // Mark visited
        visited[path]=1;
         
        // Push it it Queue
        q.push({path,p.second + 1});
      }
    }
  }
   
  // Return ans to calling function
  return ans;
}
 
// Driver code
int main()
{
  cout << numSquares(12);
  return 0;
}

Java

// Java program for the above approach
import java.util.*;
import java.awt.Point;
class GFG
{
  // Function to count minimum
  // squares that sum to n
  public static int numSquares(int n)
  {
 
    // Creating visited vector
    // of size n + 1
    int visited[] = new int[n + 1];
 
    // Queue of pair to store node
    // and number of steps
    Queue q = new LinkedList<>();
 
    // Initially ans variable is
    // initialized with inf
    int ans = Integer.MAX_VALUE;
 
    // Push starting node with 0
    // 0 indicate current number
    // of step to reach n
    q.add(new Point(n, 0));
 
    // Mark starting node visited
    visited[n] = 1;
    while(q.size() != 0)
    {
      Point p = q.peek();
      q.poll();
 
      // If node reaches its destination
      // 0 update it with answer
      if(p.x == 0)
        ans = Math.min(ans, p.y);
 
      // Loop for all possible path from
      // 1 to i*i <= current node(p.first)
      for(int i = 1; i * i <= p.x; i++)
      {
 
        // If we are standing at some node
        // then next node it can jump to will
        // be current node-
        // (some square less than or equal n)
        int path = (p.x - (i * i));
 
        // Check if it is valid and
        // not visited yet
        if(path >= 0 && (visited[path] == 0 || path == 0))
        {
 
          // Mark visited
          visited[path] = 1;
 
          // Push it it Queue
          q.add(new Point(path, p.y + 1));
        }
      }
    }
 
    // Return ans to calling function
    return ans;
  }
 
  // Driver code
  public static void main(String[] args)
  {
    System.out.println(numSquares(12));
  }
}
 
// This code is contributed by divyesh072019

蟒蛇3

# Python3 program for the above approach
import sys
 
# Function to count minimum
# squares that sum to n
def numSquares(n) :
 
    # Creating visited vector
    # of size n + 1
    visited = [0]*(n + 1)
     
    # Queue of pair to store node
    # and number of steps
    q = []
     
    # Initially ans variable is
    # initialized with inf
    ans = sys.maxsize
     
    # Push starting node with 0
    # 0 indicate current number
    # of step to reach n
    q.append([n, 0])
     
    # Mark starting node visited
    visited[n] = 1
    while(len(q) > 0) :
         
        p = q[0]
        q.pop(0)
     
        # If node reaches its destination
        # 0 update it with answer
        if(p[0] == 0) :
            ans = min(ans, p[1])
     
        # Loop for all possible path from
        # 1 to i*i <= current node(p.first)
        i = 1
        while i * i <= p[0] :
           
            # If we are standing at some node
            # then next node it can jump to will
            # be current node-
            # (some square less than or equal n)
            path = p[0] - i * i
         
            # Check if it is valid and
            # not visited yet
            if path >= 0 and (visited[path] == 0 or path == 0) :
             
                # Mark visited
                visited[path] = 1 
                 
                # Push it it Queue
                q.append([path,p[1] + 1])
             
            i += 1
     
    # Return ans to calling function
    return ans
 
print(numSquares(12))
 
# This code is contributed by divyeshrabadiya07

C#

// C# program for the above approach
using System;
using System.Collections;
using System.Collections.Generic;
 
class GFG{
   
public class Point
{
    public int x, y;
     
    public Point(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
}
 
// Function to count minimum
// squares that sum to n
public static int numSquares(int n)
{
     
    // Creating visited vector
    // of size n + 1
    int []visited = new int[n + 1];
     
    // Queue of pair to store node
    // and number of steps
    Queue q = new Queue();
     
    // Initially ans variable is
    // initialized with inf
    int ans = 1000000000;
     
    // Push starting node with 0
    // 0 indicate current number
    // of step to reach n
    q.Enqueue(new Point(n, 0));
     
    // Mark starting node visited
    visited[n] = 1;
     
    while(q.Count != 0)
    {
        Point p = (Point)q.Dequeue();
         
        // If node reaches its destination
        // 0 update it with answer
        if (p.x == 0)
            ans = Math.Min(ans, p.y);
         
        // Loop for all possible path from
        // 1 to i*i <= current node(p.first)
        for(int i = 1; i * i <= p.x; i++)
        {
             
            // If we are standing at some node
            // then next node it can jump to will
            // be current node-
            // (some square less than or equal n)
            int path = (p.x - (i * i));
             
            // Check if it is valid and
            // not visited yet
            if (path >= 0 && (visited[path] == 0 ||
                                       path == 0))
            {
                 
                // Mark visited
                visited[path] = 1;
                 
                // Push it it Queue
                q.Enqueue(new Point(path, p.y + 1));
            }
        }
    }
     
    // Return ans to calling function
    return ans;
}
 
// Driver code
public static void Main(string[] args)
{
    Console.Write(numSquares(12));
}
}
 
// This code is contributed by rutvik_56
输出
3

上述问题的时间复杂度为 O(n)*sqrt(n),比 Recursive 方法要好。
此外,这是了解 BFS(广度优先搜索)如何工作的好方法。

如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写一个。

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程