217,题目:Given an array of integers, find if the array contains any duplicates. Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct.
看数组中是否包含相同元素,是则返回真,否则返回假。
思路一:使用哈希表存储已经读取过的数组元素,时间复杂度为O(N),空间复杂度也是O(N)。
public boolean containsDuplicate(int[] nums) {
Set<Integer> distinct = new HashSet<Integer>();
for(int i=0; i<nums.length; i++)
{
if(distinct.contains(nums[i]))
return true;
distinct.add(nums[i]);
}
return false;
}
思路二:先将数组排序,然后对比前后元素是否相等即可。时间复杂度为O(NlogN),空间复杂度为O(1).
public boolean containsDuplicate(int[] nums) {
Arrays.sort(nums);
for(int i=0; i<nums.length; i++)
{
if(nums[i] == nums[i+1])
return true;
}
return false;
}
思路三,将数组变为集合,比较前后的长度是否发生变化。
思路四,使用位运算来实现,使用byte数组来进行标记,这种方法目前击败了98%的方法,是很棒的实现方式!!!!
public boolean containsDuplicate(int[] nums) {
byte[] mark = new byte[150000];
for (int i : nums) {
int j = i/8;
int k = i%8;
int check = 1<<k;
if ((mark[j] & check) != 0) {
return true;
}
mark[j]|=check;
}
return false;
}
219,Given an array of integers and an integer k, find out whether there are two distinct indices i and j in the array such that nums[i] = nums[j] and the difference between i and j is at most k.
相比上一题,添加了两个数的距离在k以内的要求。
思路一:使用哈希表来存储已经读取过的数组元素,记录其值和索引下标。注意,这里不要讲两个判断语句写在一起:
if (map.containsKey(nums[i])&&(i - map.get(nums[i]) <= k))
因为这样会使判断次数过多而超时。
public boolean containsNearbyDuplicate(int[] nums, int k) {
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i = 0; i < nums.length; i++) {
if (map.containsKey(nums[i])) {
if (i - map.get(nums[i]) <= k) return true;
}
map.put(nums[i], i);
}
return false;
}
思路二:使用集合来存储K个元素,这样保留了其下标信息。使用长度为K的滑动窗口遍历数组,只要看滑动窗口内是否出现重复值即可。空间复杂度变小,且程序耗时变短。比使用HashMap更有效。
public boolean containsNearbyDuplicate(int[] nums, int k) {
Set<Integer> set = new HashSet<Integer>();
for(int i = 0; i < nums.length; i++){
if(i > k) set.remove(nums[i-k-1]);
//若集合中已经有了nums[i],则返回真。否则添加。
if(!set.add(nums[i])) return true;
}
return false;
}