Leetcode 第 363 场周赛题解

news/2024/10/18 18:28:01/

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;}elseright = 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 除去完全平方因子后的剩余结果 resint 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://www.ppmy.cn/news/1165535.html

相关文章

..\FreeRTOS\include\FreeRTOS.h(1277): error: #65: expected a “;“出现的这个错误标志解决方法

..\FreeRTOS\include\FreeRTOS.h(1277): error: #65: expected a ";" 近来写软件过程中&#xff0c;当在某一个.C文件中我申明了FreeRTOS.h文件&#xff0c;结果呢编译是出现报错了 经过查找&#xff0c;是因为我在另外一个文件声明了 #include <stdbool.h> …

java后端调用接口Basic auth认证

该方法接收一个JSON字符串参数phoneNum 内容&#xff1a; {"phone":"13712312312"} 然后解析参数中的手机号&#xff0c;作为data去调用URL接口&#xff0c;接收接口返回的复合JSON并解析&#xff0c;拿到想要的数据public String queryUserResumeURLIn…

华纳云:linux系统如何挂载存储数据

在Linux系统中&#xff0c;挂载存储设备是将额外的磁盘、分区或网络共享附加到文件系统的过程&#xff0c;以便将其用于存储数据。以下是挂载存储数据的一般步骤&#xff1a; 1. 准备存储设备&#xff1a; 如果您要挂载本地磁盘或分区&#xff0c;请确保它已经物理连接到服务器…

Qt窗体间值的传递方法

本文介绍Qt窗体间值的传递方法。 基于图形窗口的应用程序在执行过程中&#xff0c;有时候会涉及到窗口间传递数据&#xff0c;如常见的父窗口-子窗口间&#xff0c;子窗口-子窗口间&#xff0c;传递数据的方式有多种&#xff0c;常见的有通过全局变量&#xff0c;静态变量&…

Android之使用GirdLayoutManager时候给Item设置边距

效果&#xff1a; 一、自定义设置边距方法 SpaceItemDecoration.java package com.custom.jfrb.ui.jfrb.finishedProduct; //自己包名位置import android.graphics.Rect; import android.view.View;import androidx.annotation.NonNull; import androidx.recyclerview.widg…

javascript var let const 区别

javascript var let const 区别 在 JavaScript 中&#xff0c;有三种常用的变量声明方式&#xff1a;var、let和const。它们在作用域、可变性和重复声明等方面有一些区别。 var&#xff1a;使用var关键字声明的变量是函数作用域或全局作用域的变量。它的作用范围在包含它的函…

GEE打开NASA-USDA增强型SMAP全球土壤水分数据(10KM,2015-2020)

NASA-USDA增强型SMAP全球土壤水分数据&#xff08;10KM&#xff0c;2015-2020&#xff09; 一、GEE登录 首先需要注册一个Goole账号 在该网站中注册 二、创建GEE项目 按照上面操作&#xff0c;注册完后会创建一个自己的GEE项目。&#xff08;没有的话也可以从下面这个网站…

【操作系统】MBR主引导目录结构以及作用

一.BIOS和MBR的交接仪式 当BIOS检测完内存、显卡&#xff0c;把硬盘等外设加载进来后&#xff0c;便开始在内存0X00~0X3FF处建立起数据结构、中断向量表&#xff0c;并且填写中断例程。完成这一系列的操作后便开始寻找硬盘&#xff08;如果硬盘不止一个的话&#xff0c;则会通过…