LeetCode | 287. 寻找重复数
特别感谢LeetCode大佬陈牧远的科普知识
给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。
示例 1:
输入: [1,3,4,2,2]
输出: 2
示例 2:
输入: [3,1,3,4,2]
输出: 3
说明:
- 不能更改原数组(假设数组是只读的)。
- 只能使用额外的 O(1) 的空间。
- 时间复杂度小于 O(n2) 。
- 数组中只有一个重复的数字,但它可能不止重复出现一次。
解析:
【笔记】这道题(据说)花费了计算机科学界的传奇人物Don Knuth 24小时才解出来。并且我只见过一个人(注:Keith Amling)用更短时间解出此题。
快慢指针,一个时间复杂度为O(N)的算法。
- 其一,对于链表问题,使用快慢指针可以判断是否有环。
- 其二,本题可以使用数组配合下标,抽象成链表问题。但是难点是要定位环的入口位置。
举个例子:nums = [2,5, 9 ,6,9,3,8, 9 ,7,1],构造成链表就是:2->[9]->1->5->3->6->8->7->[9],也就是在[9]处循环。
- 其三,快慢指针问题,会在环内的
[9]->1->5->3->6->8->7->[9]任何一个节点追上,不一定是在[9]处相碰,事实上会在7处碰上。 - 其四,必须另起一个
for循环定位环入口位置[9]。这里需要数学证明。
对“其四”简单说明一下,既然快慢指针在环内的某处已经相碰了。那么,第二个for循环遍历时,res指针还是在不停的绕环走,但是必定和i指针在环入口处相碰。
双指针:
class Solution {
public:
int findDuplicate(vector<int>& nums) {
int res = 0;
for (int fast = 0; res != fast || fast == 0;){
res = nums[res];
fast = nums[nums[fast]];
}
cout << res;
for (int i = 0; res != i; i = nums[i]){
res = nums[res];
}
return res;
}
};
二分查找
class Solution {
public:
int findDuplicate(vector<int> &nums) {
int len = nums.size();
int left = 0;
int right = len - 1;
while (left < right) {
int mid = left + (right - left) / 2;
int cnt = 0;
for (int num:nums) {
if (num <= mid) {
cnt++;
}
}
// 根据抽屉原理,小于等于 4 的数的个数如果严格大于 4 个,
// 此时重复元素一定出现在 [1, 4] 区间里
if (cnt > mid) {
// 重复的元素一定出现在 [left, mid] 区间里
right = mid;
} else {
// if 分析正确了以后,else 搜索的区间就是 if 的反面
// [mid + 1, right]
// 注意:此时需要调整中位数的取法为上取整
left = mid + 1;
}
}
return left;
}
};
LeetCode | 287. 寻找重复数的更多相关文章
- Java实现 LeetCode 287 寻找重复数
287. 寻找重复数 给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数.假设只有一个重复的整数,找出这个重复的数. 示例 ...
- leetcode 287寻找重复数
这道题用STL容器就很好写了,可以用set也可以用map, 用unordered_map的C++代码如下: class Solution { public: int findDuplicate(vec ...
- [LeetCode]287. 寻找重复数(二分)
题目 给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数.假设只有一个重复的整数,找出这个重复的数. 示例 1: 输入: [ ...
- LeetCode:寻找重复数【287】
LeetCode:寻找重复数[287] 题目描述 给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数.假设只有一个重复的整数 ...
- Leetcode之二分法专题-287. 寻找重复数(Find the Duplicate Number)
Leetcode之二分法专题-287. 寻找重复数(Find the Duplicate Number) 给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 ...
- 287. 寻找重复数 Java解法
287. 寻找重复数 这题的难点就在于下面的说明了,我们先不管下面的那些说明的要求,用常规的解法来解答下上的题目. 排序思想解法 先把原来的数组进行排序,然后逐个遍历,一旦发现后一个元素和当前的元素相 ...
- 【Leetcode】287. 寻找重复数(数组模拟链表的快慢指针法)
寻找重复数 根据题意,数组中的数字都在1~n之间,所以数字的范围是小于数组的范围的,数组的元素可以和数组的索引相联系. 例如:nums[0] = 1 即可以将nums[0]作为索引 通过nums[0] ...
- 【leetcode】287. 寻找重复数
题目链接:传送门 题目描述: 给定一个数组 nums 包含 n + 1 个整数,每个整数在 1 到 n 之间,包括 1 和 n.现在假设数组中存在一个重复的数字,找到该重复的数字. 注意 不能修改数组 ...
- Leetcode题目287.寻找重复数(中等)
题目描述: 给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数.假设只有一个重复的整数,找出这个重复的数. 示例 1: 输入 ...
随机推荐
- com.mysql.jdbc.exceptions.jdbc4.MySQLDataException: '2.34435678977654336E17' in column '3' is outside valid range for the datatype INTEGER.
### Error querying database. Cause: java.lang.reflect.UndeclaredThrowableException### The error may ...
- 使用wget获取其他服务器上的文件
http://www.cnblogs.com/tankblog/p/6081521.html
- 转:zabbix 更改maps图标
更改Zabbix map图标 Zabbix的maps用来图形化显示监控设备的拓扑图,并且以不同的标记显示故障事件,通过该图表很直观的显示设备的整体情况.系统默认的图标比较简陋,如图十一所示.通过更改系 ...
- 吴裕雄--天生自然KITTEN编程:滂沱大雨
- 在CodaLab上提交MURA竞赛的结果
What is MURA? MURA (musculoskeletal radiographs) is a large dataset of bone X-rays. Algorithms are t ...
- tfgan折腾笔记(一):核心功能简要概述
tfgan是什么? tfgan是tensorflow团队开发出的一个专门用于训练各种GAN的轻量级库,它是基于tensorflow开发的,所以兼容于tensorflow.在tensorflow1.x版 ...
- APScheduler使用总结
安装 pip install apscheduler APScheduler组件 1.triggers(触发器) 触发器中包含调度逻辑,每个作业都由自己的触发器来决定下次运行时间.除了他们自己初始配置 ...
- PhalApi 2.7 开发快速上手
PhalApi是一款国人制作的PHP纯后端框架.它的开发相当简单,同时也具备文档生成等特色功能.下面,我通过简单的几点,让你可以快速入门使用该框架的开发. 建议使用PHPStorm作为IDE,代码提示 ...
- 用 Python 生成 HTML 表格
在 邮件报表 之类的开发任务中,需要生成 HTML 表格. 使用 Python 生成 HTML 表格基本没啥难度, for 循环遍历一遍数据并输出标签即可. 如果需要实现合并单元格,或者按需调整表格样 ...
- bp(net core)+easyui+efcore实现仓储管理系统——入库管理之三存储过程(三十九)
abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统——ABP总体介绍(一) abp(net core)+ ...