力扣周赛 501

Q1. 连接逆序数组

🔗 https://leetcode.cn/contest/weekly-contest-501/problems/concatenate-array-with-reverse/description/

题目

  • 给定长度为 n 的数组 nums,返回长度为 2n 的数组:前半部分为 nums 本身,后半部分为 nums 的逆序。

思路

  • 简单数组操作

代码

cpp 复制代码
class Solution {
public:
    vector<int> concatWithReverse(vector<int>& nums) {
        vector<int> ans = nums;
        int n = nums.size();
        for (int i = 0; i < n; i++) {
            ans.push_back(nums[n - i - 1]);
        }
        return ans;
    }
};

Q2. 有效单词计数

🔗 https://leetcode.cn/contest/weekly-contest-501/problems/count-valid-word-occurrences/description/

题目

  • 将字符串数组 chunks 拼接成字符串 s,再给定查询数组 queries。
  • 单词定义:s 中由小写字母组成、连字符仅出现在两个小写字母之间、且不能被更长的合法串包含的极大子串。
  • 返回数组 ans,ans[i] 为 queries[i] 作为单词在 s 中出现的次数。

思路

  • 碰到 a-z,拼接字符串累积
  • 碰到 - ,进行前序判断
    • 若为空,丢弃
    • 若为 a-z,拼接上 -
    • 其他(-),非合法连字符,进行单词统计
  • 其他(空格),进行单词统计

代码

cpp 复制代码
class Solution {
public:
    vector<int> countWordOccurrences(vector<string>& chunks, vector<string>& queries) {
        stack<char> st;
        map<string, int> mp;

        auto count = [&](stack<char>& st) {
            string key;
            while (!st.empty() && st.top() == '-') st.pop();
            while (st.empty() == false) {
               key.push_back(st.top()); 
                st.pop();
            }
            reverse(key.begin(), key.end()); 
            mp[key]++;
            //printf("mp %s %d\n", key.c_str(), mp[key]);
        };

        
        for (string& chunk : chunks) {
            for (char& ch : chunk) {
                if (ch >= 'a' && ch <= 'z') st.push(ch);
                else if (ch == '-') {
                    if (st.empty()) continue;
                    char tmp = st.top();
                    if (tmp >= 'a' && tmp <= 'z') {
                        st.push(ch);
                        continue;
                    } else {
                        count(st);
                    }
                } else {
                    count(st);
                }
            }
        }
        count(st);

        vector<int> ans;
        for (string& query : queries) {
            ans.push_back(mp[query]);
        }
        return ans;
    }
};

Q3. 可整除替换后的数组最小元素和

🔗 https://leetcode.cn/contest/weekly-contest-501/problems/minimize-array-sum-using-divisible-replacements/description/

题目

  • 给定整数数组 nums
  • 可以任意多次操作:若 nums[a] % nums[b] == 0,则将 nums[a] 替换为 nums[b]
  • 返回操作后数组元素和的最小值。

思路

  • 数据范围 10^5,埃拉托斯特尼筛法
  • 把 nums 中数字的倍数全部标记,最后用 nums 的原数据查询一下标记数组

代码

cpp 复制代码
class Solution {
public:
    long long minArraySum(vector<int>& nums) {
        int max_num = 0;
        set<int> s;
        for (int num : nums) {
            max_num = max(max_num, num);
            s.insert(num);
        }

        vector<int> min_div(max_num + 1, 0);
        for (int i = 1; i <= max_num; ++i) {
            if (s.count(i)) {
                int mark = i;
                while (mark <= max_num) {
                    if (min_div[mark] == 0) {
                        min_div[mark] = i;
                    
                    }
                      mark += i;
                    
                }
            }
        }

        long long ans = 0;
        for (int num : nums) {
            ans += min_div[num];
        }

        return ans;
    }
};

Q4. 购买苹果的最低成本 II

🔗 https://leetcode.cn/contest/weekly-contest-501/problems/minimum-cost-to-buy-apples-ii/description/

题目

  • n个商店,苹果价格为 prices[i]
  • 道路 [u, v, cost, tax] 双向,空手走费用 cost,携带苹果走费用 cost*tax,去程回程路径可不同
  • 对每个商店 i,返回获得一个苹果的最小总花费(可直接买,或空手去别处买再带回)。

思路

  • 用 cost 图,算第 i 个商店的去程的单源最短路,dijkstra
  • 用 cost * tax 图,算第 i 个商店的回程的单源最短路,dijkstra
  • 计算第 i 个商店,是直接买,还是去到某个商店(cost 图的单元最短路 + cost * tax 图的单元最短路 + 某个商店 price)的最小值
  • 对每个商店都这样计算一遍

代码

cpp 复制代码
class Solution {
public:
    vector<int> minCost(int n, vector<int>& prices, vector<vector<int>>& roads) {
        const uint64_t INF = 1e18;
        vector<uint64_t> go(n);
        vector<uint64_t> back(n);

        auto dijkstra = [&](int st, vector<vector<pair<int, uint64_t>>>& edges) {
            vector<uint64_t> d(n, INF);
            d[st] = 0;

            priority_queue<pair<uint64_t, int>, vector<pair<uint64_t, int>>, greater<pair<uint64_t, int>>> pq;
            pq.push({0, st});

            while (!pq.empty()) {
                auto [dist, node] = pq.top(); pq.pop();

                if (dist > d[node]) continue;
                if (dist >= prices[st]) continue;

                for (auto& edge : edges[node]) {
                    int v = edge.first;
                    uint64_t c = edge.second;

                    if (d[v] > dist + c) {
                        d[v] = dist + c;
                        pq.push({d[v], v});
                    }
                }   
            }

            return d;
        };

        vector<vector<pair<int, uint64_t>>> edge1(n); // node, cost
        vector<vector<pair<int, uint64_t>>> edge2(n);
        

        for (auto& road : roads) {
            int u = road[0];
            int v = road[1];
            int cost = road[2];
            int tax = road[3];

            edge1[u].push_back({v, cost});
            edge1[v].push_back({u, cost});

            edge2[u].push_back({v, cost * (uint64_t)tax});
            edge2[v].push_back({u, cost * (uint64_t)tax}); 
        }

        vector<int> ans;
        for (int i = 0; i < n; i++) {
            int min_cost = prices[i];

            go = dijkstra(i, edge1);
            back = dijkstra(i, edge2);

            for (int j = 0; j < n; j++) {
                if (go[j] == INF || back[j] == INF) continue;
                min_cost = min((uint64_t)min_cost, go[j] + back[j] + prices[j]);
            }
            
            ans.push_back(min_cost);
        }
        return ans;
        
    }
};
相关推荐
努力d小白1 小时前
leetcode70.爬楼梯
算法
AbandonForce1 小时前
LeetCode 滑动窗口个人思路详解
算法·leetcode·职场和发展
bnmoel1 小时前
数据结构深度剖析顺序表:结构、扩容与增删查改全解析
c语言·数据结构·算法·顺序表
Liangwei Lin1 小时前
LeetCode 45. 跳跃游戏 II
数据结构·算法·leetcode
青山师1 小时前
Java内存模型深度解析:Happens-Before规则与内存屏障实现原理
java·spring·面试·职场和发展·java程序员·jmm
啦啦啦_99991 小时前
4. 决策树剪枝
算法·决策树·剪枝
鹿角片ljp1 小时前
全局哈希去重原理与数据集实践
算法·安全·哈希算法
Paranoid-up1 小时前
安全启动和安全固件更新(SBSFU)3:加密基础
算法·安全·哈希算法·iap·安全启动·安全升级·sbsfu
是wzoi的一名用户啊~1 小时前
Floyd 模版 弗洛伊德算法 模版
c++·算法·动态规划·图论·floyd