每日算法刷题计划Day20 6.2:leetcode二分答案3道题,用时1h20min

news2025/6/4 16:54:14
9.3048.标记所有下标的最早秒数(中等)

3048. 标记所有下标的最早秒数 I - 力扣(LeetCode)

思想

1.给你两个下标从 1 开始的整数数组 nums 和 changeIndices ,数组的长度分别为 n 和 m 。
一开始,nums 中所有下标都是未标记的,你的任务是标记 nums 中 所有 下标。
从第 1 秒到第 m 秒(包括 第 m 秒),对于每一秒 s ,你可以执行以下操作 之一 :

  • 选择范围 [1, n] 中的一个下标 i ,并且将 nums[i] 减少 1 。
  • 如果 nums[changeIndices[s]] 等于 0 ,标记 下标 changeIndices[s] 。
  • 什么也不做。
    请你返回范围 [1, m] 中的一个整数,表示最优操作下,标记 nums 中 所有 下标的 最早秒数 ,如果无法标记所有下标,返回 -1 。
    2.单调性检验:秒数越少,越不可能标记nums中所有下标,所以存在一个最少秒数
    3.本题难点在于check函数怎么写,我的思路是changeIndices中下标i最后一次出现的位置(核心) 取消标记,只要之前的次数大于nums[i-1](因为i在[1,m])就能成功标记,所以需要记录下标-最后出现位置的数据结构,用map和vector<pair<int,int>>都可以,但要注意map只能按键排序,vector按first和second都行,但是最好直接记录最后出现的位置-下标
    4.学习别人思路:
    (1)也是记录i在chanegIndices最后一次出现的位置,但是直接用vector<int>存储即可,因为i属于[0,n),且无需像我那样一点要从最后找到第一次出现位置last[i],直接顺序迭代更新即可,用后面的值覆盖前面的值
    (2)然后利用一个cnt变量记录可以消耗的值
  • last[i],即判断cnt和nums[i]的大小
  • 不是last[i],++cnt
代码

c++:

class Solution {
public:
    bool check(vector<int>& nums, vector<int>& changeIndices, int mid) {
        vector<pair<int, int>> v; // 最后位置-下标
        int n = nums.size(), m = changeIndices.size();
        for (int i = 1; i <= n; ++i) {
            int j = mid - 1;
            while (j >= 0 && changeIndices[j] != i)
                --j;
            if (j < 0)
                return false;
            v.emplace_back(j, i);
        }
        sort(v.begin(), v.end());
        int cnt = 0; // 用了几个
        for (const auto x : v) {
            int last = x.first, id = x.second;
            if (last - cnt < nums[id - 1])
                return false;
            cnt += nums[id - 1] + 1;
        }
        return true;
    }
    int earliestSecondToMarkIndices(vector<int>& nums,
                                    vector<int>& changeIndices) {
        int res = -1;
        int n = nums.size(), m = changeIndices.size();
        set<int> s;
        for (const int x : changeIndices)
            s.insert(x);
        if (s.size() < n)
            return -1;
        int left = 1, right = m;
        while (left <= right) {
            int mid = left + ((right - left) >> 1);
            if (check(nums, changeIndices, mid)) {
                res = mid;
                right = mid - 1;
            } else
                left = mid + 1;
        }
        return res;
    }
};

学习check函数:

bool check(vector<int>& nums, vector<int>& changeIndices, int mid) {
	int n = nums.size(), m = changeIndices.size();
	vector<int> lasti(n, -1); // 最后位置
	for (int i = 0; i < mid; ++i)
		lasti[changeIndices[i] - 1] = i;
	for (int i = 0; i < n; ++i) {
		if (lasti[i] == -1)
			return false;
	}
	int cnt = 0; // 可用几个
	for (int i = 0; i < mid; ++i) {
		int id = changeIndices[i] - 1;
		if (lasti[id] == i) {
			if (cnt < nums[id])
				return false;
			cnt -= nums[id];
		} else
			++cnt;
	}
	return true;
}

2.2 求最大

在练习时,请注意「求最小」和「求最大」的二分写法上的区别
前面的「求最小」和二分查找求「排序数组中某元素的第一个位置」是类似的,按照红蓝染色法,左边是不满足要求的(红色),右边则是满足要求的(蓝色)。
「求最大」的题目则相反,左边是满足要求的(蓝色),右边是不满足要求的(红色)。这会导致二分写法和上面的「求最小」有一些区别。
以开区间二分为例:
求最小:check(mid) == true 时更新 right = mid,反之更新 left = mid,最后返回 right。
求最大:check(mid) == true 时更新 left = mid,反之更新 right = mid,最后返回 left。
对于开区间写法,简单来说 check(mid) == true 时更新的是谁,最后就返回谁。相比其他二分写法,开区间写法不需要思考加一减一等细节,推荐使用开区间写二分。

1.套路

c++:

class Solution {
public:
    bool check(vector<int>& citations, int mid) {
        
    }
    int hIndex(vector<int>& citations) {
        int res = 0;
        int n = citations.size();
        int left = 0, right = min(n, citations[n - 1]);
        while (left <= right) {
            int mid = left + ((right - left) >> 1);
            if (check(citations, mid)) {
                res = mid;
                left = mid + 1; // 还可能有更大的值满足条件
            } else
                right = mid - 1;
        }
        return res;
    }
};

2.题目描述

1.给你一个整数数组 citations ,其中 citations[i] 表示研究者的第 i 篇论文被引用的次数,citations 已经按照 非降序排列。计算并返回该研究者的 h 指数(答案)
h 指数的定义:h 代表“高引用次数”(high citations),一名科研人员的 h 指数是指他(她)的 (n 篇论文中)至少 有 h 篇论文分别被引用了至少 h 次(条件)
2.给你一个 下标从 0 开始 的整数数组 candies 。数组中的每个元素表示大小为 candies[i] 的一堆糖果。你可以将每堆糖果分成任意数量的 子堆 ,但 无法 再将两堆合并到一起。
另给你一个整数 k 。你需要将这些糖果分配给 k 个小孩,使每个小孩分到 相同 数量的糖果(条件)。每个小孩可以拿走 至多一堆 糖果,有些糖果可能会不被分配。
返回每个小孩可以拿走的 最大糖果数目(答案) 。

3.学习经验

(1)求最大合法区间在右边,所以满足条件是left=mid+1,而求最小是right=mid-1

1. 275.H指数II

275. H 指数 II - 力扣(LeetCode)

思想

1.给你一个整数数组 citations ,其中 citations[i] 表示研究者的第 i 篇论文被引用的次数,citations 已经按照 非降序排列 。计算并返回该研究者的 h 指数。
h 指数的定义:h 代表“高引用次数”(high citations),一名科研人员的 h 指数是指他(她)的 (n 篇论文中)至少 有 h 篇论文分别被引用了至少 h 次。
2.单调性检验:若h越大,越不可能满足条件,但若h满足条件,小于h的值肯定满足条件,即至少有 h 篇论文分别被引用了至少h 次,那肯定有小于h 篇论文分别被引用了至少h 次,满足单调性
3.我的思想:是找到第一个大于mid的引用次数,然后判断文章数,但这样要花费时间找第一个大于mid的引用次数的下标
4.学习:可以直接假设文章数为mid,然后判断n-mid处的引用次数是否大于mid,O(1)的复杂度

代码

c++:

class Solution {
public:
    bool check(vector<int>& citations, int mid) {
        int n = citations.size();
        int i = 0;
        while (i < n && citations[i] < mid)
            ++i;
        if (i == n)
            return false;
        if (n - i >= mid)
            return true;
        else
            return false;
    }
    int hIndex(vector<int>& citations) {
        int res = 0;
        int n = citations.size();
        int left = 0, right = min(n, citations[n - 1]);
        while (left <= right) {
            int mid = left + ((right - left) >> 1);
            if (check(citations, mid)) {
                res = mid;
                left = mid + 1; // 还可能有更大的值满足条件
            } else
                right = mid - 1;
        }
        return res;
    }
};

学习:

bool check(vector<int>& citations, int mid) {
	int n = citations.size();
	if (mid == 0 || citations[n - mid] >= mid) // mid有可能为0
		return true;
	else
		return false;
}
2. 2226.每个小孩最多能分到多少糖果

2226. 每个小孩最多能分到多少糖果 - 力扣(LeetCode)

思想

1.给你一个 下标从 0 开始 的整数数组 candies 。数组中的每个元素表示大小为 candies[i] 的一堆糖果。你可以将每堆糖果分成任意数量的 子堆 ,但 无法 再将两堆合并到一起。
另给你一个整数 k 。你需要将这些糖果分配给 k 个小孩,使每个小孩分到 相同 数量的糖果。每个小孩可以拿走 至多一堆 糖果,有些糖果可能会不被分配。
返回每个小孩可以拿走的 最大糖果数目 。
2.单调性检验:糖果数目越大,越不能均分,所以存在一个最大糖果数目,且小于该糖果数目的值也一定满足条件,满足单调性
3.一个堆只能分一次子堆,就是商

代码

c++:

class Solution {
public:
    bool check(vector<int>& candies, long long k, long long mid) {
        if (mid == 0) // 注意下面除数不能为0
            return true;
        long long cnt = 0;
        for (const int x : candies) {
            cnt += (long long)x / mid;
            if (cnt >= k)
                return true;
        }
        return false;
    }
    int maximumCandies(vector<int>& candies, long long k) {
        int res = 0;
        long long sum = 0;
        for (const int x : candies)
            sum += x;
        if (sum < k)
            return 0;
        long long left = 0, right = sum / k;
        while (left <= right) {
            long long mid = left + ((right - left) >> 1);
            if (check(candies, k, mid)) {
                res = mid;
                left = mid + 1;
            } else
                right = mid - 1;
        }
        return res;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2396942.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity + HybirdCLR热更新 入门篇

官方文档 HybridCLR | HybridCLRhttps://hybridclr.doc.code-philosophy.com/docs/intro 什么是HybirdCLR? HybridCLR&#xff08;原名 huatuo&#xff09;是一个专为 Unity 项目设计的C#热更新解决方案&#xff0c;它通过扩展 IL2CPP 运行时&#xff0c;使其支持动态加载和…

ElasticSearch迁移至openGauss

Elasticsearch 作为一种高效的全文搜索引擎&#xff0c;广泛应用于实时搜索、日志分析等场景。而 openGauss&#xff0c;作为一款企业级关系型数据库&#xff0c;强调事务处理与数据一致性。那么&#xff0c;当这两者的应用场景和技术架构发生交集时&#xff0c;如何实现它们之…

【C语言极简自学笔记】项目开发——扫雷游戏

一、项目概述 1.项目背景 扫雷是一款经典的益智游戏&#xff0c;由于它简单而富有挑战性的玩法深受人们喜爱。在 C 语言学习过程中&#xff0c;开发扫雷游戏是一个非常合适的实践项目&#xff0c;它能够综合运用 C 语言的多种基础知识&#xff0c;如数组、函数、循环、条件判…

Maven概述,搭建,使用

一.Maven概述 Maven是Apache软件基金会的一个开源项目,是一个有优秀的项目构建(创建)工具,它用来帮助开发者管理项目中的jar,以及jar之间的依赖关系,完成项目的编译,测试,打包和发布等工作. 我在当前学习阶段遇到过的jar文件: MySQL官方提供的JDBC驱动文件,通常命名为mysql-…

Unity 环境搭建

Unity是一款游戏引擎&#xff0c;可用于开发各种类型的游戏和交互式应用程序。它由Unity Technologies开发&#xff0c;并在多个平台上运行&#xff0c;包括Windows、macOS、Linux、iOS、Android和WebGL。Unity也支持虚拟现实(VR)和增强现实(AR)技术&#xff0c;允许用户构建逼…

【入门】【练9.3】 加四密码

| 时间限制&#xff1a;C/C 1000MS&#xff0c;其他语言 2000MS 内存限制&#xff1a;C/C 64MB&#xff0c;其他语言 128MB 难度&#xff1a;中等 分数&#xff1a;100 OI排行榜得分&#xff1a;12(0.1*分数2*难度) 出题人&#xff1a;root | 描述 要将 China…

使用 SASS 与 CSS Grid 实现鼠标悬停动态布局变换效果

最终效果概述 页面为 3x3 的彩色格子网格&#xff1b;当鼠标悬停任意格子&#xff0c;所在的行和列被放大&#xff1b;使用纯 CSS 实现&#xff0c;无需 JavaScript&#xff1b;利用 SASS 的模块能力大幅减少冗余代码。 HTML 结构 我们使用非常基础的结构&#xff0c;9 个 .i…

Spring如何实现组件扫描与@Component注解原理

Spring如何实现组件扫描与Component注解原理 注解配置与包扫描的实现机制一、概述&#xff1a;什么是注解配置与包扫描&#xff1f;二、处理流程概览三、注解定义ComponentScope 四、核心代码结构1. ClassPathScanningCandidateComponentProvider2. ClassPathBeanDefinitionSca…

达梦数据库 Windows 系统安装教程

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家、CSDN平台优质创作者&#xff0c;高级开发工程师&#xff0c;数学专业&#xff0c;10年以上C/C, C#, Java等多种编程语言开发经验&#xff0c;拥有高级工程师证书&#xff1b;擅长C/C、C#等开发语言&#xff0c;熟悉Java常用开…

【Java EE初阶】计算机是如何⼯作的

计算机是如何⼯作的 计算机发展史冯诺依曼体系&#xff08;Von Neumann Architecture&#xff09;CPU指令&#xff08;Instruction&#xff09;CPU 是如何执行指令的&#xff08;重点&#xff09; 操作系统&#xff08;Operating System&#xff09;进程(process) 进程 PCB 中的…

RAG理论基础总结

目录 概念 流程 文档收集和切割 读取文档 转换文档 写入文档 向量转换和存储 搜索请求构建 向量存储工作原理 向量数据库 文档过滤和检索 检索前 检索 检索后 查询增强和关联 QuestionAnswerAdvisor查询增强 高级RAG架构 自纠错 RAG&#xff08;C-RAG&#xf…

列表推导式(Python)

[表达式 for 变量 in 列表] 注意&#xff1a;in后面不仅可以放列表&#xff0c;还可以放range ()可迭代对象 [表达式 for 变量 in 列表 if 条件]

一天搞懂深度学习--李宏毅教程笔记

目录 1. Introduction of Deep Learning1.1. Neural Network - A Set of Function1.2. Learning Target - Define the goodness of a function1.3. Learn! - Pick the best functionLocal minimaBackpropagation 2. Tips for Training Deep Neural Network3. Variant of Neural…

python打卡训练营打卡记录day43

复习日 作业&#xff1a; kaggle找到一个图像数据集&#xff0c;用cnn网络进行训练并且用grad-cam做可视化 进阶&#xff1a;并拆分成多个文件 数据集来源&#xff1a;Flowers Recognition 选择该数据集原因&#xff1a; 中等规模&#xff1a;4242张图片 - 训练快速但足够展示效…

【QT控件】QWidget 常用核心属性介绍 -- 万字详解

目录 一、控件概述 二、QWidget 核心属性 2.1 核心属性概览 2.2 enabled ​编辑 2.3 geometry 2.4 windowTitle 2.5 windowIcon 使用qrc文件管理资源 2.6 windowOpacity 2.7 cursor 2.8 font ​编辑 2.9 toolTip 2.10 focusPolicy 2.11 styleSheet QT专栏&…

uniapp-商城-77-shop(8.2-商品列表,地址信息添加,级联选择器picker)

地址信息,在我们支付订单上有这样一个接口,就是物流方式,一个自提,我们就显示商家地址。一个是外送,就是用户自己填写的地址。 这里先说说用户的地址添加。需要使用到的一些方式方法,主要有关于地址选择器,就是uni-data-picker级联选择。 该文介绍了电商应用中地址信息处…

【第16届蓝桥杯 | 软件赛】CB组省赛第二场

个人主页&#xff1a;Guiat 归属专栏&#xff1a;算法竞赛 文章目录 A. 密密摆放&#xff08;5分填空题&#xff09;B. 脉冲强度之和&#xff08;5分填空题&#xff09;C. 25 之和D. 旗帜E. 数列差分F. 树上寻宝G. 翻转硬币H. 破解信息 正文 总共8道题。 A. 密密摆放&#xff0…

AR/MR实时光照阴影开发教程

一、效果演示 1、PICO4 Ultra MR 发光的球 2、AR实时光照 二、实现原理 PICO4 Ultra MR开发时&#xff0c;通过空间网格能力扫描周围环境&#xff0c;然后将扫描到的环境网格材质替换为一个透明材质并停止扫描&#xff1b;基于Google ARCore XR Plugin和ARFoundation进行安卓手…

【汽车电子入门】一文了解LIN总线

前言&#xff1a;LIN&#xff08;Local Interconnect Network&#xff09;总线&#xff0c;也就是局域互联网的意思&#xff0c;它的出现晚于CAN总线&#xff0c;于20世纪90年代末被摩托罗拉、宝马、奥迪、戴姆勒、大众以及沃尔沃等多家公司联合开发&#xff0c;其目的是提供一…

【笔记】为 Python 项目安装图像处理与科学计算依赖(MINGW64 环境)

&#x1f4dd; 为 Python 项目安装图像处理与科学计算依赖&#xff08;MINGW64 环境&#xff09; &#x1f3af; 安装目的说明 本次安装是为了在 MSYS2 的 MINGW64 工具链环境中&#xff0c;搭建一个完整的 Python 图像处理和科学计算开发环境。 主要目的是支持以下类型的 Pyth…