开篇来个每日一题
1419. 数青蛙
难度中等185收藏分享切换为英文接收动态反馈
给你一个字符串 croakOfFrogs
,它表示不同青蛙发出的蛙鸣声(字符串 "croak"
)的组合。由于同一时间可以有多只青蛙呱呱作响,所以 croakOfFrogs
中会混合多个 “croak”
。
请你返回模拟字符串中所有蛙鸣所需不同青蛙的最少数目。
要想发出蛙鸣 "croak",青蛙必须 依序 输出 ‘c’, ’r’, ’o’, ’a’, ’k’
这 5 个字母。如果没有输出全部五个字母,那么它就不会发出声音。如果字符串 croakOfFrogs
不是由若干有效的 "croak" 字符混合而成,请返回 -1
。
示例 1:
输入:croakOfFrogs = "croakcroak" 输出:1 解释:一只青蛙 “呱呱” 两次
示例 2:
输入:croakOfFrogs = "crcoakroak" 输出:2 解释:最少需要两只青蛙,“呱呱” 声用黑体标注 第一只青蛙 "crcoakroak" 第二只青蛙 "crcoakroak"
示例 3:
输入:croakOfFrogs = "croakcrook" 输出:-1 解释:给出的字符串不是 "croak" 的有效组合。
感觉思路还是明显的,没有给数据范围,统一认为不大
那我们直接记录每个数字出现的次数即可,但是呀,前面的数字出现的次数要大于等于后面的(依序输出),违反了就是-1,还有出现其他的字母也是返回-1
用swith就可以解决了,看我的代码啊哈哈哈
int minNumberOfFrogs(char * croakOfFrogs){
int a[5]={0};
int res = 0, flag = 5;
for(int i = 0; i < strlen(croakOfFrogs); i++)
{
switch(croakOfFrogs[i])
{
case 'c':
if(a[0] == 0)
flag--;
a[0]++;
break;
case 'r':
if(a[0] - a[1] <= 0)
return -1;
if(a[1] == 0)
flag--;
a[1]++;
break;
case 'o':
if(a[1] - a[2] <= 0)
return -1;
if(a[2] == 0)
flag--;
a[2]++;
break;
case 'a':
if(a[2] - a[3] <= 0)
return -1;
if(a[3] == 0)
flag--;
a[3]++;
break;
case 'k':
if(a[3] - a[4] <= 0)
return -1;
if(a[4] == 0)
flag--;
a[4]++;
break;
default:
return -1;
}
if(flag == 0)
{
if(res < a[0])
res = a[0];
for(int j = 0; j < 5; j++)
{
a[j]--;
if(a[j] == 0)
flag++;
}
}
}
if(flag != 5)
return -1;
return res;
}
有很多的方法去写,判断以及输出结果,都是可以有自己的思路的,脑袋清晰,就是薄纱
来上前天为难我的题目,可恶不够细节,老是内存报错,数组总是开的不对,这题目又给我上了一课
可恶啊啊啊啊啊
2106. 摘水果
难度困难129收藏分享切换为英文接收动态反馈
在一个无限的 x 坐标轴上,有许多水果分布在其中某些位置。给你一个二维整数数组 fruits
,其中 fruits[i] = [positioni, amounti]
表示共有 amounti
个水果放置在 positioni
上。fruits
已经按 positioni
升序排列 ,每个 positioni
互不相同 。
另给你两个整数 startPos
和 k
。最初,你位于 startPos
。从任何位置,你可以选择 向左或者向右 走。在 x 轴上每移动 一个单位 ,就记作 一步 。你总共可以走 最多 k
步。你每达到一个位置,都会摘掉全部的水果,水果也将从该位置消失(不会再生)。
返回你可以摘到水果的 最大总数 。
示例 1:
输入:fruits = [[2,8],[6,3],[8,6]], startPos = 5, k = 4 输出:9 解释: 最佳路线为: - 向右移动到位置 6 ,摘到 3 个水果 - 向右移动到位置 8 ,摘到 6 个水果 移动 3 步,共摘到 3 + 6 = 9 个水果
示例 2:
输入:fruits = [[0,9],[4,1],[5,7],[6,2],[7,4],[10,9]], startPos = 5, k = 4 输出:14 解释: 可以移动最多 k = 4 步,所以无法到达位置 0 和位置 10 。 最佳路线为: - 在初始位置 5 ,摘到 7 个水果 - 向左移动到位置 4 ,摘到 1 个水果 - 向右移动到位置 6 ,摘到 2 个水果 - 向右移动到位置 7 ,摘到 4 个水果 移动 1 + 3 = 4 步,共摘到 7 + 1 + 2 + 4 = 14 个水果
示例 3:
输入:fruits = [[0,3],[6,4],[8,5]], startPos = 3, k = 2 输出:0 解释: 最多可以移动 k = 2 步,无法到达任一有水果的地方
提示:
1 <= fruits.length <= 105
fruits[i].length == 2
0 <= startPos, positioni <= 2 * 105
- 对于任意
i > 0
,positioni-1 < positioni
均成立(下标从 0 开始计数) 1 <= amounti <= 104
0 <= k <= 2 * 105
还是一样的,滑动窗口加上前缀和的核心,我们是可以选择,向左在向右,或者向右再向左,枚举每个步数,用前缀和快速得出答案,最后取最大的
有几点的细节要注意了,你的最大的位移是 k+starpos,但是水果的分布可能大于最大位移点,也可能小于,但是我们要取的是二者的最大,都要包含(在这上面跪了一天了,无语了)
前缀和只要左边界大于0就可以了右边界无关紧要,超出了也是正确的答案(我之前想限定边界,额真脑壳有问题)
上代码看看吧
int max(int a,int b){
if(a>b){
return a;}
else{
return b;}
}
int maxTotalFruits(int** fruits, int fruitsSize, int* fruitsColSize, int startPos, int k){
int len=max(fruits[fruitsSize-1][0],startPos+k)+1;
int *qian = (int*)calloc(len, sizeof(int));
int *qians = (int*)calloc(len, sizeof(int));
qians[fruits[0][0]]=fruits[0][1];
for(int j=1;j<fruitsSize;j++){
qians[fruits[j][0]]=fruits[j][1];
}
qian[0]=qians[0];
for(int h=1;h<len;h++){
qian[h]=qian[h-1]+qians[h];
}
int maxr=0;
for(int h=0;h<=k;h++){
int y = (k-h) / 2;
int l = startPos - h;
int r = startPos + y;
l= (l < 0 ? 0 : l);
int he = qian[r] - qian[l] + qians[l];
maxr = max(maxr, he);
l = startPos - y;
r = startPos + h;
he = 0;
l = (l < 0 ? 0 : l);
he = qian[r] - qian[l] + qians[l];
maxr = max(maxr, he);
}
return maxr;
}
可能有人会问,哎要是往一个方向走,
回不来了,那样计算的结果就会出戳,额确实是的,我考虑了一下,确实如此,但是上面的y的计算的方式确实完美的规避这个问题,确实还可以的呀
哈哈细心就会赢的,哎哎呀我真的是
今天还是进行了,java的学习,都不难全凭记忆
太黑了,明天发笔记
主要是学习了,集合,以及stringbuild的一点点的底层逻辑,
还有集合的,增删改查
哈哈下面有一些我在自己点脑上写的东西
目前的进度是黑马程序员的java课程115集的样子