【LeetCode第 295 场周赛】

简介: 笔记

1. 重排字符形成目标字符串


题目

1.png

样例

2.png

3.png


4.png

代码

class Solution:
    def rearrangeCharacters(self, s: str, target: str) -> int:
        x = Counter(s)
        y = Counter(target)
        cnt = inf
        for k, v in y.items():
            cnt = min(cnt, x[k] // v)
        return cnt

2. 价格减免

题目

5.png

样例

6.png


7.png

代码

class Solution:
    def discountPrices(self, sentence: str, discount: int) -> str:
        s = []
        for i in sentence.split():
            try:
                assert i[0] == '$'
                val = float(i[1:])
                val *= (100 - discount) / 100
                s.append("$%.2f" % round(val, 2))
            except:
                s.append(i)
        return " ".join(s)


3. 使数组按非递减顺序排列


题目

8.png


样例


9.png

10.png

代码

观察一个性质:


对于一串非降的序列(序列前有个更大的元素),该序列每个元素被删除的时间是单调递增的。

利用这一单调性,我们只需要存储这串非降序列的最后一个元素被删除的时间,这些时间的最大值就是所需要计算的最大值。

用一个单调递减栈存储元素及其被删除的时间,当遇到一个不小于栈顶的元素 x 时,就不断弹出栈顶元素,并取弹出元素被删除时间的最大值。

class Solution {
public:
    int totalSteps(vector<int>& nums) {
        int res = 0;
        stack<pair<int, int>> s;
        for (auto &x: nums) {
            int maxT = 0; // 当前x应该删除的时间
            // 栈不空 & x>=top
            while(!s.empty() && s.top().first <= x) {
                maxT = max(maxT, s.top().second);
                s.pop();
            }
            if(!s.empty()) ++maxT;
            res = max(maxT, res);
            s.push({x, maxT});
        }
        return res;
    }
};

4. 到达角落需要移除障碍物的最小数目


题目

11.png

样例


12.png13.png

代码

0-1 BFS:

把障碍物当作可以经过的单元格,经过它的代价为 1 ,空单元格经过的代价为 0 。

问题转化成从起点到终点的最短路。

我们可以用 Dijkstra(priority_queue),但还可以用 0-1 BFS 来将时间复杂度优化至 O(mn)。

对于队列里头的元素,很显然的是,同一时间最多只会相差点权为 1.

于是通过堆来排序的思路可以换作双端队列来手动排序, + 0  的排到队头, + 1 的排到队尾。

class Solution {
public:
    static constexpr int walk[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
    static constexpr int inf = 0x3f3f3f3f;
    int minimumObstacles(vector<vector<int>>& grid) {
        int n = grid.size(), m = grid[0].size();
        vector<vector<int>> dis(n, vector<int>(m, inf));
        deque<pair<int, int>> q;
        q.emplace_front(0, 0);
        dis[0][0] = 0;
        while(q.size()) {
            auto [x, y] = q.front(); q.pop_front();
            for (auto &[fx, fy]: walk) {
                int dx = fx + x, dy = fy + y;
                if(dx >= 0 && dx < n && dy >= 0 && dy < m) {
                    int f = grid[dx][dy];
                    if(dis[x][y] + f < dis[dx][dy]) {
                        dis[dx][dy] = dis[x][y] + f;
                        f == 0 ? q.emplace_front(dx, dy) : q.emplace_back(dx, dy);
                    }
                }
            }
        }
        return dis[n - 1][m - 1];
    }
};
相关文章
|
6月前
|
Go
golang力扣leetcode 第 291 场周赛
golang力扣leetcode 第 291 场周赛
61 0
|
6月前
|
Go vr&ar
golang力扣leetcode 第 288 场周赛
golang力扣leetcode 第 288 场周赛
52 0
|
6月前
|
Go
golang力扣leetcode 第 286 场周赛
golang力扣leetcode 第 286 场周赛
57 0
|
算法 Android开发
LeetCode 周赛上分之旅 #48 一道简单的树上动态规划问题
学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越抽象,它能覆盖的问题域就越广,理解难度也更复杂。在这个专栏里,小彭与你分享每场 LeetCode 周赛的解题报告,一起体会上分之旅。
64 1
|
6月前
|
Go
golang力扣leetcode第 294 场周赛
golang力扣leetcode第 294 场周赛
53 0
|
6月前
|
算法 Java Go
golang力扣leetcode 第 293 场周赛
golang力扣leetcode 第 293 场周赛
82 0
|
6月前
|
Go
golang力扣leetcode 第 290 场周赛
golang力扣leetcode 第 290 场周赛
52 0
|
6月前
|
Go C++
golang力扣leetcode 第 284 场周赛
golang力扣leetcode 第 284 场周赛
58 0
|
6月前
|
Go
golang力扣leetcode 第 292 场周赛
golang力扣leetcode 第 292 场周赛
66 0
|
6月前
|
存储
Leetcode第383场周赛
在LeetCode第383场周赛中,选手完成了3道题目。第一题是关于边界上的蚂蚁,蚂蚁根据非零整数数组nums的值移动,返回蚂蚁返回边界上的次数。解题方法是计算数组累加和为0的次数。第二题涉及计算网格的区域平均强度,给定一个灰度图像和阈值,返回每个像素所属区域的平均强度。解题关键在于理解相邻像素和区域定义,并计算平均强度。第三题是恢复单词初始状态的最短时间问题,通过移除前k个字符并添加k个字符,求恢复原词所需的最短时间。解题策略是检查去除前k个字符后的子串是否能作为原词的前缀。
33 1
Leetcode第383场周赛