题目介绍:

  • 在一个长度为n的数组里,所有的数字都在0到n~1的范围内!
  • 数组中某些元素是重复的,有些是不重复的。
  • 请找出数组中任意一个重复的数字。

题目分析:

一些简要的思路:

  • 先把数组排序,排序好的数组要找出重复的数字很是容易,只需要从头到尾扫面一遍就可以了。排序的时间复杂度是O(nlogn)。
  • 用哈希表表示:从头到尾扫描数组的每个数字,每扫描一个数字,就可以用O(1)的时间判断哈希表里是否包含了该数字。如果哈希表里还没有这个数字,就把它加入哈希表,如果哈希表里面已经存在该数字,就找到了一个重复数字。这个算法的时间复杂度是O(n),但是他提高时间效率的代价是以一个大小为O(n)的哈希表为代价的。

对题目的分析:

观察数组,发现数组的数字都在0-n-1的范围内。即如果这个数组中没有重复的数字,那么排序后元素 i 将出现在下标为 i 的位置。

例如:数组 [2,1,0],长度为3,即数组中的元素都要在0-2之间,符合要求,那么排序后,数组变为 [0,1,2],和数组元素的下标一致。

由于数组中有重复的数字,有些位置可能存在多个数字,同时有些位置可能没有数字。

详细思路:

  • 从头到尾扫描这个数组中每一个数字。当扫描到下标为 i 的数字时,首先比较这个数字(m)是不是等于 i 。
  • 如果是,说明这个数字是在排好序后的位置,则继续扫描下一个数字;
  • 如果不是,则再拿数字(m)和下标为 m 对应的数字比较。
  • 如果数字(m)和第m个数字相等,就找到一个重复的数字(因为该数字在下标i和m的位置都出现了。);
  • 如果数字(m)和第m个数字不相等,就把这两个数字交换,即把数字(m)放到下标为m的位置上。
  • 接下来继续重复比较、交换这样的步骤,直到我们发现一个重复的数字。

代码实现与验证(Python):

class Solution:def duplicate(self,array):if array == None or len(array) <= 0:             # 数组为空,直接Falsereturn Falsefor i in range(len(array)):if array[i] < 0 or array[i] >= len(array):   # 数组中的元素都应在0-n-1之间,否则Falsereturn Falsefor i in range(len(array)):                # 遍历while array[i] != i:                   # 若下标和元素值不等,则一直循环下去if array[array[i]] == array[i]:    # 若下标为i的元素 array[i] 和下标为 array[i] 的元素相等,则重复,返回array[i]return array[i]else:                              # 否则,交换array[array[i]], array[i] = array[i], array[array[i]]return Falseif __name__=='__main__':# 验证# 数组中不含重复的数字test_1 = [3,1,2,0]# 长度为 n 的数组里包含一个或多个重复的数字test_2 = [2, 3, 1, 0, 2, 5, 3]# 数组为空test_3 = None# 数组中元素值超出了0-n-1test_4 = [2, 6, 1, 0]solution = Solution()print("test_1:", solution.duplicate(test_1))print("test_2:", solution.duplicate(test_2))print("test_3:", solution.duplicate(test_3))print("test_4:", solution.duplicate(test_4))

验证结果:

test_1: False
test_2: 2
test_3: False
test_4: False

复杂度分析:

时间复杂度:
上述代码中,有两个循环,但是每一个数字最多交换两次就可以找到属于它自己的位置,因此总的时间复杂度的 O(n)。

空间复杂度:
上述代码的所有操作都是在原数组上进行的,不需要额外分配内存,因此空间复杂度是 O(1)。

C++实现

#include <iostream>
using namespace std;
/*****************************************/
// 参数:
//        numbers:     一个整数数组
//        length:      数组的长度
// 返回值:
//        数组中的一个重复的数字
/*****************************************/
class Solution {
public:bool duplicate(int numbers[], int length){if (numbers == nullptr || length <= 0){cout << "数组为空!" << endl;return false;}for (int i = 0; i < length; i++){if (numbers[i]<0 || numbers[i]>length){cout << "数组中元素超出范围!" << endl;return false;}}for (int i = 0; i < length; i++){while (numbers[i] != i){if (numbers[i] == numbers[numbers[i]]){cout << numbers[i] <<endl;return true;}else{int temp = numbers[i];numbers[i] = numbers[temp];numbers[temp] = temp;}}}return false;}
};
Solution solution;
int main()
{int numbers[7] = { 2,3,1,0,2,5,3};//int *numbers = nullptr;int length = 7;solution.duplicate(numbers, length);return 0;
}
输出:2

剑指_3.1数组中重复的数字(Python/C++)相关推荐

  1. Python剑指offer:数组中重复的数字

    题目一:找出数组中重复的数字 在一个长度为n的数组里的所有数字都在0~n-1的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重复的数字.例如 ...

  2. Leetcode 剑指 Offer 03. 数组中重复的数字 (每日一题 20210614)

    找出数组中重复的数字.在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重复 ...

  3. 【三种解法实现】剑指 Offer 03. 数组中重复的数字

    立志用最少的代码做最高效的表达 题目链接-->传送门 找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数 ...

  4. leetcode 剑指 Offer 03. 数组中重复的数字

    找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重 ...

  5. 【算法】剑指 Offer 03. 数组中重复的数字

    1.概述 找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中 ...

  6. leetcode 剑指 Offer 03. 数组中重复的数字 抽屉原理 一个萝卜一个坑

    找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重 ...

  7. 《剑指offer》数组中重复的数字

    题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为7的 ...

  8. 剑指 Offer 03. 数组中重复的数字()

    在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重复的数字. 解题思路 原 ...

  9. 剑指Offer之数组中重复的数字

    题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...

  10. 【LeetCode笔记】剑指 Offer 03. 数组中重复的数字(Java、哈希表、原地算法)

    文章目录 题目描述 思路 & 代码 二刷 题目描述 倒是和leetcode 287 寻找重复数很像..但是不能使用那道题的快慢指针法(也可能是我太菜了) 重点在于题干的描述[长度为 n 的数组 ...

最新文章

  1. 理解和实现分布式TensorFlow集群完整教程
  2. 除了不要 SELECT * ,数据库还有哪些技巧
  3. 多迪将企业的Python工程师定位成哪几类?
  4. jquery jcrop java_jcrop基本参数一览
  5. SecureCRT 配置文件中 找密码
  6. SAS 读取数据文件
  7. V210调整根分区大小
  8. windows下集成maven+eclipse开发环境二:集成maven到eclipse,并使用nexus作为maven仓库...
  9. 云原生时代,开发者如何构筑容器安全?
  10. python实现文件重命名_基于python实现复制文件并重命名
  11. 构建幸福婚姻需明白四件事
  12. 一个简单的WeakList的实现
  13. Python——词频统计
  14. 最新个人发卡网系统源码-全开源版
  15. Unity - Timeline 之 Timeline window(Timeline窗口)
  16. JavaScript实现逆波兰式
  17. Potplayer如何显示书签,书签编辑器
  18. 【Jupyter常用快捷键】
  19. 通过代码实现EXE文件图标的替换
  20. 考早了!华为认证推出“一试双证”,IE直接补贴3000元

热门文章

  1. 货币基金新规将出,限制T+0提现及支付额度
  2. SQLite: 注意日期查询中的“前空格”问题将引发错误查询!
  3. 进阶之路:深入解读 Java 堆外内存 | 凌云时刻
  4. select vue 获取name_在vue的组件中获取select2插件的值
  5. 【阙值分割】基于matlab遗传算法自适应多阈值图像分割【含Matlab源码 1460期】
  6. 【TWVRP】基于matlab遗传算法求解送货且带时间窗的车辆路径规划问题【含Matlab源码 1074期】
  7. 【图像增强】基于matlab同态滤波+Retinex+模糊技术图像增强【含Matlab源码 1013期】
  8. 【模拟信号】基于matlab调频信号产生+解调【含Matlab源码 986期】
  9. 【人脸识别】基于matlab GUI PCA人脸识别【含Matlab源码 748期】
  10. python语言用什么编译器_如何修改python语言pycharm工具的默认编译器