leetcode解题思路分析(一百四十四)1247 - 1253 题

  1. 交换字符使得字符串相同
    有两个长度相同的字符串 s1 和 s2,且它们其中 只含有 字符 “x” 和 “y”,你需要通过「交换字符」的方式使这两个字符串相同。每次「交换字符」的时候,你都可以在两个字符串中各选一个字符进行交换。交换只能发生在两个不同的字符串之间,绝对不能发生在同一个字符串内部。也就是说,我们可以交换 s1[i] 和 s2[j],但不能交换 s1[i] 和 s1[j]。最后,请你返回使 s1 和 s2 相同的最小交换次数,如果没有方法能够使得这两个字符串相同,则返回 -1 。

贪心算法解题:先统计差异数,然后尽可能少的解决问题。

class Solution {
public:
    int minimumSwap(string s1, string s2) {
        int xy = 0, yx = 0;
        int n = s1.size();
        for (int i = 0; i < n; i++) {
            char a = s1[i], b = s2[i];
            if (a == 'x' and b == 'y') {
                xy++;
            }
            if (a == 'y' and b == 'x') {
                yx++;
            }
        }
        if ((xy + yx) % 2 == 1) {
            return -1;
        }
        return xy / 2 + yx / 2 + xy % 2 + yx % 2;
    }
};


  1. 统计「优美子数组」
    给你一个整数数组 nums 和一个整数 k。如果某个连续子数组中恰好有 k 个奇数数字,我们就认为这个子数组是「优美子数组」。请返回这个数组中 「优美子数组」 的数目。

记录所有奇数的下标,然后找满足条件的个数。中间穿插多少个子数组通过数学公式可以计算得出。

class Solution {
public:
    int numberOfSubarrays(vector<int>& nums, int k) {
        int n = (int)nums.size();
        int odd[n + 2], ans = 0, cnt = 0;
        for (int i = 0; i < n; ++i) {
            if (nums[i] & 1) odd[++cnt] = i;
        }
        odd[0] = -1, odd[++cnt] = n;
        for (int i = 1; i + k <= cnt; ++i) {
            ans += (odd[i] - odd[i - 1]) * (odd[i + k] - odd[i + k - 1]); 
        }
        return ans;
    }
};


  1. 移除无效的括号
    给你一个由 ‘(’、‘)’ 和小写字母组成的字符串 s。你需要从字符串中删除最少数目的 ‘(’ 或者 ‘)’ (可以删除任意位置的括号),使得剩下的「括号字符串」有效。请返回任意一个合法字符串。

先统计一边的符号数,然后遍历让另一边满足对等。也可以从左往右一遍再从右往左筛一遍。

class Solution {
public:
    string minRemoveToMakeValid(string s) {
        int left = 0;
        int right = count(begin(s), end(s), ')');
        string ans = "";
        for (auto& c : s) {
            if (c == '(') {
                if (right > 0) {
                    ans += c;
                    left++;
                    right--;
                }
            } else if (c == ')') {
                if (left > 0) {
                    ans += c;
                    left--;
                } else {
                    right--;
                }
            } else {
                ans += c;
            }
        }
        return ans;
    }
};


  1. 检查「好数组」
    给你一个正整数数组 nums,你需要从中任选一些子集,然后将子集中每一个数乘以一个 任意整数,并求出他们的和。假如该和结果为 1,那么原数组就是一个「好数组」,则返回 True;否则请返回 False。

裴蜀定理的应用。

class Solution {
public:
    bool isGoodArray(vector<int>& nums) {
        int divisor = nums[0];
        for (int num : nums) {
            divisor = gcd(divisor, num);
            if (divisor == 1) {
                break;
            }
        }
        return divisor == 1;
    }
};


  1. 平均售价
    编写SQL查询以查找每种产品的平均售价。
    average_price 应该四舍五入到小数点后两位。
# Write your MySQL query statement below
SELECT
    product_id,
    Round(SUM(sales) / SUM(units), 2) AS average_price
FROM (
    SELECT
        Prices.product_id AS product_id,
        Prices.price * UnitsSold.units AS sales,
        UnitsSold.units AS units
    FROM Prices 
    JOIN UnitsSold ON Prices.product_id = UnitsSold.product_id
    WHERE UnitsSold.purchase_date BETWEEN Prices.start_date AND Prices.end_date
) T
GROUP BY product_id


  1. 奇数值单元格的数目
    给你一个 m x n 的矩阵,最开始的时候,每个单元格中的值都是 0。另有一个二维索引数组 indices,indices[i] = [ri, ci] 指向矩阵中的某个位置,其中 ri 和 ci 分别表示指定的行和列(从 0 开始编号)。对 indices[i] 所指向的每个位置,应同时执行下述增量操作:
    ri 行上的所有单元格,加 1 。
    ci 列上的所有单元格,加 1 。
    给你 m、n 和 indices 。请你在执行完所有 indices 指定的增量操作后,返回矩阵中 奇数值单元格 的数目。

如果x,y位置想为奇数,则x行和y列只可以有一个是奇数。因此统计各自奇数个数然后直接乘一下就可以得到答案了。

class Solution {
public:
    int oddCells(int m, int n, vector<vector<int>>& indices) {
        vector<int> rows(m), cols(n);
        for (auto & index : indices) {
            rows[index[0]]++;
            cols[index[1]]++;
        }
        int oddx = 0, oddy = 0;
        for (int i = 0; i < m; i++) {
            if (rows[i] & 1) {
                oddx++;
            }
        }
        for (int i = 0; i < n; i++) {
            if (cols[i] & 1) {
                oddy++;
            }
        }
        return oddx * (n - oddy) + (m - oddx) * oddy;
    }
};

  1. 重构 2 行二进制矩阵
    给你一个 2 行 n 列的二进制数组,你需要利用 upper,lower 和 colsum 来重构这个矩阵,并以二维整数数组的形式返回它。如果有多个不同的答案,那么任意一个都可以通过本题。如果不存在符合要求的答案,就请返回一个空的二维数组。

先判断不存在的条件,保证一定存在的情况下,采用贪心法优先满足upper/lower其中之一即可

class Solution {
public:
    vector<vector<int>> reconstructMatrix(int upper, int lower, vector<int>& colsum) {
        int n = colsum.size();
        int sum = 0, two = 0;
        for (int i = 0; i < n; ++i) {
            if (colsum[i] == 2) {
                ++two;
            }
            sum += colsum[i];
        }
        if (sum != upper + lower || min(upper, lower) < two) {
            return {};
        }
        upper -= two;
        lower -= two;
        vector<vector<int>> res(2, vector<int>(n, 0));
        for (int i = 0; i < n; ++i) {
            if (colsum[i] == 2) {
                res[0][i] = res[1][i] = 1;
            } else if (colsum[i] == 1) {
                if (upper > 0) {
                    res[0][i] = 1;
                    --upper;
                } else {
                    res[1][i] = 1;
                }
            }
        }
        return res;
    }
};


你可能感兴趣的:(leetcode,算法,职场和发展)