【三种解法实现】剑指 Offer 03. 数组中重复的数字
立志用最少的代码做最高效的表达
题目链接——>传送门
找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
示例 1:
输入:
[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3
限制:
2 <= n <= 100000
解法一:排序
解决这个问题一个简单办法就是先把输入的数组排序,从排序的数组中找出重复的数字是一件很容易的事情,只需从头到尾扫描即可。
时间复杂度为O(nlogn),空间复杂度O(1)
class Solution {public:int findRepeatNumber(vector<int>& nums) {int n = nums.size();sort(nums.begin(),nums.end());for(int i = 1; i < n; i++){if(nums[i-1] == nums[i])return nums[i];}return -1;}
};
解法二:哈希表
构造一个长度为n的哈希表,遍历数组,每扫描到一个数字,都判断其是否在哈希表中存在,若不存在,则加入;若存在,则为重复数字。
时间复杂度为O(nlogn),空间复杂度O(n)
代码一:c++内置容器unordered_map实现(耗时较高)
class Solution {public:int findRepeatNumber(vector<int>& nums) {unordered_map<int,int>um;int k = 0;for(auto i : nums) {um[i]++;if(um[i] > 1) { k = i; break;}}return k;}
};
代码二:数组模拟哈希表(耗时低,因为数组效率高)
class Solution {public:int findRepeatNumber(vector<int>& nums) {int a[100005] = {0};int k = 0;for(auto i : nums) {a[i]++;if(a[i] > 1) { k = i; break;}}return k;}
};
解法三:原地置换
现在让我们重排这个数组。从头到尾依次扫描这个数组中的每个数字。
当扫描到下标为i的数字时,首先比较这个数字(用m表示)是不是等于i。
如果是,则接着扫描下一个数字;如果不是,则再拿它和第m个数字进行比较。
如果它和第m个数字相等,就找到了一个重复的数字(该数字在下标为i和m的位置都出现了);如果它和第m个数字不相等,就把第i个数字和第m个数字交换,把m放到属于它的位置。
接下来再重复这个比较、交换的过程,直到我们发现一个重复的数字。
以数组{2,3,1,0,2,5,3}为例来分析找到重复数字的步骤。数组的第0个数字(从0开始计数,和数组的下标保持一致)是2,与它的下标不相等,于是把它和下标为2的数字1交换。交换之后的数组是{1,3,2,0,2,5,3}。
此时第О个数字是1,仍然与它的下标不相等,继续把它和下标为1的数字3交换,得到数组{3.1.2.0.2.5.3}。
接下来继续交换第0个数字3和第3个数字0,得到数组{0.1.2.3.2.5.3}。此时第О个数字的数值为0,接着扫描下一个数字。
在接下来的几个数字中,下标为1、2、3的3个数字分别为1、2、3,它们的下标和数值都分别相等,因此不需要执行任何操作。
接下来扫描到下标为4的数字2。由于它的数值与它的下标不相等,再比较它和下标为2的数字。
注意到此时数组中下标为2的数字也是2,也就是数字2在下标为2和下标为4的两个位置都出现了,因此找到一个重复的数字。
时间复杂度为O(n),空间复杂度O(1)
class Solution {public:int findRepeatNumber(vector<int>& nums) {int i = 0, len = nums.size();while(i < len) {if(nums[i] == i) {i++;continue;}if(nums[i] != nums[nums[i]]) {swap(nums[i], nums[nums[i]]);} else {return nums[i];}}return -1;}
};
——朝着一个目标不断做精深练习,不断犯错,不断挑战自己的极限,这种努力给你带来的收获绝对超出你的想象
【三种解法实现】剑指 Offer 03. 数组中重复的数字相关推荐
- 剑指 Offer 03. 数组中重复的数字()
在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重复的数字. 解题思路 原 ...
- 【LeetCode笔记】剑指 Offer 03. 数组中重复的数字(Java、哈希表、原地算法)
文章目录 题目描述 思路 & 代码 二刷 题目描述 倒是和leetcode 287 寻找重复数很像..但是不能使用那道题的快慢指针法(也可能是我太菜了) 重点在于题干的描述[长度为 n 的数组 ...
- Leetcode 剑指 Offer 03. 数组中重复的数字 (每日一题 20210614)
找出数组中重复的数字.在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重复 ...
- leetcode 剑指 Offer 03. 数组中重复的数字
找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重 ...
- 【算法】剑指 Offer 03. 数组中重复的数字
1.概述 找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中 ...
- leetcode 剑指 Offer 03. 数组中重复的数字 抽屉原理 一个萝卜一个坑
找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重 ...
- LeetCode-剑指 Offer 03. 数组中重复的数字
剑指 Offer 03. 数组中重复的数字 思路一:先排序,然后找到最近的两个相邻的一样数返回 class Solution {public:int findRepeatNumber(vector&l ...
- Python剑指offer:数组中重复的数字
题目一:找出数组中重复的数字 在一个长度为n的数组里的所有数字都在0~n-1的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重复的数字.例如 ...
- 【四种解法】剑指 Offer 39. 数组中出现次数超过一半的数字
立志用最少的代码做最高效的表达 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 你可以假设数组是非空的,并且给定的数组总是存在多数元素. 示例 1: 输入: [1, 2, 3, 2, ...
最新文章
- 《Drupal实战》——1.9 小结
- 【迁移学习(Transfer L)全面指南】方差、协方差和Pearson相关系数的关系
- 百度地图JavascriptApi Marker平滑移动及车头指向行径方向
- Android Studio 更新失败解决方法
- 引领PCB行业变革 捷配开启免费打样新时代
- iOS DLNA
- 使用python实现一个文件搜索功能,类似于Everything功能
- 利用docker容器ubuntu安装truecrypt
- 图像处理基础(2):自适应中值滤波器(基于OpenCV实现)
- 流程图怎么画?绘制一个流程图的简单操作方法
- BNUOJ 52506 Captcha Cracker
- AICC 2021,这些AI热门话题你一定要知道
- 打赢防“疫”战,云服务商都做了什么……
- HG30-3B型多功能校准仪
- SpringMVC @ResponseBody在IE8变下载
- 一个分组查询引发的思考
- 在C#控制台输出的爱心图案
- 零基础请进,影视解说必备的5个工具|不可错过的免费配音软件
- SIM800C连接OneNet平台HTTP协议上传GPS数据
- 图片上传到阿里云服务器_07-文件上传到阿里云OSS实战(二)