Leetcode刷题 2021.03.01
Leetcode1773 统计匹配检索规则的物品数量
给你一个数组 items ,其中 items[i] = [typei, colori, namei] ,描述第 i 件物品的类型、颜色以及名称。
另给你一条由两个字符串 ruleKey 和 ruleValue 表示的检索规则。
如果第 i 件物品能满足下述条件之一,则认为该物品与给定的检索规则 匹配 :
ruleKey == “type” 且 ruleValue == typei 。
ruleKey == “color” 且 ruleValue == colori 。
ruleKey == “name” 且 ruleValue == namei 。
统计并返回 匹配检索规则的物品数量 。
昨天早上匆匆忙忙周赛。晚上回学校,本来想到了学校晚上再更新下博客的。结果一打开插座就跳闸了,搞得整个宿舍都没电用-_-||。终于开学了,感觉各种春招也陆续开始了,现在还在纠结到底是硬刚后端还是换客户端。只能一部部看吧,希望能有好的结果吧。
这次周赛题其实感觉不难,第三题应该是比较一般的贪心题,但是越想也复杂。最后时间过了十分钟才A的。这次周赛排名也够差的。。
第一题还是简单题,就分类讨论下就好了。
class Solution {
public int countMatches(List<List<String>> items, String ruleKey, String ruleValue) {
int res = 0;
for(List<String> list : items){
if (ruleKey.equals("color") && list.get(1).equals(ruleValue)){
res++;
}else if(ruleKey.equals("type")&& list.get(0).equals(ruleValue)){
res++;
}else if (ruleKey.equals("name") && list.get(2).equals(ruleValue)){
res++;
}
}
return res;
}
}
Leetcode1774 最接近目标价格的甜点成本
你打算做甜点,现在需要购买配料。目前共有 n 种冰激凌基料和 m 种配料可供选购。而制作甜点需要遵循以下几条规则:
必须选择 一种 冰激凌基料。
可以添加 一种或多种 配料,也可以不添加任何配料。
每种类型的配料 最多两份 。
给你以下三个输入:
baseCosts ,一个长度为 n 的整数数组,其中每个 baseCosts[i] 表示第 i 种冰激凌基料的价格。
toppingCosts,一个长度为 m 的整数数组,其中每个 toppingCosts[i] 表示 一份 第 i 种冰激凌配料的价格。
target ,一个整数,表示你制作甜点的目标价格。
你希望自己做的甜点总成本尽可能接近目标价格 target 。
返回最接近 target 的甜点成本。如果有多种方案,返回 成本相对较低 的一种。
这题一开始以为是背包,后来看了下数据规模,直接暴力搜索了。期间有不少bug,搞了快二十分钟才A出来,还是不太习惯周赛的编程环境。周赛的时候也很急,为了弄快点,导致错误比较多。还是要多参加,多练习啊。
class Solution {
int res = Integer.MAX_VALUE;
public int closestCost(int[] baseCosts, int[] toppingCosts, int target) {
Arrays.sort(baseCosts);
Arrays.sort(toppingCosts);
int sum = 0;
for(int i = 0; i < baseCosts.length; i++){
//先加入必须加的配方
sum = baseCosts[i];
helper(toppingCosts, 0, sum, target);
}
return res;
}
private void helper(int[] toppingCosts, int index, int sum, int target){
int temp = Math.abs(sum - target);
//更新一下结果
if (temp < Math.abs(res - target) || (temp == Math.abs(res - target) && sum < res)){
res = sum;
}
if (index >= toppingCosts.length) return;
if (sum > target) return;
for(int k = 0; k <= 2; k++){
//每种配料最多选两次
sum += k * toppingCosts[index];
helper(toppingCosts, index + 1, sum, target);
sum -= k * toppingCosts[index];
}
}
}
Leetcode1775 通过最少操作次数使数组的和相等
给你两个长度可能不等的整数数组 nums1 和 nums2 。两个数组中的所有值都在 1 到 6 之间(包含 1 和 6)。
每次操作中,你可以选择 任意 数组中的任意一个整数,将它变成 1 到 6 之间 任意 的值(包含 1 和 6)。
请你返回使 nums1 中所有数的和与 nums2 中所有数的和相等的最少操作次数。如果无法使两个数组的和相等,请返回 -1 。
这道题本来应该最多三十分钟就能A的,结果硬是搞到超时才A。就是贪心的做法,因为只有1到6的数字,所以每次都选择最大或者最小的变换就行了。
困难题就算了,除非是暴力能过的困难题,否则现在还真的没什么信心能做出来。
class Solution {
public int minOperations(int[] nums1, int[] nums2) {
int m = nums1.length, n = nums2.length, res = 0, sum1 = 0, sum2 = 0;
//如果一个都为1,一个都为6,还小于的话,那一定无解了。
if (6 * n < m || 6 * m < n) return -1;
//统计一下数字的个数以及总和
int[] map1 = new int[7];
int[] map2 = new int[7];
for(int i = 0; i < m; i++) {
map1[nums1[i]]++;
sum1 += nums1[i];
}
for(int i = 0; i < n; i++) {
map2[nums2[i]]++;
sum2 += nums2[i];
}
//总和相等就直接返回
if (sum1 == sum2) return res;
int temp = Math.abs(sum1 - sum2);
//这里map1代表总和较小的一组数,如果大于就交换下
if (sum1 > sum2){
int[] tempArr = map1;
map1 = map2;
map2 = tempArr;
}
int i = 1;
//贪心的做法
//每一次都选择能变换最大的,比如如果是小的数,想变换到大的数
//肯定是先考虑1变换到6或者如果是大的数就是从6变换到1
while (temp > 0){
while (temp > 0 && map1[i] > 0){
temp -= (7 - i - 1);
map1[i]--;
res++;
}
while (temp > 0 && map2[7 - i] > 0){
temp -= (7 - i - 1);
map2[7 - i]--;
res++;
}
i++;
}
return res;
}
}