• [Leetcode Weekly Contest]294


    链接:LeetCode

    [Leetcode]2278. 字母在字符串中的百分比

    给你一个字符串 s 和一个字符 letter ,返回在 s 中等于 letter 字符所占的 百分比 ,向下取整到最接近的百分比。

    只要可以选出满足条件的下标,就一直执行这个操作。
    在执行所有操作后,返回 words 。可以证明,按任意顺序为每步操作选择下标都会得到相同的结果。
    字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。例如,"dacb" 是 "abdc" 的一个字母异位词。

    遍历即可。

    class Solution {
        public int percentageLetter(String s, char letter) {
            int count = 0;
            for(var ch:s.toCharArray()) {
                if(ch == letter) count++;
            }
            return count * 100 / s.length();
        }
    }
    

    [Leetcode]2279. 装满石头的背包的最大数量

    现有编号从 0 到 n - 1 的 n 个背包。给你两个下标从 0 开始的整数数组 capacity 和 rocks 。第 i 个背包最大可以装 capacity[i] 块石头,当前已经装了 rocks[i] 块石头。另给你一个整数 additionalRocks ,表示你可以放置的额外石头数量,石头可以往 任意 背包中放置。
    请你将额外的石头放入一些背包中,并返回放置后装满石头的背包的 最大 数量。

    贪心 + 前缀和 + 二分。

    class Solution {
        public int maximumBags(int[] capacity, int[] rocks, int additionalRocks) {
            int n = capacity.length;
            int[] rest = new int[n];
            for(int i=0;i<n;++i) rest[i] = capacity[i] - rocks[i];
            Arrays.sort(rest);
            long[] preSum = new long[n+1];
            for(int i=1;i<n+1;++i) preSum[i] = preSum[i-1] + rest[i-1];
            return getFistLargerIndex(preSum, additionalRocks)-1;
        }
    
        public int getFistLargerIndex(long[] nums, int target) {
            int n = nums.length;
            if(nums[n-1] < target) return n;
            int lo = 0, hi = nums.length-1;
            while(lo <= hi) {
                int mid = lo+(hi-lo)/2;
                if(nums[mid] <= target) {
                    lo = mid+1;
                }
                else hi = mid -1;
            }
            return lo;
        }
    }
    

    [Leetcode]2280. 表示一个折线图的最少线段数

    给你一个二维整数数组 stockPrices ,其中 stockPrices[i] = [dayi, pricei] 表示股票在 dayi 的价格为 pricei 。折线图 是一个二维平面上的若干个点组成的图,横坐标表示日期,纵坐标表示价格,折线图由相邻的点连接而成。

    排序 + 遍历统计即可。

    class Solution {
        public int minimumLines(int[][] stockPrices) {
            int n = stockPrices.length;
            if(n == 1) return 0;
            if(n == 2) return 1;
            Arrays.sort(stockPrices, (x,y)->x[0]-y[0]);
            int res = 1;
            int[] pre = new int[] {stockPrices[1][0]-stockPrices[0][0],  stockPrices[1][1]-stockPrices[0][1]};
            for(int i=2;i<n;++i) {
                int[] stockPrice = stockPrices[i];
                int[] preStockPrice = stockPrices[i-1];
                int dx = stockPrice[0]-preStockPrice[0], dy = stockPrice[1]-preStockPrice[1];
                if(pre[0] * dy != pre[1] * dx) {
                    res ++;
                    pre = new int[]{dx, dy};
                }
            }
            return res;
        }
    }
    

    [Leetcode]2281. 巫师的总力量和

    作为国王的统治者,你有一支巫师军队听你指挥。

    给你一个下标从 0 开始的整数数组 strength ,其中 strength[i] 表示第 i 位巫师的力量值。对于连续的一组巫师(也就是这些巫师的力量值是 strength 的 子数组),总力量 定义为以下两个值的 乘积 :

    • 巫师中 最弱 的能力值。
    • 组中所有巫师的个人力量值 之和 。

    请你返回 所有 巫师组的 总 力量之和。由于答案可能很大,请将答案对 \(10^9 + 7\) 取余 后返回。
    子数组 是一个数组里 非空 连续子序列。

    前缀和 + 单调栈,拆成小问题逐步破解。对于每个数组元素 \(a[i]\),首先求出两个数组:

    • \(left[i]\)\(a[i]\) 左侧,且 小于等于 \(a[i]\) 的 第一个数 的下标;
    • \(right[i]\)\(a[i]\) 右侧,且 严格小于 \(a[i]\) 的 的 第一个数 的下标。

    \(left[i]\)\(right[i]\) 可以通过 单调栈 来求。这样,对于每个 \(a[i]\),它的 管辖范围 就是 \([left[i] + 1, right[i] - 1]\),也就是说,所有的包含 \(a[i]\) 的、且范围在管辖范围内的区间,其最小值都是 \(a[i]\)

    然后需要求出每个 '管辖范围' 对答案的贡献。
    我们面临这样一个问题:给定 \(l,i,r(l \le i \le r)\),求

    \[\sum_{x=l}^i\sum_{y=i}^r\text{sum}(a[x...y]) \]

    如果我们对数组 a 求前缀和 psum,那么上面的式子可以写成

    \[\sum_{x=l}^i\sum_{y=i}^r(psum[y] - psum[x-1]) \]

    注意到 \(psum[y]\) 和 x 无关;\(psum[x-1]\) 和 y 无关,那么我们可以把它们拆开来:

    \[\sum_{y=i}^r(psum[y]) \cdot (i-l+1) - \sum_{x=l-1}^{i-1}(psum[x]) \cdot (r - i + 1) \]

    这样,如果求出 psum 数组的前缀和 ppsum,那么上式可以化为

    \[(ppsum[r] - ppsum[i-1]) \cdot (i-l+1) - (ppsum[i-1] - ppsum[l-2]) \cdot (r - i + 1) \]

    这样问题就可以 \((1)\) 解决了。然后把答案乘上 \(a[i]\) ,加到答案 ans 中即可。

    class Solution {
        public int totalStrength(int[] strength) {
            final var mod = (int) 1e9 + 7;
    
            var n = strength.length;
            var left = new int[n];  // left[i] 为左侧严格小于 strength[i] 的最近元素位置(不存在时为 -1)
            var right = new int[n]; // right[i] 为右侧小于等于 strength[i] 的最近元素位置(不存在时为 n)
            Arrays.fill(left, -1);
            Arrays.fill(right, n);
            ArrayDeque<Integer> st = new ArrayDeque<>();
            for (var i = 0; i < n; i++) {
                while (!st.isEmpty() && strength[st.peekFirst()] >= strength[i]) right[st.pop()] = i;
                if(!st.isEmpty())left[i] = st.peekFirst();
                st.push(i);
            }
    
            var s = 0L; // 前缀和
            var ss = new int[n + 2]; // 前缀和的前缀和
            for (var i = 1; i <= n; ++i) {
                s += strength[i - 1];
                ss[i + 1] = (int) ((ss[i] + s) % mod); // 注意取模后,下面计算两个 ss 相减,结果可能为负
            }
    
            var ans = 0L;
            for (var i = 0; i < n; ++i) {
                int l = left[i] + 1, r = right[i] - 1; // [l,r] 左闭右闭
                var tot = ((long) (i - l + 1) * (ss[r + 2] - ss[i + 1]) - (long) (r - i + 1) * (ss[i + 1] - ss[l])) % mod;
                ans = (ans + strength[i] * tot) % mod; // 累加贡献
            }
            return (int) (ans + mod) % mod; // 防止算出负数
        }
    }
    

    参考:LeetCode

  • 相关阅读:
    DB2 for Z/os Statement prepare
    Foreign key (referential) constraints on DB2 LUW v105
    复制Informational constraints on LUW DB2 v105
    DB2 SQL Mixed data in character strings
    DB2 create partitioned table
    MVC中使用EF的技巧集(一)
    Asp.Net MVC 开发技巧(二)
    Linq使用技巧及查询示例(一)
    Asp.Net MVC 开发技巧(一)
    Asp.Net MVC Identity 2.2.1 使用技巧(八)
  • 原文地址:https://www.cnblogs.com/hellojamest/p/16422028.html
Copyright © 2020-2023  润新知