吃掉 N 个橘子的最少天数(emmm)

吃掉 N 个橘子的最少天数(emmm)_第1张图片

 

这道题看起来很简单,我一眼就看出来可以用动态规划去做了,然后我就:

        for(int i=1; i<=n; i++){
            if(i % 2 == 0 && i % 3 == 0){
                dp[i] = Math.min(Math.min(dp[i-1]+1, dp[i/2]+1), Math.min(dp[i-1] + 1, dp[i-2*(i/3)]+1));
            }
            else if(i % 3 == 0 && i % 2 != 0) {
                dp[i] = Math.min(dp[i-1] + 1, dp[i-2*(i/3)]+1);
            }
            else if(i % 2 == 0 && i % 3 != 0){
                dp[i] = Math.min(dp[i-1]+1, dp[i/2]+1);
            }
            else {
                dp[i] = dp[i-1] + 1;
            }
        }

结果,当n的值为61455274时,数组太大,栈溢出

然后我就想,既然从下向上做栈溢出,那我从上往下做总可以了吧,采用递归get函数:

  • 比如说是n = 11:
  • 11既不能被2整除,也不能被3整除,所以只能是get(10)+1步
  • 10进来了,能被2整除,不过get不一定是get(5)+1就小,因为结果证明,get(9)+1的结果会更小,所以Min{get(5)+1, get(9)+1}
  • 然后就去找get(5)和get(9)
  • 比如9,因为我们也无法确定是get(3)+1大还是get(8)+1大,所以我又去判断了get(8)
  • ......

从上到下,每个元素都判断了一遍,结果大大超时!!!

然后我咋想就想不出来到底该咋办,唉.............看了答案:

class Solution {

    public int minDays(int n) {
        return getMinDay(n);

    }
    private Map maps = new HashMap<>();

    private int getMinDay(int n){
        if(n == 1) return 1;
        if(n == 2) return 2;
        if(n == 3) return 2;
        Integer re = maps.get(n);
        // 是否之前计算过
        if(re != null) return (int)re;

        int m2 = getMinDay(n/2)+n%2;
        int m3 = getMinDay(n/3)+n%3;
        int result = Math.min(m2, m3)+1;
        // 存储结果
        maps.put(n,result);
        return result;
    }
}

就这三步操作,你细品吧:

        int m2 = getMinDay(n/2)+n%2;
        int m3 = getMinDay(n/3)+n%3;
        int result = Math.min(m2, m3)+1;

 

你可能感兴趣的:(leetecode,吃掉,N,个橘子的最少天数)