279. Perfect Squares

来源:互联网 发布:淘宝黄牛怎么举报 编辑:程序博客网 时间:2024/05/21 10:40

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

For example, given n = 12, return 3 because 12 = 4 + 4 + 4; given n = 13, return 2 because 13 = 4 + 9.

思路:这题和之前322.Coins Change差不多,只是硬币变成了平方数,具体思路还是DP做,递推式都和之前那题一样:d[i]=min(d[i],d[i−c[i]]+1),每个数都由平方数组合而成,具体见代码:

class Solution {public:    int numSquares(int n) {        vector<int> res(n+1,n+1);        res[0] = 0;        for (int i = 1;i<res.size();i++){            for(int j = 0;j<=int(sqrt(i));j++){                res[i] = min(res[i-j*j]+1,res[i]);            }        }        return res[n];    }};

注意到其实在对应计算当前i时,之前的已经计算完了,有种递归的思路在里面,而且这题和322的题不同,它相当于隐含了每个数都有解的意思在里面。但是这个方法还有一个问题,就是问题题目判定程序都要重新构造一个长为n+1的数组,很费时间,所以Solutions里就有人写了下面这个新的方法:

class Solution {public:    int numSquares(int n)     {        if (n <= 0)        {            return 0;        }        // cntPerfectSquares[i] = the least number of perfect square numbers         // which sum to i. Since cntPerfectSquares is a static vector, if         // cntPerfectSquares.size() > n, we have already calculated the result         // during previous function calls and we can just return the result now.        static vector<int> cntPerfectSquares({0});        // While cntPerfectSquares.size() <= n, we need to incrementally         // calculate the next result until we get the result for n.        while (cntPerfectSquares.size() <= n)        {            int m = cntPerfectSquares.size();            int cntSquares = INT_MAX;            for (int i = 1; i*i <= m; i++)            {                cntSquares = min(cntSquares, cntPerfectSquares[m - i*i] + 1);            }            cntPerfectSquares.push_back(cntSquares);        }        return cntPerfectSquares[n];    }};

这个静态方法中vector的声明只会被执行一次,所以之后小于上次执行函数中n的解,就可以直接从静态数组中读取出来了,当然这题还有一个数学的方法,也就是我之前说的这题必有解的原因,Lagrange’s four-square theorem,简单来说,就是一个自然数,必定能拆分成四个平方数(当然这里0也算平方数),所以只要求解出解是1~4之中哪个,再结合Legendre’s three-square theorem 就可以找出解是哪个了,具体看参考代码:

class Solution {  private:      int is_square(int n)    {          int sqrt_n = (int)(sqrt(n));          return (sqrt_n*sqrt_n == n);      }public:    // Based on Lagrange's Four Square theorem, there     // are only 4 possible results: 1, 2, 3, 4.    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)(sqrt(n));         for(int i = 1; i <= sqrt_n; i++)        {              if (is_square(n - i*i))             {                return 2;              }        }          return 3;      }  }; 

最后还有一个BFS的python的代码,比较有意思,也放上来

def numSquares(self, n):    if n < 2:        return n    lst = []    i = 1    while i * i <= n:        lst.append( i * i )        i += 1    cnt = 0    toCheck = {n}    while toCheck:        cnt += 1        temp = set()        for x in toCheck:            for y in lst:                if x == y:                    return cnt                if x < y:                    break                temp.add(x-y)        toCheck = temp    return cnt
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 快递号码写错了怎么办 网购下单后商家说没有货该怎么办 京东账号换手机怎么办 手机不发验证码怎么办 京东打白条分期付款额度不够怎么办 网易云音乐昵称被占用怎么办 ebay账号邮箱忘了怎么办 易贝账号邮箱忘了怎么办 运动鞋网上擦了黑鞋油怎么办 真皮鞋用水洗了怎么办 支付宝余额限额了怎么办 微信余额转账限额怎么办 微信充值话费充错了怎么办 京东白条月限额怎么办 淘手游上买的账号被找回了怎么办 手机看视频缓冲慢怎么办 wan口状态未连接怎么办 王者荣耀本地回放过期怎么办 qq邮件发错了怎么办 千叶钻戒换款怎么办 车钥匙掉厕所了怎么办 宿舍有个整晚磨牙的室友该怎么办 百度云照片压缩后模糊怎么办 手机点+号无法上传图片怎么办 支付宝账户支付功能关闭怎么办 一件衣服买小了怎么办 交行u盾密码忘了怎么办 老婆婚内出轨丈夫应该怎么办 微信小程序获取用户信息失败怎么办 拼多多砍价没有完成怎么办 微信人数上限了怎么办 微信5000人满了怎么办 微信朋友满了怎么办啊 失业金签到忘签怎么办 gec安全密码忘了怎么办 唯品会微信商城地址错怎么办跨省 电脑突然没网了怎么办 移动光猫只能连一台电脑怎么办 网上银行用户名和密码忘了怎么办 中国银行网银用户名忘了怎么办 中行企业网银证书过期怎么办