从零学算法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 = [3,3,3,3,3]
输出:3
提示:
1 <= n <= 10^5
nums.length == n + 1
1 <= nums[i] <= n
nums 中 只有一个整数 出现 两次或多次 ,其余整数均只出现 一次
进阶:
如何证明 nums 中至少存在一个重复的数字?
你可以设计一个线性级时间复杂度 O(n) 的解决方案吗?

  • 为了只使用 O(1) 的额外空间,我们借用原数组的空间做标记,找到结果后复原数组。具体思路如下:由于数组中的数都小于数组长度 n+1,所以每个 nums[i] 都能对应一个数组下标,比如 nums[0]=3,我们令其指向数组下标为 3 的地方,将 nums[3] 标记为负数,这就表示数组中存在一个数为 3,若所有数不重复,那么最后每个 nums[i] 都会指向对应的位置且位置不重复;而如果存在重复的数就会有:要标记时被标记数已为负数
  •   public int findDuplicate(int[] nums) {
          int res = nums[0];
          for(int n:nums){
          	// 因为这个位置上的数可能被标记为负数,所以取绝对值
              int a = Math.abs(n);
              // 将对应位置上的数标记为负数
              if(nums[a]>0)nums[a]=-nums[a];
              // 否则说明已经标记过了,此时 a 为结果
              else res = a;
          }
          // 复原
          for(int i=0;i<nums.length;i++){
              nums[i]=Math.abs(nums[i]);
          }
          return res;
      }
    
  • 他人题解:把数组看做环形链表,上面说了每个 nums[i] 都能对应一个数组下标,那么就把 nums[i] 看做下一个节点的下标,我们把数组下标与值一一对应,可以得到类似链表的结构,例如[1,3,4,2,2]我们可以得到:
  • 0 -> 1
    1 -> 3
    2 -> 4
    3 -> 2
    4 -> 2

  • 我们从下标 0 开始,根据 nums[0] 得到一个值 n,然后从这个值继续,以他为下标,可以得到 nums[n],他就是新的 n,然后继续得到 nums[n]…
  • 也就是说上面例子可以看做 0->1->3->2->4->2->4->2->…,其中的 2->4 为一个循环,可以看做如下链表请添加图片描述
  • 由于有重复的数,所以一定会产生多对一的映射,并且因为 nums[i] 的范围为 [1,n],而数组长度为 n+1,所以不可能导致链表中断,一定会得到环。
  • 举个不符合规则的测试用例 [1,3,2,4],会得到链表 0->1->3->4->null,这里就是没有 nums[4] 所以链表中断了,但是实际上 nums[i] 的范围被限制为 [1,3],所以不会出现这个例子的情况
  • 那么最后本题中找到重复的数就被我们转化为了找到环的入口,因为只有重复的数才能满足环的起点和终点一样的特点
  • 接下来分析怎么得到环的入口,使用快慢指针,首先当两个点相遇时,能相遇的原因就是快指针进行了无用功,比如跑了一个环的长度回到了原地,所以被慢指针追上了,设环长度为 m,慢指针走了 x 步,那么快指针和它相遇肯定是走了 x+ym 步(y=1,2,3…,表示比慢指针多跑了 y 圈环的长度)。那么两点第一次相遇时,慢指针步数为 x,快指针步数为 x+m,这个 x 是多少步?因为快指针的速度是慢指针的两倍,所以快指针步数 x+m 等于慢指针步数 x 的两倍 => x+m=x+x => x=m,也就是说快慢指针第一次相遇时慢指针走了 m 步,设相遇点离环起点 n 步,环起点离原点就有 m-n 步,同时,从相遇点继续走到环起点也需要 m-n 步,那么此时就让慢指针回到原点,快指针开始一步一步走,最后经过 m-n 步,两个指针就同时到达了环起点请添加图片描述
  • 如上图的例子,两点会在环的长度也就是第四个点处第一次相遇,此时快指针再走三步到环起点,慢指针也是走三步到环起点
  •   public int findDuplicate(int[] nums) {
          int slow = 0,fast = 0;
          // 初始走一下,不然直接相等了
          slow = nums[slow];
          fast = nums[nums[fast]];
          // 第一次相遇时停止
          while(slow != fast){
              slow = nums[slow];
              fast = nums[nums[fast]];
          }
          // slow 回原点
          slow = 0;
          // 共同走 m-n 步在环起点相遇
          while(slow != fast){
              slow = nums[slow];
              fast = nums[fast];
          }
          return slow;
      }
    

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

聊聊python中面向对象编程思想

面向对象编程思想 1、什么是面向过程 传统的面向过程的编程思想总结起来就八个字——自顶向下&#xff0c;逐步细化&#xff01; → 将要实现的功能描述为一个从开始到结束按部就班的连续的“步骤” → 依次逐步完成这些步骤&#xff0c;如果某一个步骤的难度较大&#xff…

2024年品牌推广:构建品牌生态圈与注重品牌故事和文化传播

在全球经济深度融合、数字化浪潮汹涌澎湃的2024年&#xff0c;品牌推广的策略与模式正经历着前所未有的变革。在这一背景下&#xff0c;构建品牌生态圈和注重品牌故事与文化传播&#xff0c;成为了企业提升品牌竞争力和市场占有率的重要手段。 一、2024年市场经济分析与现状 …

上门预约按摩系统相比较传统按摩店有哪些优点和特色;

上门按摩系统与传统按摩店的运营对比&#xff1a; 1. 技师自由选择&#xff1a;在上门按摩系统中&#xff0c;技师可以兼职加入&#xff0c;无需固定门店。平台为技师提供订单&#xff0c;技师则携带基础服务用具上门服务。同时&#xff0c;兼职技师也需提交详尽资料和资质证明…

伟骅英才|二月二:龙年龙抬头

二月二龙抬头&#xff0c;是中国民间传统节日&#xff0c;人们期盼通过对龙的祈求来实现降雨的目的&#xff0c;寄托了老百姓对美好生活的向往。这一天&#xff0c;人们通常会去理个发&#xff0c;寓意着“二月二剃龙头&#xff0c;一年都有精神头”。现如今的二月二&#xff0…

软件测试需要学什么?学多久?软件测试技术进阶路线图

很多新手&#xff0c;不知道软件测试学习该如何开始&#xff0c;软件测试需要掌握哪些知识。下面是根据本人的理解&#xff0c;粗略整理的一个学习大纲&#xff0c;基本上涵盖了软件测试工程师需要掌握的全部技能&#xff0c;希望对刚入行或者准备学习测试的朋友提供一点指引。…

Java17 --- SpringCloud初始项目创建

目录 一、cloud项目创建 1.1、项目编码规范 1.2、注解生效激活 1.3、导入父工程maven的pom依赖 二、创建子工程并导入相关pom依赖 2.1、相关配置文件 2.1.1、数据库配置文件内容 2.1.2、自动生成文件配置内容 三、创建微服务8001子工程 3.1、导入相关pom依赖 3.…

基于51单片机超声波测距

目录 摘 要 2 ABSTRACT 3 目 录 4 1 绪论 1 1 概述 12 国内外发展现状 1 2 系统总体方案设计 21 设计要求 2 1&#xff09;可进行距离测量。 2 2&#xff09; 采用数码管显示距离数据。 2 3&#xff09; 可按键设置距离门限值 2 4&#xff09; 具有报警功能 22 方案选择 2 1 …

Vue点击切换组件颜色

例如我有一个这样的组件&#xff0c;我希望在点击组件之后由蓝色变成橙色 先把原来的代码附上(简化掉了叉号&#xff09;&#xff1a; <div v-for"(item, index) in words" :key"index" class"scrollbar-demo-item"><span>{{ item …

PL/SQL学习笔记

介绍 PL/SQL 编程语言是SQL 和 Oracle 关系数据库的过程扩展语言 是Oracle 编程环境中的一个工具 基本语法 S.No Sections & Description 1 Declarations 此部分以关键字 DECLARE 开头。 它是一个可选部分&#xff0c;定义了程序中要使用的所有变量、游标、子程序和其他…

C++虚继承的一些细节

C虚继承的一些细节 何时使用虚继承普通继承的类对象布局虚继承类对象布局虚函数表指针虚函数表内容 何时使用虚继承 看代码&#xff0c;代码主要是菱形继承&#xff0c;base里面的成员变量会存在二义性 #include<iostream> using namespace std;class base { public:in…

客户案例|100M 768 维向量数据,Zilliz Cloud 稳定支持 Shulex VOC 业

日前&#xff0c;国际化 VOC SaaS 公司数里行间&#xff08;Shulex&#xff09;将上亿数据量的核心业务从开源向量数据库 Milvus 迁移至全托管的向量数据库云服务 Zilliz Cloud。 相比于 Milvus&#xff0c;Zilliz Cloud 实现了 Shulex VOC 评论分析洞察报告生成速度 30% 的提升…

第二十天-数据分析

1.介绍 1.什么是数据分析 1.以下4个纬度结合起来的数据科学 2.数据分析的特殊性

物体检测-系列教程23:YOLOV5 源码解析13 (SPP层、Flatten模块、Concat模块、Classify模块)

&#x1f60e;&#x1f60e;&#x1f60e;物体检测-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 点我下载源码 17、SPP模块 17.1 SPP类 SPP是一种特殊的池化策略&#xff0c;最初在YOLOv3-SPP中被使用…

Axuer的中继器~增删改查

目录 1. 中继器 2. 增加 3. 全选 4. 删除 5. 修改 6. 排序 7.分页 正文&#xff1a; 1.中继器&#xff1a;拉一个中继器给中继器名称写一个数据 在右边点击样式 写入数据 1.2 双击中继器进入动态页面 在里面放3个框 1.3 退出来 给中继器添加数据 2. 增加&#xff1…

研发效能DevOps: OpenEuler 部署 drone 持续集成平台

目录 一、实验 1.环境 2.OpenEuler 部署 drone 持续集成平台 二、问题 1.drone登录失败 一、实验 1.环境 &#xff08;1&#xff09;主机 表1 主机 系统架构版本IP备注LinuxopenEuler22.03 LTS SP2 192.168.204.145&#xff08;动态&#xff09; 192.168.204.141&…

使用maven打包执行install命令时候一直卡在No proxies configured不动,如何解决?

问题描述&#xff1a; [INFO] [INFO] — frontend-maven-plugin:1.9.1:install-node-and-npm (install node and npm) frontend — [INFO] Installing node version v16.0.0 [INFO] Copying node binary from D:\Maven\maven-repository\com\github\eirslett\node\16.0.0\node…

3.11_C++_day1_作业

作业要求&#xff1a; 程序代码&#xff1a; #include <iostream> #include <string.h>using namespace std;int main() {int a0,b0,c0,d0,e0;//分别记录字符串中的大写&#xff0c;小写&#xff0c;数字&#xff0c;空格&#xff0c;其他字符个数string str;cha…

Docker初体验之安装部署和镜像加速(openeuler版)

安装部署&#xff1a; 本人使用的为openeuler版本&#xff0c;无法使用二进制进行安装&#xff08;使用二进制安装时&#xff0c;无法使用docker中的补全命令&#xff0c;需要重新进行配置&#xff09;在此使用yum直接进行安装。 [rootlocalhost ~]# yum install docker 镜像…

java异常概述及自定义处理

前言 学到异常了&#xff0c;本来以为处理异常只是避免bug&#xff0c;结果发现还可以为了编程需要自定义异常。打好基础&#xff0c;daydayup! 异常 什么是异常 异常就是代表程序出现的问题 异常的体系 异常体系指的是java开发人员为了方便程序员使用所开发的异常类&#xff…

稀碎从零算法笔记Day10-LeecCode:赎金信

题型&#xff1a;哈希表、字符串 链接&#xff1a;383. 赎金信 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 题目描述 给你两个字符串&#xff1a;ransomNote 和 magazine &#xff0c;判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以…