1518. 换酒问题

小区便利店正在促销,用 numExchange 个空酒瓶可以兑换一瓶新酒。你购入了 numBottles 瓶酒。

如果喝掉了酒瓶中的酒,那么酒瓶就会变成空的。

请你计算 最多 能喝到多少瓶酒。

/**
	学会从总体上考虑问题,训练思维
*/

//方法一:正常模拟

//开始有n瓶酒,所以ans = n;当且仅当n >= m 时,可以继续喝到酒(兑换),
//兑换后可以得到 a = (下取整)n / m ; 
//剩下 n % m 个,所以还剩下 a + n % m 个瓶子,
//继续兑换
class Solution {
    public int numWaterBottles(int n, int m) {
    	int ans = n;
        while (n >= m) {
        	int a = n / m;
            int b = n % m;
            ans += a;
            n = a + b;
        }
        return ans;
    }
}


//方法二:整体考虑,每次兑换会减少 m - 1个瓶子,拿m个瓶子兑换 1 瓶酒。
//利用每个交易会损失瓶子个数m - 1为定值,可以算出最大交换次数(额外的
//饮用次数)cnt = (向下取整) (n / (m - 1)),加上起始瓶子就是答案。
class Solution {
    public int numWaterBottles(int n, int m) {
    	int cnt = n / (m - 1);
        return n % (m - 1) == 0 ? cnt + n - 1 : cnt + n;
    }
}
  • 注意边界条件:当n为m-1的倍数时,最后一个回合不满足兑换条件,因为最后一个交易回合剩下m-1个酒瓶,不够要求的兑换数量m。

面试题(换酒问题的变体)

alt

  • 初始有n/2瓶汽水,numExchange 分别为2和4(m = 2 or m = 4),问最多能喝多少瓶汽水。
class Solution {
	//方法一
    public int numWaterBottles(int numBottles, int numExchange) {
    	//capExtra 是 初始 n/2 个酒瓶,4换一,能喝到的总数
    	int capExtra = numBottles(n/2, 4);
        //bottleExtra 是 初始 n/2 个酒瓶,2换一,能喝到的总数
        int bottleExtra = numBottles(n/2, 2);
        //多算了一边初始值,所以要减掉
        return capExtra + bottleExtra - n / 2;
    }
    public int numBottles(int n, int m) {
    	int ans = n;
        while (n >= m) {
        	int a = n / m;
            int b = n % m;
            ans += a;
            n = a + b;
        }
        return ans;
    }
}

class Solution {
	//方法二
    public int numWaterBottles(int numBottles, int numExchange) {
    	numBottles = n / 2;//瓶子和瓶盖初始数量;
        numExchange = 2;//瓶子的兑换
        int bottleExtra = numBottles % numExchange == 0 ? 
        				numExchange / (numExchange - 1) - 1 : 
                        numExchange / (numExchange - 1);
        numExchange = 4;//盖子的兑换
        int capExtra = 	numBottles % numExchange == 0 ? 
        				numExchange / (numExchange - 1) - 1 : 
                        numExchange / (numExchange - 1);
        return numBottles + bottleExtra + capExtra;
    }
}