LeetCode-287 寻找重复数 二分法

LeetCode-287 寻找重复数 二分法

287. 寻找重复数

给定一个包含 n + 1 个整数的数组 nums ,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。

假设 nums 只有 一个重复的整数 ,找出 这个重复的数 。

你设计的解决方案必须不修改数组 nums 且只用常量级 O(1) 的额外空间。

示例 1:

输入:nums = [1,3,4,2,2]
输出:2
示例 2:

输入:nums = [3,1,3,4,2]
输出:3
示例 3:

输入:nums = [1,1]
输出:1
示例 4:

输入:nums = [1,1,2]
输出:1

提示:

1 <= n <= 105
nums.length == n + 1
1 <= nums[i] <= n
nums 中 只有一个整数 出现 两次或多次 ,其余整数均只出现 一次

进阶:

如何证明 nums 中至少存在一个重复的数字?
你可以设计一个线性级时间复杂度 O(n) 的解决方案吗?

对于寻找重复数这种题,常规做法的话如哈希都可以做,但是本题的要求是不修改数组 nums 且只用常量级 O(1) 的额外空间。注意到本题给出了一个常规寻找重复数题目没有的条件:其数字都在 1 到 n 之间(包括 1 和 n)

二分法

记要找的重复数为 target,cnt(i)cnt(i)cnt(i) 表示给定数组 numsnumsnums 中不大于 iii 的数字个数。比如 cnt(3)cnt(3)cnt(3) 就是 numsnumsnums 中1, 2, 3的个数之和,显然 cnt(i)cnt(i)cnt(i)递增的。以数组 {1, 2, 3, 3, 4 ,5} 为例:

iii12345
cnt(i)cnt(i)cnt(i)12456

根据上面提到的额外的条件,我们可以发现这样一个规律:对于小于 target 的数 i,cnt(i)=icnt(i)=icnt(i)=i​,对于大于等于 target 的数 i,cnt(i)>icnt(i)>icnt(i)>i​ 。因此,我们要找的重复数 target,就是最小的使得 cnt(i)>icnt(i)>icnt(i)>i​ 的数字 i。可以看到,上例中 target 为3,当 i<3i<3i<3 时,cnt(i)=icnt(i)=icnt(i)=i,当 i≥3i\ge3i3 时,cnt(i)>icnt(i)>icnt(i)>i

而我们回顾以下常规的二分法,是这样的:对于一个递增(有序)的序列 numsnumsnums 和 给定值 target,我们要找到最小的使得 nums[i]>targetnums[i]>targetnums[i]>target 的数字 i

这就是这个题为什么可以使用二分法,递增序列当然是使用二分法的前提,我们用 cnt(i)cnt(i)cnt(i) 来合理地构造;然后根据具体的要找的条件来更新结果就好了。

常规二分法代码(返回索引):

int bin_search(vector<int>& nums, int target) {int n = nums.size();int l = 0, r = n-1;int mid;while (l<=r) {mid = (l+r) >> 1;if (nums[mid] < target) l = mid + 1;else if (nums[mid] > target)r = mid - 1;elsebreak;}return mid;
}

本题代码(C++):


class Solution {
public:int findDuplicate(vector<int>& nums) {int n = nums.size();int l = 0, r = n-1, ans = -1;while (l<=r) {int mid = (l+r) >> 1;int cnt = 0;for (int i=0; i<n; ++i) {				// 计算cnt(mid),这里的mid就是我们上面公式中的icnt += nums[i] <= mid ? 1 : 0;}if (cnt<=mid) {				// 比较cnt(mid)和midl = mid + 1;}else {								// 若cnt(mid)>mid,则mid有可能是target:所有满足cnt(mid)>mid的值中最小的mid值即为target(即代码中的ans)ans = mid;r = mid - 1;}}return ans;}
};

双指针

我们将数组转换为链表,即将下标 nnn 和数 nums[n]nums[n]nums[n] 建立一个映射关系 f(n),将 nnn 作为下一个元素 f(n)f(n)f(n) 的志向。数组元素的取值范围在 [1,n][1,n][1,n] 之间,而数组长度为 n+1n+1n+1 ,所以按照数组元素取值一定不可能越界。然后利用链表判环的快慢指针方法找到相同元素。

详见:https://leetcode.cn/problems/find-the-duplicate-number/solution/287xun-zhao-zhong-fu-shu-by-kirsche/

class Solution {
public:int findDuplicate(vector<int>& nums) {int fast = 0, slow = 0;while (true) {fast = nums[nums[fast]];slow = nums[slow];if (slow == fast) break;}fast = 0;while (true) {slow = nums[slow];fast = nums[fast];if (slow == fast) return fast;}}
};

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

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

相关文章

对某公司一次弱口令到存储型xss挖掘

转自我的奇安信攻防社区文章:https://forum.butian.net/share/885 免责声明: 渗透过程为授权测试,所有漏洞均以提交相关平台,博客目的只为分享挖掘思路和知识传播** 涉及知识: xss注入及xss注入绕过 挖掘过程: 某次针对某目标信息搜集无意发现某工程公司的项目招标平台 …

C++11新特性选讲 语言部分 侯捷

C11新特性选讲 语言部分 侯捷 本课程分为两个部分&#xff1a;语言的部分和标准库的部分。只谈新特性&#xff0c;并且是选讲。 本文为语言部分笔记。 语言 Variadic Templatesmove semanticsautoRange-based for loopInitializer listLambdas… 标准库 type_traitsunodered…

java安全(二):JDBC|sql注入|预编译

给个关注&#xff1f;宝儿&#xff01; 给个关注&#xff1f;宝儿&#xff01; 给个关注&#xff1f;宝儿&#xff01; 1 JDBC基础 JDBC(Java Database Connectivity)是Java提供对数据库进行连接、操作的标准API。Java自身并不会去实现对数据库的连接、查询、更新等操作而是通…

java安全(三)RMI

给个关注&#xff1f;宝儿&#xff01; 给个关注&#xff1f;宝儿&#xff01; 给个关注&#xff1f;宝儿&#xff01; 1.RMI 是什么 RMI(Remote Method Invocation)即Java远程方法调用&#xff0c;RMI用于构建分布式应用程序&#xff0c;RMI实现了Java程序之间跨JVM的远程通信…

LeetCode-726 原子的数量 递归

LeetCode-726 原子的数量 递归 题目链接&#xff1a;LeetCode-726 原子的数量 给你一个字符串化学式 formula &#xff0c;返回 每种原子的数量 。 原子总是以一个大写字母开始&#xff0c;接着跟随 0 个或任意个小写字母&#xff0c;表示原子的名字。 如果数量大于 1&#xf…

java安全(四) JNDI

给个关注&#xff1f;宝儿&#xff01; 给个关注&#xff1f;宝儿&#xff01; 给个关注&#xff1f;宝儿&#xff01; 1.JNDI JNDI(Java Naming and Directory Interface)是Java提供的Java 命名和目录接口。通过调用JNDI的API应用程序可以定位资源和其他程序对象。JNDI是Java…

二叉树的层序遍历和前中后序遍历代码 迭代/递归

前中后序遍历&#xff08;DFS&#xff09; 首先我们要明确前中后序遍历的顺序&#xff1a; 前序&#xff1a;中左右中序&#xff1a;左中右后序&#xff1a;左右中 前中后序遍历的递归代码和迭代代码分别有各自的框架&#xff0c;然后根据遍历顺序调整记录元素的位置即可。 …

java安全(五)java反序列化

给个关注&#xff1f;宝儿&#xff01; 给个关注&#xff1f;宝儿&#xff01; 给个关注&#xff1f;宝儿&#xff01; 1. 序列化 在调用RMI时,发现接收发送数据都是反序列化数据. 例如JSON和XML等语言,在网络上传递信息,都会用到一些格式化数据,大多数处理方法中&#xff0c…

git merge和rebase的区别与选择

git merge和rebase的区别与选择 转自&#xff1a;https://github.com/geeeeeeeeek/git-recipes/wiki/5.1-%E4%BB%A3%E7%A0%81%E5%90%88%E5%B9%B6%EF%BC%9AMerge%E3%80%81Rebase-%E7%9A%84%E9%80%89%E6%8B%A9#merge BY 童仲毅&#xff08;geeeeeeeeekgithub&#xff09; 这是一篇…

java安全(六)java反序列化2,ysoserial调试

给个关注&#xff1f;宝儿&#xff01; 给个关注&#xff1f;宝儿&#xff01; 给个关注&#xff1f;宝儿&#xff01; ysoserial 下载地址&#xff1a;https://github.com/angelwhu/ysoserial ysoserial可以让⽤户根据⾃⼰选择的利⽤链&#xff0c;⽣成反序列化利⽤数据&…

C++面试常见问题一

C面试常见问题一 转自&#xff1a;https://oldpan.me/archives/c-interview-answer-1 原作者&#xff1a;[oldpan][https://oldpan.me/] 前言 这里收集市面上所有的关于算法和开发岗最容易遇到的关于C方面的问题&#xff0c;问题信息来自互联网以及牛客网的C面试题目汇总。答题…

java安全(七) 反序列化3 CC利用链 TransformedMap版

给个关注&#xff1f;宝儿&#xff01; 给个关注&#xff1f;宝儿&#xff01; 给个关注&#xff1f;宝儿&#xff01; 目录图解代码demo涉及的接口与类&#xff1a;TransformedMapTransformerConstantTransformerInvokerTransformerChainedTransformerdome理解总结&#xff1a…

C++编译时多态和运行时多态

C编译时多态和运行时多态 作者&#xff1a;melonstreet 出处&#xff1a;https://www.cnblogs.com/QG-whz/p/5132745.html 本文版权归作者和博客园共有&#xff0c;欢迎转载&#xff0c;但未经作者同意必须保留此段声明&#xff0c;且在文章页面明显位置给出原文连接&#xff0…

java安全(八)TransformedMap构造POC

给个关注&#xff1f;宝儿&#xff01; 给个关注&#xff1f;宝儿&#xff01; 给个关注&#xff1f;宝儿&#xff01; 上一篇构造了一个了commons-collections的demo 【传送门】 package test.org.vulhub.Ser;import org.apache.commons.collections.Transformer; import org…

Pytorch Tutorial 使用torch.autograd进行自动微分

Pytorch Tutorial 使用torch.autograd进行自动微分 本文翻译自 PyTorch 官网教程。 原文&#xff1a;https://pytorch.org/tutorials/beginner/basics/autogradqs_tutorial.html#optional-reading-tensor-gradients-and-jacobian-products 在训练神经网络时&#xff0c;最常使用…

TVM:编译深度学习模型快速上手教程

TVM&#xff1a;编译深度学习模型快速上手教程 本文将展示如何使用 Relay python 前端构建一个神经网络&#xff0c;并使用 TVM 为 Nvidia GPU 生成一个运行时库。 注意我们需要再构建 TVM 时启用了 cuda 和 llvm。 TVM支持的硬件后端总览 在本教程中&#xff0c;我们使用 cu…

TVM:设计与架构

TVM&#xff1a;设计与架构 本文档适用于想要了解 TVM 架构和/或积极开发项目的开发人员。页面组织如下&#xff1a; 示例编译流程概述了 TVM 将模型的高层描述转换为可部署模块所采取的步骤。要开始使用&#xff0c;请先阅读本节。 逻辑架构组件部分描述了逻辑组件。后面的部…

递归+回溯

递归-回溯 本文参考自代码随想录视频&#xff1a; https://www.bilibili.com/video/BV1cy4y167mM https://www.bilibili.com/video/BV1ti4y1L7cv 递归回溯理论基础 只要有递归&#xff0c;就会有回溯&#xff0c;递归函数的下面的部分通常就是回溯的逻辑。 回溯是纯暴力的搜索…

Nvidia CUDA初级教程1 CPU体系架构综述

Nvidia CUDA初级教程1 CPU体系架构综述 视频&#xff1a;https://www.bilibili.com/video/BV1kx411m7Fk?p2 讲师&#xff1a;周斌 本节内容&#xff1a;了解现代CPU的架构和性能优化&#xff1a; 流水线 Pipelining分支预测 Branch Prediction超标量 Superscalar乱序执行 Out…

Nvidia CUDA初级教程2 并行程序设计概述

Nvidia CUDA初级教程2 并行程序设计概述 视频&#xff1a;https://www.bilibili.com/video/BV1kx411m7Fk?p3 讲师&#xff1a;周斌 本节内容&#xff1a; 为什么需要&#xff1f;怎么做&#xff1f;一些技术和概念 串并行计算模式 串行计算模式 常规软件时串行的 设计运行…