【每日LeetCode】二分查找 + 两两之间距离累积和求解公式 + 取模计算小技巧

55 阅读3分钟

2861. 最大合金数 O(nklogC)O(1)\lgroup O(nk\log C)、O(1) \rgroup

image.png

class Solution:
    def maxNumberOfAlloys(self, n: int, k: int, budget: int, composition: List[List[int]], stock: List[int], cost: List[int]) -> int:
        res = 0 
        left = 0
        right = min(stock) + budget
        while left <= right:
            mid = (left + right) // 2
            valid = False 
            for i in range(k): # 遍历 机器
                spend = 0  # 计算 该机器的 生产 mid 个 合金 的 花费
                for composition_j, stock_j, cost_j in zip(composition[i], stock, cost):
                    spend += max(composition_j * mid - stock_j, 0)* cost_j
                if spend <= budget:
                    valid = True
                    break 

            if valid:
                res = mid 
                left = mid + 1
            else:
                right = mid - 1
        return res 

image.png

class Solution {
public:
    int maxNumberOfAlloys(int n, int k, int budget, vector<vector<int>>& composition, vector<int>& stock, vector<int>& cost) {
        int res = 0;
        int left = 0, right = 2e8;
        while (left <= right){
            int mid = (left + right) / 2;
            bool valid = false;
            for (int i = 0; i < k; ++i){// k 台机器
                long long spend = 0;
                for (int j = 0; j < n; ++j){// n 种 合金
                    spend += max((long long)(composition[i][j]) * mid - stock[j], 0LL) * cost[j];              
                }
                if (spend <= budget){
                    valid = true;
                    break;
                }
            }
            if (valid){
                res = mid;
                left = mid + 1;
            }else{
                right = mid - 1;
            }
        }
        return res;        
    }
};

2731. 移动机器人 O(nlogn)O(n)\lgroup O(n\log n)、O(n) \rgroup

这里 要用 一个两两距离和求解公式, 否则超时

此外, 碰撞可忽略。

image.png

class Solution:
    def sumDistance(self, nums: List[int], s: str, d: int) -> int:
        # 
        for i, c in enumerate(s):
            nums[i] += d if c == 'R' else -d 

        res = 0
        nums.sort()
        n = len(nums)
        return sum([(nums[i] - nums[i - 1]) * i * (n - i) for i in range(1, n)]) % (10**9 + 7)


image.png

image.png

class Solution {
public:
    int sumDistance(vector<int>& nums, string s, int d) {
        int n = nums.size();
        const int MOD = 1e9 + 7;
        vector<long long> arr(n);
        for (int i = 0; i < n; ++i){
            arr[i] = 1LL * nums[i] + (s[i] == 'L' ? -d : d);
        }
        sort(arr.begin(), arr.end());
        long long res = 0;
        for (int i = 1; i < n; ++i){
            res +=  i * (arr[i] - arr[i - 1]) % MOD * (n - i) % MOD;
            res %= MOD;  //  (ab)% MOD = (a % MOD)(b % MOD) % MOD
        }
        return res;
    }
};

2272. 最大波动的子字符串

image.png

class Solution:
    def largestVariance(self, s: str) -> int:
        # diff 维护 a 和 b 出现次数 之差  不一定包含 b
        # diffWithB 
        res = 0
        for a, b in permutations(ascii_lowercase, 2):
            diff, diffWithB = 0, -inf 
            for ch in s:
                if ch == a:
                    diff += 1
                    diffWithB += 1
                elif ch == b:
                    diff -= 1
                    diffWithB = diff  # 此时 肯定包含 b 
                    if diff < 0:
                        diff = 0
                if diffWithB > res:
                    res = diffWithB
        return res 

class Solution:
    def largestVariance(self, s: str) -> int:
        # 假设 a 多  b 少 。 最理想的子串情况 是 尽量多的 a 和 1个 b
        # diff 记录  只含a 的未包含 b 的子串长度。
        # diffWithB  出现 一个b 了。 aab a***a**aab 等的 差

        ## 优化,  a  只考虑 s 中 出现的
        res = 0
        diff = [[0] * 26 for _ in range(26)]
        diffWithB = [[-inf] * 26 for _ in range(26)]
        for ch in s:
            ch = ord(ch) - ord('a')
            for i in range(26):
                if i == ch:
                    continue 
                diff[ch][i] += 1
                diffWithB[ch][i] += 1  # 碰到 b 也要 维护, 有时更长
                diff[i][ch] -= 1
                diffWithB[i][ch]  = diff[i][ch]
                if diff[i][ch] < 0:
                    diff[i][ch] = 0
                res = max(res, diffWithB[ch][i], diffWithB[i][ch])

        return res 

——————————

⭐ 方法:枚举最多和最少的字符 + 最大子段和动态规划

class Solution:
    def largestVariance(self, s: str) -> int:
        pos = defaultdict(list)
        for i, ch in enumerate(s):
            pos[ch].append(i)

        res = 0
        for c0, pos0 in pos.items():
            for c1, pos1 in pos.items():
                if c0 != c1:
                    i = j = 0
                    f, g = 0, -inf
                    while i < len(pos0) or j < len(pos1):
                        if j == len(pos1) or (i < len(pos0) and pos0[i] < pos1[j]):
                            f += 1
                            g += 1
                            i += 1
                        else:
                            f = f - 1
                            g = f
                            f = max(f, 0)  # 被 b 隔断了 
                            j += 1
                        res = max(res, g)
        return res 
                        

class Solution {
public:
    int largestVariance(string s) {
        unordered_map<char, vector<int>> pos;
        for (int i = 0; i < s.size(); ++i){
            pos[s[i]].emplace_back(i);
        }
        int res = 0;
        for (auto && [c0, pos0] : pos){
            for (auto && [c1, pos1] : pos){
                if (c0 != c1){
                    int i = 0, j = 0;
                    int f = 0, g = INT_MIN;
                    while (i < pos0.size() || j < pos1.size()){
                        if (j == pos1.size() || (i < pos0.size() && pos0[i] < pos1[j])){
                            ++f;
                            ++g;
                            ++i;
                        }else{
                            --f;
                            g = f;
                            f = max(f, 0); // 被 截断了, 
                            ++j;
                        }
                        res = max(res, g);
                    }
                }
            }
        }
        return res;        
    }
};

image.png

image.png