2019-01-06 leetcode279 完全平方數(shù)

Given a positive integern, find the least number of perfect square numbers (for example,1, 4, 9, 16, ...) which sum ton.

For example, givenn=12, return3because12 = 4 + 4 + 4; givenn=13, return2because13 = 4 + 9.

【題目分析】

一個(gè)數(shù)可以由一些完全平方數(shù)相加得到,例如1,4,9,16,...

給定一個(gè)數(shù)n,求出使得相加結(jié)果為n所需最少的完全平方數(shù)的個(gè)數(shù)。

【思路】

1. 遞歸

  對(duì)于一個(gè)數(shù),我們?cè)趺辞笏挠赡男┩耆椒綌?shù)相加得到的呢?

  首先找到距離這個(gè)數(shù)最近的完全平方數(shù)m = x*x,我們從1~x中選擇一個(gè)數(shù),求出n中包含z個(gè)x*x,我們?cè)谶f歸求出n-z*x*x所包含的完全平方數(shù)。遍歷1~x,返回其中最小的結(jié)果。

2. 動(dòng)態(tài)規(guī)劃

  動(dòng)態(tài)規(guī)劃用 dp[i] 數(shù)組存儲(chǔ)第 i 個(gè)數(shù)的完美平方數(shù)。遞推式為:dp[i] = Math.min(dp[j] + dp[i-j], dp[i]),認(rèn)為 i 的完全平方數(shù)是從和為 i 的兩個(gè)完全平方數(shù) dp[j] 和 dp[i-j]之和,然后從中取最小。

?3. 改進(jìn)后的動(dòng)態(tài)規(guī)劃

任何數(shù)字都可以表示成為一個(gè)普通數(shù)字加上一個(gè)完全平方數(shù),因此有如下表格:



任何數(shù)的表示形式

 如圖所示,紅色部分表示平方數(shù),所有的數(shù)都可以看做一個(gè)普通數(shù)加上一個(gè)完美平方數(shù),那么遞推式就變?yōu)榱耍篸p[i + j * j] = Math.min(dp[i] + 1, dp[i + j * j])。

java遞歸實(shí)現(xiàn):

public class Solution {

? ? public int numSquares(int n) {

? ? ? ? int count = n;

? ? ? ? int nearest = (int)Math.sqrt(n);

? ? ? ? if(n == 0) return 0;

? ? ? ? if(nearest*nearest == n) return 1;

? ? ? ? for(int i = nearest; i >= 1; i--) {

? ? ? ? ? ? int cur = 0, num? = n, t = i*i;

? ? ? ? ? ? while(num - t >= 0) {

? ? ? ? ? ? ? ? num -= t;

? ? ? ? ? ? ? ? cur++;

? ? ? ? ? ? }

? ? ? ? ? ? if(cur < count){

? ? ? ? ? ? ? ? count = Math.min(numSquares(num)+cur, count);

? ? ? ? ? ? }

? ? ? ? }


? ? ? ? return count;

? ? }

}

java 動(dòng)態(tài)規(guī)劃實(shí)現(xiàn):

public class Solution {

? ? /*

? ? 動(dòng)態(tài)規(guī)劃的思想來(lái)解決,遞推公式dp[i] = Math.min(dp[j] + dp[i-j], dp[i])

? ? */

? ? public int numSquares(int n) {

? ? ? ? int[] array = new int[n+1];

? ? ? ? Arrays.fill(array, Integer.MAX_VALUE);

? ? ? ? array[1] = 1;


? ? ? ? for(int i = 2; i <=n; i++) {

? ? ? ? ? ? int sqr = (int)Math.sqrt(i);

? ? ? ? ? ? if(sqr*sqr == i) array[i] = 1;

? ? ? ? ? ? else{

? ? ? ? ? ? ? ? for(int j = 1; j <= i/2; j++) {

? ? ? ? ? ? ? ? ? ? array[i] = Math.min(array[j]+array[i-j], array[i]);

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? return array[n];

? ? }

}、

改進(jìn)的動(dòng)態(tài)規(guī)劃實(shí)現(xiàn):

public class Solution {

? ? /*

? ? 改進(jìn)后動(dòng)態(tài)規(guī)劃,遞推公式dp[i+j*j] = Math.min(dp[i]+1, dp[i+j*j])

? ? */

? ? public int numSquares(int n) {

? ? ? ? int[] array = new int[n+1];

? ? ? ? Arrays.fill(array, Integer.MAX_VALUE);


? ? ? ? for(int i = 1; i*i <= n; i++) {

? ? ? ? ? ? array[i*i] = 1;

? ? ? ? }

? ? ? ? for(int i = 1; i <= n; i++) {

? ? ? ? ? ? for(int j = 1; i+j*j <= n; j++) {

? ? ? ? ? ? ? ? array[i+j*j] = Math.min(array[i]+1, array[i+j*j]);

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? return array[n];

? ? }

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 在C語(yǔ)言中,五種基本數(shù)據(jù)類(lèi)型存儲(chǔ)空間長(zhǎng)度的排列順序是: A)char B)char=int<=float C)ch...
    夏天再來(lái)閱讀 4,044評(píng)論 0 2
  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問(wèn)題, 分享了一些自己做題目的經(jīng)驗(yàn)。 張土汪:刷leetcod...
    土汪閱讀 12,922評(píng)論 0 33
  • 【程序1】 題目:古典問(wèn)題:有一對(duì)兔子,從出生后第3個(gè)月起每個(gè)月都生一對(duì)兔子,小兔子長(zhǎng)到第三個(gè)月后每個(gè)月又生一對(duì)兔...
    開(kāi)心的鑼鼓閱讀 3,394評(píng)論 0 9
  • Zero in your target and go for it ....!!!
    勇敢的向日葵閱讀 169評(píng)論 0 0
  • 在外地做生意的,在城市生活的?,F(xiàn)在檔次都提高了。每個(gè)人的眼光和每個(gè)人的稱(chēng)呼,也不一樣了。早期做生意的叫掌柜的,老板...
    范振民閱讀 658評(píng)論 4 31

友情鏈接更多精彩內(nèi)容