美文网首页
BFS--Perfect Squares

BFS--Perfect Squares

作者: miky_zheng | 来源:发表于2019-02-12 09:18 被阅读0次
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:

Input: n = 12
Output: 3 
Explanation: 12 = 4 + 4 + 4.
Example 2:

Input: n = 13
Output: 2
Explanation: 13 = 4 + 9.

解法1:

 public int numSquares(int n) {
 // If n is a perfect square, return 1.
          if(is_square(n)) 
            {
                return 1;  
            }
            
            // The result is 4 if and only if n can be written in the 
            // form of 4^k*(8*m + 7). Please refer to 
            // Legendre's three-square theorem.
            while ((n & 3) == 0) // n%4 == 0  
            {
                n >>= 2;  
            }
            if ((n & 7) == 7) // n%8 == 7
            {
                return 4;
            }
            
            // Check whether 2 is the result.
            int sqrt_n = (int)(Math.sqrt(n)); 
            for(int i = 1; i <= sqrt_n; i++)
            {  
                if (is_square(n - i*i)) 
                {
                    return 2;  
                }
            }  
            
            return 3;  
        } 

     private boolean is_square(int i) {
            for (int j = 0; j <i; j++) {
                if(j*j==i){
                    return true;
                }
            }
            return false;
        }
上面核心数学理论:四平方和定理
(a^2 + b^2 + c^2 + d^2)(x^2 + y^2 + z^2 + w^2) = 
(ax + by + cz + dw)^2 + (ay - bx + cw - dz)^2 + (az - bw - cx + dy)^2 + (aw + bz - cy - dx)^2

以及推导出的结论:
1.上面的解,只可能是4个答案:1,2,3,4
2.如果结果是4,则n可以表示为:4^k(8m + 7)

以上算法最快。

解法2:

 public int numSquares(int n) {
            int[] memo = new int[n + 1];
            
            Arrays.fill(memo, Integer.MAX_VALUE);
            memo[0] = 0;
            
            for (int i = 1; i <= n; i++) {
                int min = Integer.MAX_VALUE;
                for (int j = 1; i - (j * j) >= 0; j++) {//
                    min = Math.min(min, 1 + memo[i - (j * j)]);
                }
                memo[i] = min;
            }
            
            return memo[n];//      [0, 1, 2, 3, 1, 2, 3, 4, 2]
                           //n=8    [0, 1, 2, 3, 4, 5, 6, 7, 8]
     
        } 

总结:
1)如果n是123456,
解法1只要3ms,
解法2要56ms。
可见数学对科学的重要性。
2)Math.sqrt,获取的是最接近开平方的数。
比如:Math.sqrt(Double.valueOf(13))==3;
3)(n & 3) == 0) // n%4 == 0
((n & 7) == 7) // n%8 == 7
上面两个是恒等的。

其他联想:关于double装箱拆箱的问题见:
https://www.jianshu.com/p/1322a59f9e69

相关文章

网友评论

      本文标题:BFS--Perfect Squares

      本文链接:https://www.haomeiwen.com/subject/urdheqtx.html