Perfect Squares--lintcode

Description

Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, …) which sum to n.

Example

Given n = 12, return 3 because 12 = 4 + 4 + 4
Given n = 13, return 2 because 13 = 4 + 9

这道题是说 给我们一个正整数,求它能由几个最少的平方和组成。可以用到四平方和定理(我的知识很匮乏啊)

根据四平方和定理,任意一个正整数均可表示为4个整数的平方和,其实是可以表示为4个以内的平方数之和,那么就是说返回结果只有1,2,3或4其中的一个。将数字简化一下,一个数含有因子4,可以除去这个4,获得的结果不变。例如 12/4=3. 12的返回结果是3, 3的返回结果也是3. 还有8和2。还有一个可以简化的是如果一个数除以8余7的话,那么肯定是由4个完全平方数组成。(可以自行举例)。接下来 将正整数 拆成两个平方数之和,如果拆成功了,则返回1或者2。

可能好奇a>0 && b>0 ?2 :1;是干什么的,判断a和b是否都是整数,如果都是则返回2 只要一个是 返回1(不可能两个都不是整数的。)

  public int numSquares(int n) {
   while (n % 4 == 0) n /= 4;
        if (n % 8 == 7) return 4;
        for (int a = 1; a * a <= n; ++a) {
            //取整
            double b =Math.floor(Math.sqrt(n - a * a)) ;
            if (a * a + b * b == n) {
               // return !!a + !!b;
               //System.out.println(a+" "+b);
               return a>0 && b>0 ?2 :1;
            }
        }
        return 3;
 }

还要一种是动态规划 Dynamic Programming.

这里写图片描述

红色部分表示平方数,所有的完美平方数都可以看做一个普通数加上一个完美平方数,那么递推式就变为了:dp[i + j * j] = Math.min(dp[i] + 1, dp[i + j * j]).

public int numSquares(int n) {  
        int[] dp = new int[n+1];  
        Arrays.fill(dp, Integer.MAX_VALUE);  

        for(int i = 0; i * i <= n; i++)   
            dp[i * i] = 1;  

        for(int i = 1; i <= n; i++) {  //选定第一个数为 i  
            for(int j = 1; i + j * j <= n; j++) {  //选定另一个数为 j*j  
                dp[i + j * j] = Math.min(dp[i] + 1, dp[i + j * j]);  //从小到大查找  
            }  
        }  
        return dp[n];  
    }  

刚看到这段代码的时候 ,我很好奇 这个i+j*j是怎么想到的。(我想了很长时间就没有想到)。

还有一种写法 也是动态规划 虽然比上面的运算时间长,但是容易理解点

用 dp[i] 数组存储第 i 个数的完美平方数。递推式为:dp[i] = Math.max(dp[j] + dp[i-j], dp[i],认为 i 的完全平方数是从和为 i 的两个完全平方数 dp[j] 和 dp[i-j]之和,然后从中取最小。

public int numSquares(int n) {  
        int[] dp = new int[n+1];  
        Arrays.fill(dp, Integer.MAX_VALUE);  
        dp[1] = 1;  
        for(int i = 1; i <= n; i++) {  
            int sqr = (int)Math.sqrt(i);  
            if(sqr * sqr == i) dp[i] = 1;  //如果 i 本身是个平方数,就将 dp[i] 置1  
            else {  
                for(int j = 1; j <= i/2; j++) {  
                    dp[i] = Math.min(dp[j] + dp[i-j], dp[i]);  //从0开始遍历所有和为 i 的 dp,使得 dp[i]取最小  
                }  
            }  
        }  
        return dp[n];  
    }  

参考网址:http://blog.csdn.net/happyaaaaaaaaaaa/article/details/51584790
http://www.cnblogs.com/grandyang/p/4800552.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]: Curves and Surfaces A Bidirectional Generating Algorithm for Rational Parametric Curves(Z. Li, L. Ma)Fast Detection of the Geometric Form of Two-Dimensional Cubic Bézier Curves(S. Vincent)Exact Evaluation of Subdivision Surfaces(eigenstructures for Catmull-Clark and Loop schemes) (J. Stam)Exact Evaluation of Catmull-Clark Subdivision Surfaces near B-Spline Boundaries(D. Lacewell, B. Burley)Smooth Two-Dimensional Interpolations: A Recipe for All Polygons(E. Malsch, J. Lin, G. Dasgupta) Normal Patches / PN-Triangles(R. Stimpson)Marching Cubes(.vol files) (R. Stimpson)Coons Patches(R. Stimpson)Exact Catmull-Clark Subdivision evaluation(and mean-curvature minimization) (F. Hecht)Laplacian Surface Editing(2D curve deformation) (O. Sorkine, D. Cohen-Or, Y. Lipman, M. Alexa, C. Roessl, H.-P. Seidel)Elasticurves: Exploiting Stroke Dynamics and Inertia for the Real-time Neatening of Sketched 2D Curves(Y. Thiel, K. Singh, R. Balakrishnan) 。 引用\[2\]: Segmentation efpisoft: hierarchical mesh segmentation based on fitting primitives(M. Attene)mesh segmentation benchmark database and viewer(X. Chen, A. Golovinskiy, T. Funkhouser)Graphite(variational shape approximation,image vectorization) \[documentation wiki\] (Authors)SegMatch: Shape Segmentation and Shape Matching from Point Cloud(T. Dey, S. Goswami)ShapeAnnotatorsegmentation tool (fitting primitives, barycentric/height/integral geodesic Morse, Plumber, Lloyd clustering)(Authors)Shape Diameter Function (SDF) segmentation tool(L. Shapira) 。 引用\[3\]:DP。对于每个'#'来说,要使图美丽就要保证每个'#'的正下方到正右下都填满'#' ....#. ....#. ...... ....## .#.... -> .#..## (题解里CV过来的) ...... .##.## ...... .##### 。 问题: Defect-free Squares是什么意思? 回答: Defect-free Squares是指在一个图形中,每个'#'的正下方到正右下方都填满了'#',从而使整个图形看起来没有缺陷。这个概念可以通过动态规划(DP)来实现,对于每个'#',需要保证其正下方到正右下方都填满了'#',从而形成一个完整的正方形。\[3\] #### 引用[.reference_title] - *1* *2* [图形学领域的关键算法及源码链接](https://blog.csdn.net/u013476464/article/details/40857873)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [ABC311 A-F](https://blog.csdn.net/Muelsyse_/article/details/131873631)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值