Leetcode 第 363 场周赛题解

news/2024/7/9 5:12:37

Leetcode 第 363 场周赛题解

  • Leetcode 第 363 场周赛题解
    • 题目1:2859. 计算 K 置位下标对应元素的和
      • 思路
      • 代码
      • 复杂度分析
    • 题目2:让所有学生保持开心的分组方法数
      • 思路:排序 + 枚举
      • 代码
      • 复杂度分析
    • 题目3:最大合金数
      • 思路:二分查找
      • 代码
      • 复杂度分析
    • 题目4:完全子集的最大元素和
      • 思路
      • 代码
      • 复杂度分析

Leetcode 第 363 场周赛题解

题目1:2859. 计算 K 置位下标对应元素的和

思路

模拟。

秒杀题。

代码

/*
 * @lc app=leetcode.cn id=2859 lang=cpp
 *
 * [2859] 计算 K 置位下标对应元素的和
 */

// @lc code=start
class Solution
{
public:
    int sumIndicesWithKSetBits(vector<int> &nums, int k)
    {
        int sum = 0;
        for (int i = 0; i < nums.size(); i++)
            if (countOne(i) == k)
                sum += nums[i];
        return sum;
    }
    // 辅函数 - 求整数 x 的置位(1)的个数
    int countOne(int x)
    {
        int count = 0;
        while (x)
        {
            count += x % 2;
            x /= 2;
        }
        return count;
    }
};
// @lc code=end

注:STL函数 __builtin_popcount(i) 可以代替 countOne(i)。

复杂度分析

时间复杂度:O(n),其中 n 是数组 nums 的长度。

空间复杂度:O(1)。

题目2:让所有学生保持开心的分组方法数

思路:排序 + 枚举

条件1:这位学生被选中,并且被选中的学生人数严格大于 nums[i]。

说明 nums[i] 越小,越能满足这个条件。

条件2:这位学生没有被选中,并且被选中的学生人数 严格小于 nums[i].

说明nums[i] 越大,越能满足这个条件。

所以,我们将数组 nums 从小到大排序,优先选择 nums[i] 小的学生。

枚举选中学生的个数 i,0 <= i <= n,注意特判全选和不选,每次判断能够满足让所有学生保持开心,最终返回分组方法的数目。

代码

/*
 * @lc app=leetcode.cn id=2860 lang=cpp
 *
 * [2860] 让所有学生保持开心的分组方法数
 */

// @lc code=start
class Solution
{
public:
    int countWays(vector<int> &nums)
    {
        int n = nums.size();
        int way = 0; // 分组方法的数目
        sort(nums.begin(), nums.end());
        // 枚举选中学生个数
        for (int i = 0; i <= n; i++)
        {
            if (i == 0) // 不选学生
            {
                // 将 0 与数组的最小值(nums[0])比较
                if (0 < nums[0])
                    way++;
            }
            else if (i == n) // 全选学生
            {
                // 将 n 与数组的最大值(nums[n - 1])比较
                if (n > nums[n - 1])
                    way++;
            }
            else // 选中 前 i(1 ~ n - 1) 个学生
            {
                // 选中学生的最大值为 nums[i - 1],未选中学生的最小值为 nums[i]
                // i 必须位于 (nums[i - 1], nums[i]) 才行
                if (i > nums[i - 1] && i < nums[i])
                    way++;
            }
        }
        return way;
    }
};
// @lc code=end

复杂度分析

时间复杂度:O(nlogn),其中 n 为数组 nums 的长度。瓶颈在排序上。

空间复杂度:O(1)。

题目3:最大合金数

思路:二分查找

拆分成 k 个子问题:每台机器最多可以制造多少份合金。

子问题中,假设要制造 num 份合金,由于 num 越小,花费的钱越少,num 越多,花费的钱越多,有单调性,可以二分。

对于第 j 份金属:

  • 如果 composition[i][j] * num ≤ stock[j],那么无需购买额外的金属。
  • 如果 composition[i][j] * num > stock[j],那么需要购买额外的金属,花费为 (composition[i][j]⋅num−stock[j])⋅cost[j]。

如果总花费超过 budget,则无法制造 num 份合金,否则可以制造。

确定二分查找的上下界:

  • 二分下界:0。

  • 二分上界:粗略计算一下,假设 composition[i] 和 cost[j] 都是 1,此时可以制造最多的合金,个数为 *min_element(stock.begin(), stock.end()) + budget。

代码

/*
 * @lc app=leetcode.cn id=2861 lang=cpp
 *
 * [2861] 最大合金数
 */

// @lc code=start

// 二分查找

class Solution
{
public:
    int maxNumberOfAlloys(int n, int k, int budget, vector<vector<int>> &composition, vector<int> &stock, vector<int> &cost)
    {
        int ans = 0;
        int mx = *min_element(stock.begin(), stock.end()) + budget;
        for (vector<int> &com : composition)
        {
            auto check = [&](long long num) -> bool
            {
                long long money = 0;
                for (int i = 0; i < n; i++)
                {
                    if (stock[i] < com[i] * num)
                    {
                        money += (com[i] * num - stock[i]) * cost[i];
                        if (money > budget)
                            return false;
                    }
                }
                return true;
            };
            int left = 0, right = mx + 1;
            while (left < right)
            {
                int mid = (left + right) / 2;
                if (check(mid))
                {
                    ans = max(ans, mid);
                    left = mid + 1;
                }
                else
                    right = mid;
            }
        }
        return ans;
    }
};
// @lc code=end

复杂度分析

时间复杂度:O(knlogU),其中 U=min⁡(stock)+budget。

空间复杂度:O(1)。

题目4:完全子集的最大元素和

思路

按照下标的 core 值分组。

定义 core(n) 为 n 除去完全平方因子后的剩余结果,即 n 的所有出现次数为奇数的质因子相乘。

根据题意,如果同一组中有两个数,它们的下标的 core 值不同,那么这两个数相乘,就不是一个完全平方数。

所以,同一组内的数字下标的 core 值必须都一样。

那么按照下标的 core 值分组,累加同一组的元素和,最大元素和即为答案。

代码

/*
 * @lc app=leetcode.cn id=2862 lang=cpp
 *
 * [2862] 完全子集的最大元素和
 */

// @lc code=start
class Solution
{
public:
    long long maximumSum(vector<int> &nums)
    {
        int n = nums.size();
        vector<long long> sum(n + 1, 0);
        for (int i = 1; i <= n; i++)
            sum[core(i)] += nums[i - 1];
        return *max_element(sum.begin(), sum.end());
    }
    // 辅函数 - 得到 n 除去完全平方因子后的剩余结果 res
    int core(int n)
    {
        int res = 1;
        for (int i = 2; i * i <= n; i++)
        {
            int count = 0;
            while (n % i == 0)
            {
                count++;
                n /= i;
            }
            if (count % 2 == 1)
                res *= i;
        }
        if (n > 1)
            res *= n;
        return res;
    }
};
// @lc code=end

复杂度分析

时间复杂度:O( n n n\sqrt{n} nn ),其中 n 为数组 nums 的长度。

空间复杂度:O(n),其中 n 为数组 nums 的长度。


http://lihuaxi.xjx100.cn/news/1698410.html

相关文章

【学习笔记】[ABC323G] Inversion of Tree

前置知识&#xff1a;矩阵树定理&#xff0c;特征多项式 省流&#xff1a;板子缝合题。可以复习一下线性代数的基本知识。 定义 P u > P v P_u>P_v Pu​>Pv​的边价值为 x x x&#xff0c; P u < P v P_u<P_v Pu​<Pv​的边价值为 1 1 1&#xff0c;那么我…

Jmeter测试关联接口

Jmeter用于接口测试时&#xff0c;后一个接口经常需要用到前一次接口返回的结果&#xff0c;本文主要介绍jmeter通过正则表达式提取器来实现接口关联的方式&#xff0c;可供参考。 一、实例场景&#xff1a; 有如下两个接口&#xff0c;通过正则表达式提取器&#xff0c;将第一…

【数据集资源】大数据资源-数据集下载方法-汇总

大概包含10个领域数据集&#xff1a; 金融 交通 商业 推荐系统 医疗健康 图像数据 视频数据 音频数据 自然语言处理 社会数据 处理后的科研和竞赛数据 1、huggingface的数据下载方式&#xff1a; 1.进入官网数据集列&#xff1a;Hugging Face – The AI community building the…

用3D扫描生成合成数据

合成数据集&#xff08;Synthetic Datasets&#xff09;正在成为计算机视觉模型训练的标准部分。 虽然新工具使合成数据集变得更容易访问&#xff0c;但除了标准机器学习过程之外&#xff0c;许多工具还需要对 3D 建模有基本的了解。 最简单的捷径是从现实世界中获取现有对象并…

分频流水灯

在开发板中&#xff0c;有一个内置的时钟周期&#xff0c;为100MHZ&#xff0c;我们需要使用这样一个时钟信号来设计一个1HZ的流水灯&#xff08;使用8个led灯&#xff09;&#xff0c;也就是一秒钟有一个灯是亮起的&#xff0c;依次从左到右。 另外还有一个低有效的复位使能端…

WuThreat身份安全云-TVD每日漏洞情报-2023-10-13

漏洞名称:libcue <2.2.1 越权访问漏洞 漏洞级别:高危 漏洞编号:CVE-2023-43641,CNNVD-202310-579 相关涉及:系统-alpine_edge-libcue-*-Up to-(excluding)-2.2.1-r0- 漏洞状态:未定义 参考链接:https://tvd.wuthreat.com/#/listDetail?TVD_IDTVD-2023-25092 漏洞名称:科大…

1024程序员节日快乐

在这个1024程序员节日&#xff0c;我想和大家分享一个故事&#xff0c;同时展示一些有趣的技术。 曾经有一个年轻的程序员&#xff0c;名叫小明。他热爱编程&#xff0c;对技术充满了好奇心和激情。一天&#xff0c;他遇到了一个挑战&#xff1a;创建一个智能家居系统&#xf…

k8s基础 随笔

写个笔记&#xff0c;后面再完善 部署第一个应用 为什么先实战水平扩缩&#xff1f;因为这个最简单&#xff0c;首先来部署一个喜闻乐见的nginx kubectl create deployment web --imagenginx:1.14 --dry-run -o yaml > web.yaml --dry-run表示试运行&#xff0c;试一下看…