一道简单的数组遍历题,加上四个条件后感觉无从下手

2024-02-13 13:59

本文主要是介绍一道简单的数组遍历题,加上四个条件后感觉无从下手,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

点击蓝色“五分钟学算法”关注我哟

加个“星标”,天天中午 12:15,一起学算法

640?wx_fmt=jpeg

作者 | P.yh

来源 | 五分钟学算法

今天分享的题目来源于 LeetCode 第 287 号问题:寻找重复数。

题目描述

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

示例 1:

输入: [1,3,4,2,2]
输出: 2

示例 2:

输入: [3,1,3,4,2]
输出: 3

说明:

  • 不能更改原数组(假设数组是只读的)。

  • 只能使用额外的 O(1) 的空间。

  • 时间复杂度小于 O(n^2) 。

  • 数组中只有一个重复的数字,但它可能不止重复出现一次。

题目解析

题目的限制真多!!!

首先 不能改变数组 导致无法排序,也无法用 index 和元素建立关系;

只能使用 O(1) 的空间 意味着使用哈希表去计数这条路也走不通;

时间复杂度必须小于 O(n^2) 表示暴力求解也不行;

重复的元素可重复多次 这一条加上后,本来可以通过累加求和然后做差 sum(array) - sum(1,2,...,n) 的方式也变得不可行。

本来是非常简单的一道数组遍历的题目,加上了上面这四个条件后感觉有点无从下手

我们说做题要借助算法,而不是空想,因此对于这道题也不例外,我们可以问自己这样一个问题,就是 “什么样的算法可以不使用额外的空间解决数组上面的搜索问题?”

静静的思索一下。

你这时应该隐隐约约知道了,难道是 二分查找

什么?二分查找法?!

二分查找法不是对有序数组才适用么?

这里澄清一个误区,二分法的使用 并不一定 需要在排序好的数组上面进行,不要让常见的例题限制了你的思路,二分法还有一个比较高级的用法叫做 按值二分

这道题目交代的信息很少,我们只需要关注两个东西 - 数组,数组里的元素,利用二分我们需要去思考的是,我们要找符合条件的元素作为答案,那么 比答案小的元素具有什么样的特质,比答案大的元素又具有什么样的特质?,结合题目给我们的例子来看看:

( 说明:下面的  <=  符号表明 小于或者等于。)

例1:

[1,3,4,2,2]                      元素个数
<= 1 的元素:1                       1
<= 2 的元素:1, 2, 2                 3
<= 3 的元素:1, 2, 2, 3              4
<= 4 的元素:1, 2, 2, 3, 4           5

例2:

[3,1,3,4,2]
<= 1 的元素:1                        1
<= 2 的元素:1, 2                     2
<= 3 的元素:1, 2, 3, 3               4
<= 4 的元素:1, 2, 3, 3, 4            5

极端一点的例子 (必须保证数组的长度是 n + 1, 并且元素都在区间[1,n] 上, 有且只有一个重复)

[3,3,3,3,4]
<= 1 的元素:                        0
<= 2 的元素:                        0
<= 3 的元素:3, 3, 3, 3              4
<= 4 的元素:3, 3, 3, 3, 4           5

看完上面几个例子,相信你明白了一个事实:

  • “如果选中的数 小于 我们要找的答案,那么整个数组中小于或等于该数的元素个数必然小于或等于该元素的值;

  • 如果选中的数 大于或等于 我们要找的答案,那么整个数组中小于或等于该数的元素个数必然 大于 该元素的值”

而且你可以看到,我们要找的答案其实就处于一个分界点的位置,寻找边界值,这又是二分的一个应用,而且题目已经告诉我们数组里面的值只可能在 [1, n] 之间,这么一来,思路就是在 [1, n] 区间上做二分,然后按我们之前提到的逻辑去做分割。整个解法的时间复杂度是 O(nlogn),也是满足题目要求的。

上面的解法不是最优的,但是个人觉得是根据现有的知识比较容易想到的。

另外一种 O(n) 的解法借鉴快慢指针找交点的思想,算法非常的巧妙,也非常的有趣,但不太容易想到,这里把代码放上。

动画描述

代码实现一

//二分查找
class Solution {public int findDuplicate(int[] nums) {int len = nums.length;int start = 1;int end = len - 1;while (start < end) {int mid = start + (end - start) / 2;int counter = 0;for (int num:nums) {if (num <= mid) {counter++;}}if (counter > mid) {end = mid;} else {start = mid + 1;}}return start;}
}

代码实现二

//快慢指针
public int findDuplicate(int[] nums) {        int fast = nums[nums[0]];int slow = nums[0];while (fast != slow) {fast = nums[nums[fast]];slow = nums[slow];}slow = 0;while (fast != slow) {fast = nums[fast];slow = nums[slow];}return slow;
}

640?

有热门推荐?

1.【程序员】

2.【GitHub】

3.【算法】

4.【数据结构】

640?wx_fmt=jpeg

▼ 点击『阅读原文』解锁更多图解 LeetCode 题目

这篇关于一道简单的数组遍历题,加上四个条件后感觉无从下手的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/705718

相关文章

JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法

《JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法》:本文主要介绍JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法,每种方法结合实例代码给大家介绍的非常... 目录引言:为什么"相等"判断如此重要?方法1:使用some()+includes()(适合小数组)方法2

Python 基于http.server模块实现简单http服务的代码举例

《Python基于http.server模块实现简单http服务的代码举例》Pythonhttp.server模块通过继承BaseHTTPRequestHandler处理HTTP请求,使用Threa... 目录测试环境代码实现相关介绍模块简介类及相关函数简介参考链接测试环境win11专业版python

从基础到进阶详解Python条件判断的实用指南

《从基础到进阶详解Python条件判断的实用指南》本文将通过15个实战案例,带你大家掌握条件判断的核心技巧,并从基础语法到高级应用一网打尽,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录​引言:条件判断为何如此重要一、基础语法:三行代码构建决策系统二、多条件分支:elif的魔法三、

python连接sqlite3简单用法完整例子

《python连接sqlite3简单用法完整例子》SQLite3是一个内置的Python模块,可以通过Python的标准库轻松地使用,无需进行额外安装和配置,:本文主要介绍python连接sqli... 目录1. 连接到数据库2. 创建游标对象3. 创建表4. 插入数据5. 查询数据6. 更新数据7. 删除

Jenkins的安装与简单配置过程

《Jenkins的安装与简单配置过程》本文简述Jenkins在CentOS7.3上安装流程,包括Java环境配置、RPM包安装、修改JENKINS_HOME路径及权限、启动服务、插件安装与系统管理设置... 目录www.chinasem.cnJenkins安装访问并配置JenkinsJenkins配置邮件通知

Java中数组与栈和堆之间的关系说明

《Java中数组与栈和堆之间的关系说明》文章讲解了Java数组的初始化方式、内存存储机制、引用传递特性及遍历、排序、拷贝技巧,强调引用数据类型方法调用时形参可能修改实参,但需注意引用指向单一对象的特性... 目录Java中数组与栈和堆的关系遍历数组接下来是一些编程小技巧总结Java中数组与栈和堆的关系关于

Python yield与yield from的简单使用方式

《Pythonyield与yieldfrom的简单使用方式》生成器通过yield定义,可在处理I/O时暂停执行并返回部分结果,待其他任务完成后继续,yieldfrom用于将一个生成器的值传递给另一... 目录python yield与yield from的使用代码结构总结Python yield与yield

Java中使用 @Builder 注解的简单示例

《Java中使用@Builder注解的简单示例》@Builder简化构建但存在复杂性,需配合其他注解,导致可变性、抽象类型处理难题,链式编程非最佳实践,适合长期对象,避免与@Data混用,改用@G... 目录一、案例二、不足之处大多数同学使用 @Builder 无非就是为了链式编程,然而 @Builder

Java中的数组与集合基本用法详解

《Java中的数组与集合基本用法详解》本文介绍了Java数组和集合框架的基础知识,数组部分涵盖了一维、二维及多维数组的声明、初始化、访问与遍历方法,以及Arrays类的常用操作,对Java数组与集合相... 目录一、Java数组基础1.1 数组结构概述1.2 一维数组1.2.1 声明与初始化1.2.2 访问

MySQL查询JSON数组字段包含特定字符串的方法

《MySQL查询JSON数组字段包含特定字符串的方法》在MySQL数据库中,当某个字段存储的是JSON数组,需要查询数组中包含特定字符串的记录时传统的LIKE语句无法直接使用,下面小编就为大家介绍两种... 目录问题背景解决方案对比1. 精确匹配方案(推荐)2. 模糊匹配方案参数化查询示例使用场景建议性能优