思路:
题目的主要信息:
- 1红球+1黄球+1蓝球=1彩票
- 1红球=2黄球+1蓝球
- 1黄球=2蓝球+1红球
- 1蓝球=2红球+1黄球
球的相互兑换是循环的,要求最多可兑换的彩票数
方法一:过程模拟+贪心
具体做法:
采用贪心思想,因为球换球不划算,所以先把能兑换彩票的球换完,再考虑球换球。
在abc不为0的情况下,每个参数减1,彩票数加1。一旦有一个数(假设是a)为0,用另外两个数来换球,这种时候需要3个b球+2个c球才能换一张彩票,最后换到只剩一种颜色的球为止。。因为是一个循环,所以不管是哪个球先被耗尽,另外两个球都能表示。
class Solution {
public:
int two_color_ball(int x, int y){ //用两种球换另一种球,并加上两种球本身换彩排
int count = 0;
while(x > 0 && y > 0){
x -= 3;
y -= 2;
if(x >= 0 && y >= 0)
count++;
}
return count;
}
int solve(int a, int b, int c) {
int res = 0;
while(a > 0 && b > 0 && c > 0){ //优先换完
a--;
b--;
c--;
res++;
}
if(a == 0){ //红球没有换红球
res += two_color_ball(b, c);
}else if(b == 0){//黄球没有换黄球
res += two_color_ball(c, a);
}else {//蓝球没有换蓝球
res += two_color_ball(a, b);
}
return res;
}
};复杂度分析:
- 时间复杂度:
,最多不超过这个复杂度,精确复杂度不可求
- 空间复杂度:
,无额外空间
方法二:数学+贪心
具体做法:
上述模拟过程可以直接用数学来表现:第一个循环,可以直接找到abc三者最小值,可以直接都减去这个最小值,取到最小的那个为0.
再来看谁是0,另外两种球,一种是除以3,一种是除以2,找最小次数。
class Solution {
public:
int solve(int a, int b, int c) {
int res = min(a, min(b, c)); //取三者最小
a -= res;
b -= res;
c -= res;
if(a == 0) //一种为0,用另外两种来换
return res + min(b / 3, c / 2);
else if(b == 0)
return res + min(c / 3, a / 2);
else if(c == 0)
return res + min(a / 3, b / 2);
return res;
}
};复杂度分析:
- 时间复杂度:
,无循环,常数时间
- 空间复杂度:
,常数空间

京公网安备 11010502036488号