• 279. Perfect Squares


    问题:

    给定数字n,求将其分解为多个*方数的和,最少用多少个*方数可以得到。

    Example 1:
    Input: n = 12
    Output: 3
    Explanation: 12 = 4 + 4 + 4.
    
    Example 2:
    Input: n = 13
    Output: 2
    Explanation: 13 = 4 + 9. 
    
    Constraints:
    1 <= n <= 104
    

      

    解法:Binary Search(二分查找)BFS(广度优先搜索)

    对于一个数n,

    首先,需要找到与它最*的*方数,getmaxsq(n, formar_try)

    ♻️ 优化:减少查找的消耗:若有上次查找的结果formar_try,那么上限为min(formar_try, n)

    base状态:由于题目给定的限制,

    • 1 <= n <= 10^4

    那么查找上限,不超过100。

    那么,BFS中,

    • queue里保存:剩下的当前数字cur,上次查找结果formar_try
      • 对于当前cur,我们可拆分的选择有:j:
        • getmaxsq(n, formar_try)获得的最大*方数->1 的所有选择。
      • 每次,做出选择后,cur-j^2 作为剩下的数字存入queue,待下一次继续拆解。
    • 遍历层数,即为所求最少的拆分次数。
    • 若此时cur-j^2==0,则找到完全拆分的一个解。由于res从小到大,那么第一次找到,即为最少。

    代码参考:

     1 class Solution {
     2 public:
     3     int getmaxsq(int n, int right) {
     4         int l = 1, r = right;
     5         if(n<right) r = n;
     6         while(l<r) {
     7             int m = l+(r-l)/2;
     8             if(m*m >= n) {
     9                 r = m;
    10             } else {
    11                 l = m+1;
    12             }
    13         }
    14         return l;
    15     }
    16     int numSquares(int n) {
    17         int res=0;
    18         if(n==1) return 1;
    19         queue<pair<int,int>> q;//leftnum,formartry
    20         q.push({n,getmaxsq(n,min(100,n))});
    21         int sz = 0;
    22         int cur=0, nextcur=0, trysq=100;
    23         while(!q.empty()) {
    24             sz=q.size();
    25             res++;
    26             for(int i=0; i<sz; i++) {
    27                 cur = q.front().first;
    28                 trysq = q.front().second;
    29                 //printf("cur:%d, trysq:%d
    ", cur, trysq);
    30                 q.pop();
    31                 for(int j=trysq; j>0; j--) {
    32                     nextcur = cur-j*j;
    33                     if(nextcur==0) return res;
    34                     if(nextcur<0) continue;
    35                     q.push({nextcur, getmaxsq(nextcur, j)});
    36                 }
    37             }
    38             //printf("
    ");
    39         }
    40         return res;
    41     }
    42 };
  • 相关阅读:
    【机器学习】scikit-learn中的特征选择小结
    【机器学习】scikit-learn中的数据预处理小结(归一化、缺失值填充、离散特征编码、连续值分箱)
    【机器学习】随机森林原理与调参小结
    用find命令巧查目录下文件的个数
    git
    数据库删除主键
    Linux安装JDK
    计算机进制
    java虚拟机故障处理工具
    线程的六种状态
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/14464936.html
Copyright © 2020-2023  润新知