[原题链接](初级算法 - LeetBook - 力扣(LeetCode)全球极客挚爱的技术成长平台 (leetcode-cn.com))
给定一个整数数组,判断是否存在重复元素。
如果存在一值在数组中出现至少两次,函数返回 true
。如果数组中每个元素都不相同,则返回 false
。
题解
法一:排序
public class Solution {
/**
* 给定一个整数数组,判断是否存在重复元素。
* 如果存在一值在数组中出现至少两次,函数返回 true 。如果数组中每个元素都不相同,则返回 false 。
* 排序后,若当前元素比前一个元素大,则返回true。
* @param nums
* @return
*/
public boolean containsDuplicate(int[] nums) {
//排除数组大小为1的情况
if(nums.length <= 1) return false;
quickSort(nums, 0, nums.length - 1);
for (int i = 1; i < nums.length; i++) {
if(nums[i] == nums[i - 1]) return true;
}
return false;
}
/**
* 快速排序
* @param nums
* @param left
* @param right
*/
private void quickSort(int[] nums, int left, int right){
int i, j, t, temp;
if(left > right) return;
temp = nums[left];
i = left;
j = right;
while (i != j){
while (nums[j] >= temp && i < j) j--;
while (nums[i] <= temp && i < j) i++;
if (i < j){
t = nums[i];
nums[i] = nums[j];
nums[j] = t;
}
}
nums[left] = nums[i];
nums[i] = temp;
quickSort(nums, left, i - 1);
quickSort(nums, i + 1, right);
return;
}
}
时间复杂度O(nlogn),空间复杂度O(1),很遗憾超时了。
法二:利用Set的互异性(作弊)
public class Solution {
/**
* 利用Set.add()
* @param nums
* @return
*/
public boolean containsDuplicate(int[] nums) {
if (nums.length <= 1) return false;
Set<Integer> set = new HashSet<Integer>();
for (int i = 0; i < nums.length; i++) {
if (!set.add(nums[i])) return true;
}
return false;
}
}
法三:桶标记
public class Solution {
/**
* 桶排序变种
* 初始布尔桶内全为false,每当遇到该桶对应的值,则对该桶取反,
* 当该桶的值由true变成false时,说明有重复值,返回true
* @param nums
* @return
*/
public boolean containsDuplicate(int[] nums) {
//数组的最大值和最小值
int max = nums[0], min = nums[0];
//得到数组最小值和最大值
for (int i = 0; i < nums.length; i++) {
if(nums[i] > max) max = nums[i];
if(nums[i] < min) min = nums[i];
}
//对负数进行修正
if (min < 0) {
min = -min;
}
max = max + min;
boolean[] bucket = new boolean[max + 1]; //默认全为false
for (int i = 0; i < nums.length; i++) {
//若该桶值由true变成false,说明有重复值
if (!(bucket[nums[i] + min] = !bucket[nums[i] + min])) return true;
}
return false;
}
}
时间复杂度为O(n),空间复杂度为O(?)(和数据的最大值、最小值有关)