LeetCode周赛总结——第 72 场双周赛

171 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

5996. 统计数组中相等且可以被整除的数对

题目

给你一个下标从 0 开始长度为 n 的整数数组 nums 和一个整数 k ,请你返回满足 0 <= i < j < n ,nums[i] == nums[j] 且 (i * j) 能被 k 整除的数对 (i, j) 的 数目 。

示例 1:

输入:nums = [3,1,2,2,2,1,3], k = 2 输出:4 解释: 总共有 4 对数符合所有要求:

  • nums[0] == nums[6] 且 0 * 6 == 0 ,能被 2 整除。
  • nums[2] == nums[3] 且 2 * 3 == 6 ,能被 2 整除。
  • nums[2] == nums[4] 且 2 * 4 == 8 ,能被 2 整除。
  • nums[3] == nums[4] 且 3 * 4 == 12 ,能被 2 整除。

示例 2:

输入:nums = [1,2,3,4], k = 1 输出:0 解释:由于数组中没有重复数值,所以没有数对 (i,j) 符合所有要求。

提示:

1 <= nums.length <= 100 1 <= nums[i], k <= 100

来源:力扣(LeetCode)

链接:leetcode-cn.com/problems/co…

代码

遍历即可

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

5997. 找到和为给定整数的三个连续整数

题目

给你一个整数 num ,请你返回三个连续的整数,它们的 和 为 num 。如果 num 无法被表示成三个连续整数的和,请你返回一个 空 数组。

示例 1:

输入:num = 33 输出:[10,11,12] 解释:33 可以表示为 10 + 11 + 12 = 33 。 10, 11, 12 是 3 个连续整数,所以返回 [10, 11, 12] 。

示例 2:

输入:num = 4 输出:[] 解释:没有办法将 4 表示成 3 个连续整数的和。

提示:

0 <= num <= 10^15

来源:力扣(LeetCode)

链接:leetcode-cn.com/problems/fi…

代码

直接除3获取中间值,如果以中间值为基础的三维数之和为num返回3个值,否则返回空

class Solution {
public:
    vector<long long> sumOfThree(long long num) {
        long long mid = num / 3;
        if(mid-1 + mid + mid + 1 == num){
            return {mid-1, mid, mid+1};
        }
        return {};
    }
};

5998. 拆分成最多数目的偶整数之和

题目 给你一个整数 finalSum 。请你将它拆分成若干个 互不相同 的偶整数之和,且拆分出来的偶整数数目 最多 。

比方说,给你 finalSum = 12 ,那么这些拆分是 符合要求 的(互不相同的偶整数且和为 finalSum):(2 + 10) ,(2 + 4 + 6) 和 (4 + 8) 。它们中,(2 + 4 + 6) 包含最多数目的整数。注意 finalSum 不能拆分成 (2 + 2 + 4 + 4) ,因为拆分出来的整数必须互不相同。 请你返回一个整数数组,表示将整数拆分成 最多 数目的偶整数数组。如果没有办法将 finalSum 进行拆分,请你返回一个 空 数组。你可以按 任意 顺序返回这些整数。

示例 1:

输入:finalSum = 12 输出:[2,4,6] 解释:以下是一些符合要求的拆分:(2 + 10),(2 + 4 + 6) 和 (4 + 8) 。 (2 + 4 + 6) 为最多数目的整数,数目为 3 ,所以我们返回 [2,4,6] 。 [2,6,4] ,[6,2,4] 等等也都是可行的解。

示例 2:

输入:finalSum = 7 输出:[] 解释:没有办法将 finalSum 进行拆分。 所以返回空数组。

示例 3:

输入:finalSum = 28 输出:[6,8,2,12] 解释:以下是一些符合要求的拆分:(2 + 26),(6 + 8 + 2 + 12) 和 (4 + 24) 。 (6 + 8 + 2 + 12) 有最多数目的整数,数目为 4 ,所以我们返回 [6,8,2,12] 。 [10,2,4,12] ,[6,2,4,16] 等等也都是可行的解。

提示:

1 <= finalSum <= 10^10

来源:力扣(LeetCode)

链接:leetcode-cn.com/problems/ma…

分析

如果num是奇数,那么他不可能被拆成若干个偶数的和,直接返回空。如果num是偶数则一定存在若干个偶数和为num,这时我们递增地对偶数进行深度优先搜索即可,注意这里只要找到可行解即可,所以我们一旦找到合适的情况即可退出。在代码中用flag来表示是否已找到合适的情况。

代码

class Solution {
public:
    vector<long long> ans;
    bool flag = false;
    void dfs(long long num, long long start){
        if(num < 0){
            return;
        }
        if(num == 0){
            flag = true;
            return;
        }
        for(long long i=start; num && i <= num/2; i++){
            ans.push_back(i * 2);
            dfs(num - i * 2, i+1);
            if(flag){
                break;
            }
            ans.pop_back();
        }
    }
    vector<long long> maximumEvenSplit(long long finalSum) {
        if(finalSum % 2){
            return {};
        }
        for(long long i=1; finalSum && i <= finalSum/2; i++){
            ans.push_back(i * 2);
            dfs(finalSum - i * 2, i+1);
            if(flag){
                break;
            }
            ans.pop_back();
        }
        return ans;
    }
};

5999. 统计数组中好三元组数目

题目

给你两个下标从 0 开始且长度为 n 的整数数组 nums1 和 nums2 ,两者都是 [0, 1, ..., n - 1] 的 排列 。

好三元组 指的是 3 个 互不相同 的值,且它们在数组 nums1 和 nums2 中出现顺序保持一致。换句话说,如果我们将 pos1v 记为值 v 在 nums1 中出现的位置,pos2v 为值 v 在 nums2 中的位置,那么一个好三元组定义为 0 <= x, y, z <= n - 1 ,且 pos1x < pos1y < pos1z 和 pos2x < pos2y < pos2z 都成立的 (x, y, z) 。

请你返回好三元组的 总数目 。

示例 1:

输入:nums1 = [2,0,1,3], nums2 = [0,1,2,3] 输出:1 解释: 总共有 4 个三元组 (x,y,z) 满足 pos1x < pos1y < pos1z ,分别是 (2,0,1) ,(2,0,3) ,(2,1,3) 和 (0,1,3) 。 这些三元组中,只有 (0,1,3) 满足 pos2x < pos2y < pos2z 。所以只有 1 个好三元组。

示例 2:

输入:nums1 = [4,0,1,3,2], nums2 = [4,1,0,2,3] 输出:4 解释:总共有 4 个好三元组 (4,0,3) ,(4,0,2) ,(4,1,3) 和 (4,1,2) 。

提示:

n == nums1.length == nums2.length 3 <= n <= 105 0 <= nums1[i], nums2[i] <= n - 1 nums1 和 nums2 是 [0, 1, ..., n - 1] 的排列。

来源:力扣(LeetCode)

链接:leetcode-cn.com/problems/co…

分析

对nums1做映射,然后按照树状数组去做即可

代码

class Solution {
public:
	vector<int> tree;
    long long goodTriplets(vector<int>& nums1, vector<int>& nums2) {
        int n = nums1.size();
        vector<int> pos(n);
        for (int i = 0; i < n; ++i) {
            pos[nums2[i]] = i;
        }

        long long ans = 0;
        tree.resize(n + 1);
        
        // 只需要在 [1, n-1) 范围内枚举 pos1_y 即可
        for (int i = 1; i < n - 1; ++i) {
            update(pos[nums1[i - 1]] + 1);
            int p = pos[nums1[i]];
            int t = query(p);
            ans += static_cast<long long>(t) * (n - i - p + t - 1);
        }

        return ans;
    }

    static int lowbit(int x) {
        return x & (-x);
    }

    void update(int x) {
        while (x < tree.size()) {
            ++tree[x];
            x += lowbit(x);
        }
    }

    int query(int x) {
        int ans = 0;
        while (x) {
            ans += tree[x];
            x -= lowbit(x);
        }
        return ans;
    }
};