LeetCode 双周赛70

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

一家商店正在打折销售糖果。每购买 两个 糖果,商店会 免费 送一个糖果。
免费送的糖果唯一的限制是:它的价格需要小于等于购买的两个糖果价格的 较小值 。
比方说,总共有 4 个糖果,价格分别为 1 ,2 ,3 和 4 ,一位顾客买了价格为 2 和 3 的糖果,那么他可以免费获得价格为 1 的糖果,但不能获得价格为 4 的糖果。
给你一个下标从 0 开始的整数数组 cost ,其中 cost[i] 表示第 i 个糖果的价格,请你返回获得 所有 糖果的 最小 总开销。

  • 贪心
class Solution {
public:
    int minimumCost(vector<int>& cost) {
        int sum = 0 , cnt = 0 ;
        sort(cost.begin(),cost.end());
        for(int i = cost.size() - 1 ; i >= 0 ; i --){
            cnt ++ ;
            if(cnt % 3 != 0){
                sum += cost[i];
            }
        }
        return sum;
    }
};

lc.2145 统计隐藏数组数目

给你一个下标从 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 。

  • 超时
class Solution {
public:
    int numberOfArrays(vector<int>& d, int lower, int upper) {
        int max = 0 , min = 0 ;
        for(int i = 1 ; i < d.size() ; i ++){
            d[i] += d[i - 1];
            if(d[i] < min) min = d[i];
            if(d[i] > max) max = d[i];
        }
        if(d[0] < min) min = d[0];
        if(d[0] > max) max = d[0];

        if((upper - lower) - (max - min) + 1 > 0) return (upper - lower) - (max - min) + 1 ;
        else return 0;
        
    }
};
  • long long
class Solution {
public:
    int numberOfArrays(vector<int>& d, int lower, int upper) {
        long long int tmp = 0 , maxd = 0 , mind = 0 ;
        for(int i = 0 ; i < d.size() ; i ++){
            tmp += d[i];
            if(tmp < mind) mind = tmp;
            if(tmp > maxd) maxd = tmp;
        }

        if((upper - lower) - (maxd - mind) + 1 > 0) return (upper - lower) - (maxd - mind) + 1 ;
        else return 0;
        
    }
};

服了。超 int 范围了。

lc.2146 价格范围内最高排名的 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 件物品,那么请将它们的坐标 全部 返回。

  • BFS
const int d[4][2] = {{-1, 0}, {0, -1}, {0, 1}, {1, 0}};

class Solution {
public:
    vector<vector<int>> highestRankedKItems(vector<vector<int>>& grid, vector<int>& pricing, vector<int>& start, int k) {
        int n = grid.size(), m = grid[0].size();
        int lo = pricing[0], hi = pricing[1];
        int r = start[0], c = start[1];
        vector<tuple<int, int, int, int>> ans;
        queue<tuple<int, int, int>> q;
        vector<vector<bool>> vis(n, vector<bool>(m));
        q.emplace(0, r, c);
        vis[r][c] = true;
        while (!q.empty()) {
            auto [steps, i, j] = q.front();
            if (grid[i][j] >= lo && grid[i][j] <= hi)
                ans.emplace_back(steps, grid[i][j], i, j);
            q.pop();
            for (int t = 0; t < 4; ++t) {
                int ni = i + d[t][0], nj = j + d[t][1];
                if (ni < 0 || ni >= n || nj < 0 || nj >= m || vis[ni][nj] || grid[ni][nj] == 0)
                    continue;
                q.emplace(steps + 1, ni, nj);
                vis[ni][nj] = true;
            }
        }
        sort(ans.begin(), ans.end());
        vector<vector<int>> ret;
        for (int i = 0; i < min(k, (int)ans.size()); ++i)
            ret.push_back(vector<int>{get<2>(ans[i]), get<3>(ans[i])});
        return ret;
    }
};

lc.2147 分隔长廊的方案数

在一个图书馆的长廊里,有一些座位和装饰植物排成一列。给你一个下标从 0 开始,长度为 n 的字符串 corridor ,它包含字母 ‘S’ 和 ‘P’ ,其中每个 ‘S’ 表示一个座位,每个 ‘P’ 表示一株植物。
在下标 0 的左边和下标 n - 1 的右边 已经 分别各放了一个屏风。你还需要额外放置一些屏风。每一个位置 i - 1 和 i 之间(1 <= i <= n - 1),至多能放一个屏风。
请你将走廊用屏风划分为若干段,且每一段内都 恰好有两个座位 ,而每一段内植物的数目没有要求。可能有多种划分方案,如果两个方案中有任何一个屏风的位置不同,那么它们被视为 不同 方案。
请你返回划分走廊的方案数。由于答案可能很大,请你返回它对 109 + 7 取余 的结果。如果没有任何方案,请返回 0 。

using ll = long long;
const ll MOD = 1e9 + 7;

class Solution {
public:
    int numberOfWays(string corridor) {
        int seats = 0;
        for (char ch : corridor)
            seats += ch == 'S';
        if (seats % 2 != 0)
            return 0;
        
        ll zero = 1, one = 0, two = 0;
        for (char ch : corridor) {
            ll nz = 0, no = 0, nt = 0;
            
            if (ch == 'S') {
                nz = one;
                no = zero;
                nt = one;
            } else {
                nz = (zero + two) % MOD;
                no = one;
                nt = two;
            }
            
            zero = nz, one = no, two = nt;
            
        }
        
        return two;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值