zoukankan      html  css  js  c++  java
  • 单周赛 253 题解

    知识点:字符串比较,大根堆,贪心,最长上升子序列,二分优化

    检查字符串是否为数组前缀

    给定一个字符串 (s),给定一个字典 (w),如果 (w) 中前 (k) 个字符串可以构成 (s),返回 (true),否则返回 (false),其中 (1leq kleq w.size)

    题解

    模拟

    // cpp
    class Solution {
    public:
        bool isPrefixString(string s, vector<string>& words) {
            string temp;
            for (int i = 0; i < words.size(); ++i) {
                temp += words[i];
                if (s == temp) return 1;
            }
            return 0;
        }
    };
    
    // go
    func isPrefixString(s string, w []string) bool {
        var temp string 
        for _, i := range w {
            temp += i
            if s == temp {
                return true
            }
        }
        return false
    }
    

    移除石子使总数最小

    给定长 (n) 的数组 (a),给定 (k),执行 (k) 次操作,每次把 (a_{i}) 减去 (lfloorfrac{a_{i}}{2} floor),返回操作后 (a) 的数组和的可能的最小值

    题解

    贪心,每次对最大的 (a_{i}) 操作即可,使用优先队列维护,时间复杂度 (O(nlog n))

    // cpp
    class Solution {
    public:
        int minStoneSum(vector<int>& piles, int k) {
            priority_queue<int> pq;
            for (auto &i: piles) pq.push(i);
            while (k--) {
                int top = pq.top(); pq.pop();
                pq.push(top - top / 2);
            }
            int ans = 0;
            while (!pq.empty()) {
                ans += pq.top(); pq.pop();
            }
            return ans;
        }
    };
    

    使字符串平衡的最小交换次数

    给定 [] 组成的字符串,你可以交换任意两个括号,使得整体括号匹配,返回最小的交换数

    保证左右括号数相等

    题解

    找规律,对于题设中的字符串,一定可以抽象成 ]]]]][[[[[ 的形式,设共有 (n) 对,那么答案即为 (lceilfrac{n}{2} ceil)

    // cpp
    class Solution {
    public:
        int minSwaps(string s) {
            int l = 0, r = 0;
            for (auto &i: s) {
                if (i == '[') l++;
                else {
                    if (l) l--;
                    else r++;
                }
            }
            return (r + 1) / 2;
        }
    };
    
    // go
    func minSwaps(s string) int {
        l := 0
        r := 0
        for _, i := range(s) {
            if i == '[' {
                l++
            } else {
                if l > 0 {
                    l--
                } else {
                    r++
                }
            }
        }
        return (r + 1) / 2
    }
    

    找出到每个位置为止最长的有效障碍赛跑路线

    给定长为 (n) 的数组 (a),找到以每个位置 (i) 结尾的最长不降子序列的长度,以数组形式返回

    数据规定

    (1leq nleq 10^5)

    题解

    使用 (LIS) 的二分解法

    具体来讲,设 (dp[i]) 表示长为 (i + 1) 的最长不降子序列的最后一个位置的最小值,初始化为 (inf)

    对于每一个位置 (i),可以在 (dp) 数组中二分查找最后一个小于 (a[i]) 的位置,并把 (a[i]) 赋值在该位置后面,获取最长不降子序列的长度只需要用该位置减去数组头,维护答案即可

    举个例子,对 a[4] = [1, 2, 3, 2] 进行操作

    dp 数组初始化:
    [inf, inf, inf, inf]
    
    处理 a[0] = 1,得到:
    [1, inf, inf, inf]
    
    处理 a[1] = 2,得到:
    [1, 2, inf, inf]
    
    处理 a[2] = 3,得到:
    [1, 2, 3, inf]
    
    处理 a[3] = 2,得到:
    [1, 2, 2, inf]
    
    // cpp
    class Solution {
    public:
        #define inf 0x3f3f3f3f
        vector<int> longestObstacleCourseAtEachPosition(vector<int>& o) {
            int n = o.size();
            vector<int> dp(n + 7), ans(n + 7);
            fill(dp.begin(), dp.end(), inf);
            for (int i = 0; i < n; ++i) {
                int len = upper_bound(dp.begin(), dp.end(), o[i]) - dp.begin() + 1;
                *upper_bound(dp.begin(), dp.end(), o[i]) = o[i];
                ans[i] = len;
            }
            return {ans.begin(), ans.begin() + n};
        }
    };
    
  • 相关阅读:
    Maven下载依赖项的源代码(source code)和Javadoc
    Spring读写xml文件
    重建二叉树
    从尾到头打印链表
    替换空格
    洞穴逃生
    二维数组中的查找
    分苹果
    最小生成树算法prim and kruskal
    HTTP报文格式详解
  • 原文地址:https://www.cnblogs.com/ChenyangXu/p/15147224.html
Copyright © 2011-2022 走看看