513. 完美平方

描述

給一個(gè)正整數(shù) n, 找到若干個(gè)完全平方數(shù)(比如1, 4, 9, ... )使得他們的和等于 n姜凄。你需要讓平方數(shù)的個(gè)數(shù)最少。

樣例

給出 n = 12, 返回 3 因?yàn)?12 = 4 + 4 + 4顷蟀。
給出 n = 13, 返回 2 因?yàn)?13 = 4 + 9绞呈。

代碼

  1. DP
public class Solution {
    /**
     * @param n a positive integer
     * @return an integer
     */
    public int numSquares(int n) {
        // dp[i]代表當(dāng)前元素i可以分解成的最少平方數(shù)個(gè)數(shù)
        // 從0到n串稀,n + 1個(gè)數(shù)
        int[] dp = new int[n + 1];
        Arrays.fill(dp, Integer.MAX_VALUE);
    
        // 比如9可以分解成3 * 3
        for (int i = 0; i * i <= n; ++i) {
            dp[i * i] = 1;
        }
        
        // i 的上一個(gè)接龍為去掉某個(gè)平方數(shù)j * j(j可多種取值)后剩余的i - j * j
        // dp[i]的值依賴于dp[i - j * j]的值
        for (int i = 0; i <= n; ++i) {
            // j 如果從0開始會(huì)出現(xiàn) i - j * j 還是 i 無變化
            // 無窮次計(jì)算后奇唤,不能直接分解成x * x 的dp[i] 的值為Integer.MAX_VALUE;
            for (int j = 1; j * j <= i; ++j) {
                dp[i] = Math.min(dp[i], dp[i - j * j] + 1);
            }
        }

        return dp[n];
    }
}
  1. 另一種DP
public class Solution {
    /**
     * @param n a positive integer
     * @return an integer
     */
    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;
        }

        // dp[i] 可以確定dp[i + j * j]的值
        for (int i = 0; i <= n; ++i) {
            for (int j = 0; i + j * j <= n; ++j) {
                dp[i + j * j] = Math.min(dp[i] + 1, dp[i + j * j]);
            }
        }

        return dp[n];
    }
}

兩種DP的區(qū)別是第一種計(jì)算當(dāng)前dp[i]的值要不斷向前計(jì)算摊滔,通過前面的dp數(shù)值來確定當(dāng)前dp[i]的值苔巨,第二種dp的做法是通過當(dāng)前dp[i]值確定后邊dp[i]的值

  1. Math
public class Solution {
    /**
     * @param n a positive integer
     * @return an integer
     */
    public int numSquares(int n) {
        while (n % 4 == 0)
            n /= 4;
        if (n % 8 == 7)
            return 4;
        for (int i = 0; i * i <= n; ++i) {
            int j = (int)Math.sqrt(n * 1.0 - i * i);
            if (i * i + j * j == n) {
                int res = 0;
                if (i > 0)
                    res += 1;
                if (j > 0)
                    res += 1;
                return res;
            }
        }
        return 3;
    }
}

四平方和定理瞻润,看不懂
http://blog.csdn.net/jmspan/article/details/51148344

  1. BFS
public class Solution {
    /*
     * @param n: a positive integer
     * @return: An integer
     */
    public int numSquares(int n) {
        if (n == 0) {
            return 1;
        }
        int root = (int) Math.sqrt(n);
        int[] roots = new int[root];
        for (int i = 0; i < root; i++) {
            roots[i] = (i + 1) * (i + 1);
        }
        int len = 0;
        Queue<Integer> q = new LinkedList<>();
        Set<Integer> set = new HashSet<>();
        for (int r : roots) {
            q.offer(r);
            set.add(r);
        }
        while (!q.isEmpty()) {
            len++;
            int size = q.size();
            for (int i = 0; i < size; i++) {
                int curr = q.poll();
                if (curr == n) {
                    return len;
                }
                for (int j = 0; j < roots.length; j++) {
                    int temp = curr + roots[j];
                    if (temp > n || set.contains(temp)) {
                        continue;
                    }
                    q.offer(temp);
                    set.add(temp);
                }
            }
        }
        return -1;
    }
}

把所有小于平方n的數(shù)當(dāng)做結(jié)點(diǎn)喘垂,用BFS尋找最短路徑

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市绍撞,隨后出現(xiàn)的幾起案子正勒,更是在濱河造成了極大的恐慌,老刑警劉巖傻铣,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件章贞,死亡現(xiàn)場離奇詭異,居然都是意外死亡非洲,警方通過查閱死者的電腦和手機(jī)鸭限,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來两踏,“玉大人败京,你說我怎么就攤上這事±掳辏” “怎么了喧枷?”我有些...
    開封第一講書人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我隧甚,道長车荔,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任戚扳,我火速辦了婚禮忧便,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘帽借。我一直安慰自己珠增,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開白布砍艾。 她就那樣靜靜地躺著蒂教,像睡著了一般。 火紅的嫁衣襯著肌膚如雪脆荷。 梳的紋絲不亂的頭發(fā)上凝垛,一...
    開封第一講書人閱讀 51,198評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音蜓谋,去河邊找鬼梦皮。 笑死,一個(gè)胖子當(dāng)著我的面吹牛桃焕,可吹牛的內(nèi)容都是我干的剑肯。 我是一名探鬼主播,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼观堂,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼让网!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起型将,我...
    開封第一講書人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤寂祥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后七兜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體丸凭,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年腕铸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了惜犀。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡狠裹,死狀恐怖虽界,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情涛菠,我是刑警寧澤莉御,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布撇吞,位于F島的核電站,受9級(jí)特大地震影響礁叔,放射性物質(zhì)發(fā)生泄漏牍颈。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一琅关、第九天 我趴在偏房一處隱蔽的房頂上張望煮岁。 院中可真熱鬧,春花似錦涣易、人聲如沸画机。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽步氏。三九已至,卻和暖如春徒爹,著一層夾襖步出監(jiān)牢的瞬間戳护,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來泰國打工瀑焦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人梗肝。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓榛瓮,卻偏偏與公主長得像,于是被迫代替她去往敵國和親巫击。 傳聞我的和親對(duì)象是個(gè)殘疾皇子禀晓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容