作者:指定不告诉你 | 来源:互联网 | 2023-10-12 18:31
寻找数组中的重复值
题目来源于:Leetcode-287。本题归类到简单我无法理解…要满足四个条件需要用很特定的解法,面试中要是用到的话很可能是在给自己挖坑,所以我这里只讲几种能满足一部分条件的解法。
给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。示例 1:输入: [1,3,4,2,2]
输出: 2
示例 2:输入: [3,1,3,4,2]
输出: 3
说明:1、不能更改原数组(假设数组是只读的)。
2、只能使用额外的 O(1) 的空间。
3、时间复杂度小于 O(n2) 。
4、数组中只有一个重复的数字,但它可能不止重复出现一次。
下面给出四种解法,
1、第一种基于排序,大家都懂的,满足条件2、3、4。时间nlogn,空间n
2、第二种属于元素归位,其实和缺失最小正数那题挺像的,不过我们判断的时候,应当以目标位置中的元素是不是与当前元素重复为依据,如果索引不一致,但是值重复了,那就说明这是一个重复元素,满足2、3、4并且比排序方式更快。时间n,空间1
3、第三种是利用哈希表,满足1、3、4 。时间n空间n
4、第四种同样是利用哈希表,不过该哈希表我们可以自建,满足1、3、4。时间n空间n
第2类方式是比较好的。
public int findDuplicate(int[] nums) {Arrays.sort(nums);for(int i&#61;1;i<nums.length;i&#43;&#43;){if(num[i]&#61;&#61;nums[i-1]){return nums[i];}}return 0;}public int findDuplicate(int[] nums) {for(int i&#61;0;i<nums.length;i&#43;&#43;){while(i!&#61;nums[i]-1){if((i!&#61;nums[i]-1)&&nums[nums[i]-1]&#61;&#61;nums[i]){return nums[i];}swap(nums,nums[i]-1,i);}}return 0;}private void swap(int nums[],int i,int j){int temp&#61;nums[i];nums[i]&#61;nums[j];nums[j]&#61;temp;}public int findDuplicate(int[] nums) {Set<Integer> set&#61;new HashSet<>();for(int i&#61;0;i<nums.length;i&#43;&#43;){if(set.contains(nums[i])){return nums[i];}set.add(nums[i]);}return 0;}public int findDuplicate(int[] nums) {int[] map&#61;new int[nums.length];for(int i&#61;0;i<nums.length;i&#43;&#43;){if(map[nums[i]]&#61;&#61;1){return nums[i];}map[nums[i]]&#43;&#43;;}return 0;}