LeetCode周赛总结——第 70 场双周赛

413 阅读5分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

5971. 打折购买糖果的最小开销

题目

一家商店正在打折销售糖果。每购买 两个 糖果,商店会 免费 送一个糖果。

免费送的糖果唯一的限制是:它的价格需要小于等于购买的两个糖果价格的 较小值 。

比方说,总共有 4 个糖果,价格分别为 1 ,2 ,3 和 4 ,一位顾客买了价格为 2 和 3 的糖果,那么他可以免费获得价格为 1 的糖果,但不能获得价格为 4 的糖果。 给你一个下标从 0 开始的整数数组 cost ,其中 cost[i] 表示第 i 个糖果的价格,请你返回获得 所有 糖果的 最小 总开销。

示例 1:

输入:cost = [1,2,3] 输出:5 解释:我们购买价格为 2 和 3 的糖果,然后免费获得价格为 1 的糖果。 总开销为 2 + 3 = 5 。这是开销最小的 唯一 方案。 注意,我们不能购买价格为 1 和 3 的糖果,并免费获得价格为 2 的糖果。 这是因为免费糖果的价格必须小于等于购买的 2 个糖果价格的较小值。 示例 2:

输入:cost = [6,5,7,9,2,2] 输出:23 解释:最小总开销购买糖果方案为:

  • 购买价格为 9 和 7 的糖果
  • 免费获得价格为 6 的糖果
  • 购买价格为 5 和 2 的糖果
  • 免费获得价格为 2 的最后一个糖果 因此,最小总开销为 9 + 7 + 5 + 2 = 23 。 示例 3:

输入:cost = [5,5] 输出:10 解释:由于只有 2 个糖果,我们需要将它们都购买,而且没有免费糖果。 所以总最小开销为 5 + 5 = 10 。

提示:

1 <= cost.length <= 100 1 <= cost[i] <= 100

来源:力扣(LeetCode)

链接:leetcode-cn.com/problems/mi…

代码

class Solution {
public:
    int minimumCost(vector<int>& cost) {
        sort(cost.begin(), cost.end());
        int cnt=0;
        int cur=0;
        for(int i=cost.size()-1; i >= 0; i--){
            cur++;
            if(cur<=2){
                cnt+= cost[i];
            }else{
                cur=0;
            }
        }
        return cnt;
    }
};

5972. 统计隐藏数组数目

题目

给你一个下标从 0 开始且长度为 n 的整数数组 differences ,它表示一个长度为 n + 1 的 隐藏 数组 相邻 元素之间的 差值 。更正式的表述为:我们将隐藏数组记作 hidden ,那么 differences[i] = hidden[i + 1] - hidden[i] 。

同时给你两个整数 lower 和 upper ,它们表示隐藏数组中所有数字的值都在 闭 区间 [lower, upper] 之间。

比方说,differences = [1, -3, 4] ,lower = 1 ,upper = 6 ,那么隐藏数组是一个长度为 4 且所有值都在 1 和 6 (包含两者)之间的数组。 [3, 4, 1, 5] 和 [4, 5, 2, 6] 都是符合要求的隐藏数组。 [5, 6, 3, 7] 不符合要求,因为它包含大于 6 的元素。 [1, 2, 3, 4] 不符合要求,因为相邻元素的差值不符合给定数据。 请你返回 符合 要求的隐藏数组的数目。如果没有符合要求的隐藏数组,请返回 0 。

示例 1:

输入:differences = [1,-3,4], lower = 1, upper = 6 输出:2 解释:符合要求的隐藏数组为:

  • [3, 4, 1, 5]
  • [4, 5, 2, 6] 所以返回 2 。 示例 2:

输入:differences = [3,-4,5,1,-2], lower = -4, upper = 5 输出:4 解释:符合要求的隐藏数组为:

  • [-3, 0, -4, 1, 2, 0]
  • [-2, 1, -3, 2, 3, 1]
  • [-1, 2, -2, 3, 4, 2]
  • [0, 3, -1, 4, 5, 3] 所以返回 4 。 示例 3:

输入:differences = [4,-7,2], lower = 3, upper = 6 输出:0 解释:没有符合要求的隐藏数组,所以返回 0 。

提示:

n == differences.length 1 <= n <= 105 -105 <= differences[i] <= 105 -105 <= lower <= upper <= 105

来源:力扣(LeetCode)

链接:leetcode-cn.com/problems/co…

代码

class Solution {
public:
    int numberOfArrays(vector<int>& differences, int lower, int upper) {
        long long minn=0, maxn=0;
        long long cnt=0;
        for(int i=0; i < differences.size(); i++){
            cnt+=differences[i];
            minn = min(minn, cnt);
            maxn = max(maxn, cnt);
        }
        int tmp=lower-minn;
        cout<<tmp<<endl;
        minn+=tmp;
        maxn+=tmp;
        if(upper-maxn+1 > 0){
            return upper-maxn+1;
        }
        return 0;
    }
};

5973. 价格范围内最高排名的 K 样物品

题目

给你一个下标从 0 开始的二维整数数组 grid ,它的大小为 m x n ,表示一个商店中物品的分布图。数组中的整数含义为:

0 表示无法穿越的一堵墙。 1 表示可以自由通过的一个空格子。 所有其他正整数表示该格子内的一样物品的价格。你可以自由经过这些格子。 从一个格子走到上下左右相邻格子花费 1 步。

同时给你一个整数数组 pricing 和 start ,其中 pricing = [low, high] 且 start = [row, col] ,表示你开始位置为 (row, col) ,同时你只对物品价格在 闭区间 [low, high] 之内的物品感兴趣。同时给你一个整数 k 。

你想知道给定范围 内 且 排名最高 的 k 件物品的 位置 。排名按照优先级从高到低的以下规则制定:

距离:定义为从 start 到一件物品的最短路径需要的步数(较近 距离的排名更高)。 价格:较低 价格的物品有更高优先级,但只考虑在给定范围之内的价格。 行坐标:较小 行坐标的有更高优先级。 列坐标:较小 列坐标的有更高优先级。 请你返回给定价格内排名最高的 k 件物品的坐标,将它们按照排名排序后返回。如果给定价格内少于 k 件物品,那么请将它们的坐标 全部 返回。

示例 1:

输入:grid = [[1,2,0,1],[1,3,0,1],[0,2,5,1]], pricing = [2,5], start = [0,0], k = 3 输出:[[0,1],[1,1],[2,1]] 解释:起点为 (0,0) 。 价格范围为 [2,5] ,我们可以选择的物品坐标为 (0,1),(1,1),(2,1) 和 (2,2) 。 这些物品的排名为:

  • (0,1) 距离为 1
  • (1,1) 距离为 2
  • (2,1) 距离为 3
  • (2,2) 距离为 4 所以,给定价格范围内排名最高的 3 件物品的坐标为 (0,1),(1,1) 和 (2,1) 。 示例 2:

输入:grid = [[1,2,0,1],[1,3,3,1],[0,2,5,1]], pricing = [2,3], start = [2,3], k = 2 输出:[[2,1],[1,2]] 解释:起点为 (2,3) 。 价格范围为 [2,3] ,我们可以选择的物品坐标为 (0,1),(1,1),(1,2) 和 (2,1) 。 这些物品的排名为:

  • (2,1) 距离为 2 ,价格为 2
  • (1,2) 距离为 2 ,价格为 3
  • (1,1) 距离为 3
  • (0,1) 距离为 4 所以,给定价格范围内排名最高的 2 件物品的坐标为 (2,1) 和 (1,2) 。 示例 3:

输入:grid = [[1,1,1],[0,0,1],[2,3,4]], pricing = [2,3], start = [0,0], k = 3 输出:[[2,1],[2,0]] 解释:起点为 (0,0) 。 价格范围为 [2,3] ,我们可以选择的物品坐标为 (2,0) 和 (2,1) 。 这些物品的排名为:

  • (2,1) 距离为 5
  • (2,0) 距离为 6 所以,给定价格范围内排名最高的 2 件物品的坐标为 (2,1) 和 (2,0) 。 注意,k = 3 但给定价格范围内只有 2 件物品。

提示:

m == grid.length
n == grid[i].length
1 <= m, n <= 105
1 <= m * n <= 105
0 <= grid[i][j] <= 105
pricing.length == 2
2 <= low <= high <= 105
start.length == 2
0 <= row <= m - 1
0 <= col <= n - 1
grid[row][col] > 0
1 <= k <= m * n

来源:力扣(LeetCode)

链接:leetcode-cn.com/problems/k-…

代码

struct Node{
    int dist;
    int price;
    int x;
    int y;
};
int xm[4] = {0,1,0,-1};
int ym[4] = {1,0,-1,0};
class Solution {
public:    
    vector<vector<int>> highestRankedKItems(vector<vector<int>>& grid, vector<int>& pricing, vector<int>& start, int k) {
        queue<Node> q;
        vector<Node> v;
        Node p;
        int m = grid.size(), n=grid[0].size();
        p.dist=0;
        p.price=grid[start[0]][start[1]];
        p.x = start[0];
        p.y = start[1];
        grid[p.x][p.y] = 0;
        q.push(p);
        if(p.price >= pricing[0] && p.price <= pricing[1]){
            v.push_back(p);
        }
        while(!q.empty()){
            p = q.front();
            q.pop();
            for(int i=0; i < 4; i++){
                int newx=p.x + xm[i], newy = p.y + ym[i];   
                if(newx < m && newx >= 0 && newy < n && newy >= 0 && grid[newx][newy] > 0){
                    Node tmp;
                    tmp.dist = p.dist+1;
                    tmp.price = grid[newx][newy];
                    tmp.x = newx;
                    tmp.y = newy;
                    
                    if(tmp.price <= pricing[1] && tmp.price >= pricing[0] && tmp.price != 1){
                        v.push_back(tmp);
                    }
                    q.push(tmp);
                    grid[newx][newy] = 0;
                }
            }
            
        }
        int len = v.size();
        sort(v.begin(),v.end(),[](auto &lhs,auto &rhs){
            if(lhs.dist < rhs.dist)return true;
            if(lhs.dist == rhs.dist){
                if(lhs.price < rhs.price)return true;
                if(lhs.price == rhs.price){
                    if(lhs.x < rhs.x)return true;
                    if(lhs.x == rhs.x)return lhs.y < rhs.y;
                    return false;
                }
                return false;
            }
            return false;
        });
        vector<vector<int>> ans;
        for(int i=0; i < k && i < v.size(); i++){
            vector<int> tmp;
            tmp.push_back(v[i].x);
            tmp.push_back(v[i].y);
            ans.push_back(tmp);
        }
        return ans;
    }
};

5974. 分隔长廊的方案数

题目

在一个图书馆的长廊里,有一些座位和装饰植物排成一列。给你一个下标从 0 开始,长度为 n 的字符串 corridor ,它包含字母 'S' 和 'P' ,其中每个 'S' 表示一个座位,每个 'P' 表示一株植物。

在下标 0 的左边和下标 n - 1 的右边 已经 分别各放了一个屏风。你还需要额外放置一些屏风。每一个位置 i - 1 和 i 之间(1 <= i <= n - 1),至多能放一个屏风。

请你将走廊用屏风划分为若干段,且每一段内都 恰好有两个座位 ,而每一段内植物的数目没有要求。可能有多种划分方案,如果两个方案中有任何一个屏风的位置不同,那么它们被视为 不同 方案。

请你返回划分走廊的方案数。由于答案可能很大,请你返回它对 109 + 7 取余 的结果。如果没有任何方案,请返回 0 。

示例 1:

输入:corridor = "SSPPSPS" 输出:3 解释:总共有 3 种不同分隔走廊的方案。 上图中黑色的竖线表示已经放置好的屏风。 上图每种方案中,每一段都恰好有 两个 座位。 示例 2:

输入:corridor = "PPSPSP" 输出:1 解释:只有 1 种分隔走廊的方案,就是不放置任何屏风。 放置任何的屏风都会导致有一段无法恰好有 2 个座位。 示例 3:

输入:corridor = "S" 输出:0 解释:没有任何方案,因为总是有一段无法恰好有 2 个座位。

提示:

n == corridor.length 1 <= n <= 105 corridor[i] 要么是 'S' ,要么是 'P' 。

来源:力扣(LeetCode)

链接:leetcode-cn.com/problems/nu…

代码

class Solution {
public:
    int numberOfWays(string corridor) {
        int pre, cnt=0;
        int ans = 1; 
        int mod = 1e9+7;
        for(int i=0; i < corridor.size(); i++){
            if(corridor[i] == 'S'){
                cnt++;
                if(cnt >= 3 && cnt % 2){
                    ans = (long)ans * (i - pre) % mod; 
                }
                pre = i;
            } 
        }
        return cnt && cnt % 2==0 ? ans : 0;
    }
};