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;
        
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值