leetcode第70场双周赛

leetcode第70场双周赛

第一题[2144. 打折购买糖果的最小开销]

贪心:

  1. 要使得花费的钱最少,就要尽可能的免费拿到价格高的糖果
class Solution {
    public int minimumCost(int[] cost) {
           //这感觉是贪心算法
        if (cost.length == 2){
            return cost[0] + cost[1];
        }
        Arrays.sort(cost);
        int res = 0;
        int count = 0;
        for (int i = cost.length - 1;i >= 0;i--){
            if (count == 2) {
                count = 0;
                continue;
            }
            count++;
            res += cost[i];
        }
        return res;
    }
}

第二题[2145. 统计隐藏数组数目]

前缀和 + 差分数组:

需要注意的一点是结果用int会爆

前缀和数组接触的不多,刷完dp之后,会是理解的对象,以前理解的都快要忘光了。

class Solution {
    public int numberOfArrays(int[] differences, int lower, int upper) {
        //试着理解差分数组的范围
        long sum = 0,min = 0,max = 0;
        for(int i = 0;i < differences.length;i++){
            sum += differences[i];
            if(sum > max){
                max = sum;
            }else if ( sum < min){
                min = sum;
            }
        }

        int res =(int) (upper - lower + 1 -(max - min));
        return res > 0? res : 0;
    }
}

第三题[2146. 价格范围内最高排名的 K 样物品]

BFS + 优先队列

还是不熟练,思路想到了,但是代码不熟练,中间花了很多很多时间。中间搜索,向周围扩开,用deque做容器装二维数组中所有的数据,根据条件进行筛选放在优先队列里面进行排序,排序的规则就是题目说的,先数字小的,行小的,后列小的。

class Solution {
    List<List<Integer>> res;
    int[][] direct = new int[][]{{-1,0},{1,0},{0,-1},{0,1}};
    public List<List<Integer>> highestRankedKItems(int[][] grid, int[] pricing, int[] start, int k) {
        //想明白了,感觉还是挺简单的,比较难的点可能就在优先队列的排序规则
        //试着广度优先搜索,尽可能的写一写吧
        res = new LinkedList<>();
        int len = grid.length;
        int line = grid[0].length;
        //辅助的队列
        Deque<int[]> d = new ArrayDeque<>();
        d.addLast(start);
        PriorityQueue<int[]> queue = new PriorityQueue<>((a,b)->{
            if(grid[a[0]][a[1]] ==  grid[b[0]][b[1]]){
                if(a[0] == b[0]){
                    return a[1] - b[1];
                }

                return a[0] - b[0];
            }

            return grid[a[0]][a[1]] - grid[b[0]][b[1]];
        });
        boolean[][] visit = new boolean [len][line];
        visit[start[0]][start[1]] = true;
        while(!d.isEmpty() && res.size() < k){
            int size = d.size();
            for(int i = 0;i < size;i++){
                int[] xy = d.poll();
                int cprice = grid[xy[0]][xy[1]];
                if(cprice == 0){
                    continue;
                }
                if(cprice == 1 || cprice < pricing[0] || cprice > pricing[1]){

                }else{
                    queue.add(xy); 
                }
                // 深搜还是跑不了啊
                for(int j = 0;j < direct.length;j++){
                    int x = xy[0] + direct[j][0];
                    int y = xy[1] + direct[j][1];
                    if(x >= 0 && x < len && y >= 0 && y < line && !visit[x][y]){
                        d.addLast(new int[]{x,y});
                        visit[x][y] = true;
                    }
                }
            }

            while(!queue.isEmpty() && res.size() < k){
                int[] poll = queue.poll();
                LinkedList<Integer> temp = new LinkedList<Integer>();
                temp.add(poll[0]);
                temp.add(poll[1]);
                res.add(temp);
            }

        }
        return res;
    }
}

第四题 分隔长廊的方案数

排列组合:

  • 每次用两个盆栽进行分组,统计两组之间盆栽的数量,相乘极为结果,为什么要mod上一个10000007呢? 我不李姐。
class Solution {
    public int numberOfWays(String corridor) {
        //我好像明白了,把每两个椅子之间进行分组,统计中间植物的数量,然后×在一起
        int slen = 0;
        int plen = 0;
        long res = 1;
        int mod = 1000000007;
        for(int i = 0;i < corridor.length();i++){
            if(corridor.charAt(i) == 'S'){
                if(slen != 0 && slen % 2 == 0){
                    if(plen != 0){
                        res *= (plen + 1);
                        res = res % mod;
                        plen = 0;
                    }
                }
                slen++;
            }else if(slen % 2 == 0 && slen != 0){
                plen++;
            }
        }

        if(slen == 2){
            return 1;
        }else if (slen % 2 != 0 || slen == 0){
            return 0;
        }else{
            return (int)res % mod;
        }

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值