力扣372周赛

力扣第372场周赛

使三个字符串相等

模拟,找到最长前缀,再用每个长度减去最长前缀

class Solution {
public:
    int findMinimumOperations(string s1, string s2, string s3) {
        int a = s1.size() , b = s2.size() , c = s3.size();
        int minl = min(a , min(b , c));
        int maxl = max(a , max(b , c));
        int l = 0 , ans = 0;
        for(; l < minl ; l ++){
            if(s1[l] == s2[l] && (s2[l] == s3[l])){
                continue;
            }else{
                break;
            }
        }
        if(l == 0)return -1;
        ans += (a - l);
        ans += (b - l);
        ans += (c - l);
        return ans;
    }
};

区分黑球与白球

贪心,找到最近的位置

class Solution {
public:
    long long minimumSteps(string s) {
        long long ans = 0;
        int n = s.size();
        int cnt = 0;
        for(int i = 0 ; i < n ; i ++){
            if(s[i] == '0')cnt ++;
        }
        vector<int>v;
        for(int i = cnt;  i < n ; i ++){
            if(s[i] == '0')v.push_back(i);
        }
        int j = 0;
        for(int i = 0 ; i < cnt ; i ++){
            if(s[i] != '0'){
                ans += (v[j++] - i);
            }
        }
        return ans;
    }
};

最大异或乘积

单独考虑每一个二进制位,依据数学原理,要让两数尽可能大的同时差尽可能的小

class Solution {
public:
    int maximumXorProduct(long long a, long long b, int n) {
        const int MOD = 1e9 + 7;
        long long p = (a >> n) << n, q = (b >> n) << n;
        for (int i = n - 1; i >= 0; i--) {
            int x = a >> i & 1;
            int y = b >> i & 1;
            if (x == y) p |= 1LL << i, q |= 1LL << i;
            else if (p < q) p |= 1LL << i;
            else q |= 1LL << i;
        }
        p %= MOD;
        q %= MOD;
        return p * q % MOD;
    }
};

找到 Alice 和 Bob 可以相遇的建筑

离线+最小堆

//代码来自灵茶山艾府
class Solution {
public:
    vector<int> leftmostBuildingQueries(vector<int> &heights, vector<vector<int>> &queries) {
        vector<int> ans(queries.size(), -1);

        //以j为右端点时要处理的第i个的高度,第qi个询问
        vector<vector<pair<int, int>>> left(heights.size());
        for (int qi = 0; qi < queries.size(); qi++) {
            int i = queries[qi][0], j = queries[qi][1];
            if (i > j) {
                swap(i, j); // 保证 i <= j
            }
            if (i == j || heights[i] < heights[j]) {
                ans[qi] = j; // i 直接跳到 j
            } else {
                left[j].emplace_back(heights[i], qi); // 离线
            }
        }

        //最小堆
        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;
        for (int i = 0; i < heights.size(); i++) { // 从小到大枚举下标 i
            //右端点为i的询问入堆
            for (auto &p: left[i]) {
                pq.emplace(p); // 后面再回答
            }
            //堆中小于的即为答案
            while (!pq.empty() && pq.top().first < heights[i]) {
                ans[pq.top().second] = i; // 可以跳到 i(此时 i 是最小的)
                pq.pop();
            } 
        }
        return ans;
    }
};

你可能感兴趣的:(力扣,leetcode,算法,c++)