难度
思路
暴力遍历
- 使用
HashSet集合存储遍历对象。 - 获取一个元素,先使用
contain()判断HashSet是否包含该元素,如果包含,则直接Return,否则i++。
| 时间复杂度 | O(n) | | —- | —- | | 空间复杂度 | O(n) |public static int findRepeatNumber_0(int[] nums) {if (nums.length == 0)return -1;// 构建HashSet集合Set<Integer> resultMap = new HashSet<Integer>();for (int i = 0; i < nums.length; i++) {if (resultMap.contains(nums[i])) {return nums[i];}resultMap.add(nums[i]);}return -1;}
对号入座法
- 前提: 数组长度为
n且数字都在0~n-1范围内。因此,可以让它们对号入座(数组值与数组序号相对应)。 - 如果在对号入座的过程中,发送座位号的数值相同,则表示重复。相当于买票看电影,但前提是座位号与票号是一致的,即对号入座。
| 时间复杂度 | O(n) | | —- | —- | | 空间复杂度 | O(1) |public static int findRepeatNumber_3(int[] nums) {if (nums.length == 0)return -1;for (int i = 0; i < nums.length; i++) {// 一直循环while (nums[i] != i) {if (nums[i] != nums[nums[i]]) {// 交换int temp = nums[nums[i]];nums[nums[i]] = nums[i];nums[i] = temp;} else {// 遇到相等数据,直接返回return nums[i];}}}return -1;}
总结
虽然是 简单 类型,但是需要让大家注意 时间 和 空间 两种概念。比如使用 HashSet 时间复杂度较低(查找判断为 O(1)),但是空间复杂度高。而使用 “对号入座” 方法,前提条件比较苛刻,它让空间复杂度变为 O(1)。
