39.猜数字大小Ⅱ(dedium)

1.题目链接:375. 猜数字大小 II - 力扣(LeetCode)375. 猜数字大小 II - 我们正在玩一个猜数游戏,游戏规则如下: 1. 我从 1 到 n 之间选择一个数字。 2. 你来猜我选了哪个数字。 3. 如果你猜到正确的数字,就会 赢得游戏 。 4. 如果你猜错了,那么我会告诉你,我选的数字比你的 更大或者更小 ,并且你需要继续猜数。 5. 每当你猜了数字 x 并且猜错了的时候,你需要支付金额为 x 的现金。如果你花光了钱,就会 输掉游戏 。给你一个特定的数字 n ,返回能够 确保你获胜 的最小现金数,不管我选择那个数字 。 示例 1:[https://assets.leetcode.com/uploads/2020/09/10/graph.png]输入:n = 10输出:16解释:制胜策略如下:- 数字范围是 [1,10] 。你先猜测数字为 7 。  - 如果这是我选中的数字,你的总费用为 $0 。否则,你需要支付 $7 。  - 如果我的数字更大,则下一步需要猜测的数字范围是 [8,10] 。你可以猜测数字为 9 。  - 如果这是我选中的数字,你的总费用为 $7 。否则,你需要支付 $9 。  - 如果我的数字更大,那么这个数字一定是 10 。你猜测数字为 10 并赢得游戏,总费用为 $7 + $9 = $16 。  - 如果我的数字更小,那么这个数字一定是 8 。你猜测数字为 8 并赢得游戏,总费用为 $7 + $9 = $16 。  - 如果我的数字更小,则下一步需要猜测的数字范围是 [1,6] 。你可以猜测数字为 3 。  - 如果这是我选中的数字,你的总费用为 $7 。否则,你需要支付 $3 。  - 如果我的数字更大,则下一步需要猜测的数字范围是 [4,6] 。你可以猜测数字为 5 。  - 如果这是我选中的数字,你的总费用为 $7 + $3 = $10 。否则,你需要支付 $5 。  - 如果我的数字更大,那么这个数字一定是 6 。你猜测数字为 6 并赢得游戏,总费用为 $7 + $3 + $5 = $15 。  - 如果我的数字更小,那么这个数字一定是 4 。你猜测数字为 4 并赢得游戏,总费用为 $7 + $3 + $5 = $15 。  - 如果我的数字更小,则下一步需要猜测的数字范围是 [1,2] 。你可以猜测数字为 1 。  - 如果这是我选中的数字,你的总费用为 $7 + $3 = $10 。否则,你需要支付 $1 。  - 如果我的数字更大,那么这个数字一定是 2 。你猜测数字为 2 并赢得游戏,总费用为 $7 + $3 + $1 = $11 。在最糟糕的情况下,你需要支付 $16 。因此,你只需要 $16 就可以确保自己赢得游戏。示例 2:输入:n = 1输出:0解释:只有一个可能的数字,所以你可以直接猜 1 并赢得游戏,无需支付任何费用。示例 3:输入:n = 2输出:1解释:有两个可能的数字 1 和 2 。- 你可以先猜 1 。  - 如果这是我选中的数字,你的总费用为 $0 。否则,你需要支付 $1 。  - 如果我的数字更大,那么这个数字一定是 2 。你猜测数字为 2 并赢得游戏,总费用为 $1 。最糟糕的情况下,你需要支付 $1 。 提示: * 1 <= n <= 200https://leetcode.cn/problems/guess-number-higher-or-lower-ii/description/

2.题目描述:

我们正在玩一个猜数游戏,游戏规则如下:
             a. 我从 1 到 n 之间选择一个数字。​
             b. 你来猜我选了哪个数字。​
             c. 如果你猜到正确的数字,就会 赢得游戏 。​
             d. 如果你猜错了,那么我会告诉你,我选的数字比你的 更大或者更小 ,并且你需要继续猜数。​         

             e. 每当你猜了数字 x 并且猜错了的时候,你需要支付金额为 x 的现金。如果你花光了钱,就会输掉游戏 。​
    给你一个特定的数字 n ,返回能够 确保你获胜 的最小现金数,不管我选择那个数字 。​​
示例 1:​

        输入:n = 10​
        输出:16​
解释:制胜策略如下:
     数字范围是 [1,10] 。你先猜测数字为 7 。​
 - 如果这是我选中的数字,你的总费用为 $0 。否则,你需要支付 $7 。​
 - 如果我的数字更大,则下一步需要猜测的数字范围是 [8,10] 。你可以猜测数字为 9 。​
         - 如果这是我选中的数字,你的总费用为 $7 。否则,你需要支付 $9 。​
         - 如果我的数字更大,那么这个数字一定是 10 。你猜测数字为 10 并赢得游戏,总费用为 $7 + $9 = $16 。​
         - 如果我的数字更小,那么这个数字一定是 8 。你猜测数字为 8 并赢得游戏,总费用为 $7 + $9 = $16 。​
 - 如果我的数字更小,则下一步需要猜测的数字范围是 [1,6] 。你可以猜测数字为 3 。​
         - 如果这是我选中的数字,你的总费用为 $7 。否则,你需要支付 $3 。​
         - 如果我的数字更大,则下一步需要猜测的数字范围是 [4,6] 。你可以猜测数字为 5 。​
         - 如果这是我选中的数字,你的总费用为 $7 + $3 = $10 。否则,你需要支付 $5 。​
         - 如果我的数字更大,那么这个数字一定是 6 。你猜测数字为 6 并赢得游戏,总费用为 $7 + $3 + $5 = $15 。​
         - 如果我的数字更小,那么这个数字一定是 4 。你猜测数字为 4 并赢得游戏,总费用为 $7 + $3 + $5 = $15 。​

                  - 如果我的数字更小,则下一步需要猜测的数字范围是 [1,2] 。你可以猜测数字为 1 。​
                  - 如果这是我选中的数字,你的总费用为 $7 + $3 = $10 。否则,你需要支付 $1 。​
                  - 如果我的数字更大,那么这个数字一定是 2 。你猜测数字为 2 并赢得游戏,总费用为 $7 + $3 + $1 = $11 。​
     在最糟糕的情况下,你需要支付 $16 。因此,你只需要 $16 就可以确保自己赢得游戏。​
     示例 2:​
             输入:n = 1​
             输出:0​
             解释:只有一个可能的数字,所以你可以直接猜 1 并赢得游戏,无需支付任何费用。​
     示例 3:​
             输入:n = 2​
             输出:1​
             解释:有两个可能的数字 1 和 2 。​
                  你可以先猜 1 。​
                 - 如果这是我选中的数字,你的总费用为 $0 。否则,你需要支付 $1 。​
                 - 如果我的数字更大,那么这个数字一定是 2 。你猜测数字为 2 并赢得游戏,总费用为 $1 。​    最糟糕的情况下,你需要支付 $1 。​
     提示:
             1 <= n <= 200​
3. 解法(暴搜 -> 记忆化搜索):​
算法思路:
暴搜:
         a. 递归含义:给 dfs  一个使命,给他一个区间 [left, right] ,返回在这个区间上能完胜的最小费用;
         b. 函数体:选择 [left, right]  区间上的任意一个数作为头结点,然后递归分析左右子树。求出所有情况下的最小值;​
        c. 递归出口:当 left >= right  的时候,直接返回 0 。​

记忆化搜索:
a. 加上一个备忘录;

b. 每次进入递归的时候,去备忘录里面看看;​

c. 每次返回的时候,将结果加入到备忘录里面。

Java算法代码:

class Solution {
    int [][] memo;

    public int getMoneyAmount(int n) {
        memo = new int[n+1][n+1];
        return dfs(1,n);
    }

    public int dfs(int left, int right) {
        if(left >= right) return 0;
        if(memo[left][right] != 0) return memo[left][right];
        int ret = Integer.MAX_VALUE;
        for( int head = left; head <= right; head++){
            int x = dfs(left, head - 1);
            int y = dfs(head + 1,right);
            ret = Math.min(Math.max(x,y) + head, ret);
        }
        memo[left][right] = ret;
        return ret;
    }
}

运行结果:

递归展开:

这里笔者简单做两句解释,一个是先找最大的(再一个二叉搜索树中,看那个比较大,也就是从那个叉上来比较大。),然后再这里找到的所有的大的值里面取最小的。

逻辑展开:笔者这里是通过n=3来进行展开,并且同时以二叉搜索树的形式来画(笔者可以思考一下)。为什么这里的二叉搜索树。

---------------------------------------------------------------------------------------------------------------------------------

记住,相信你的递归函数,它可以做到!

记住,不理解时候,去尝试手动展开!

记住,逻辑展开(你不可能对所有的题目都进行手动展开)!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值