题目
给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 i 和 j ,满足 nums[i] == nums[j] 且 abs(i - j) <= k 。如果存在,返回 true ;否则,返回 false 。
示例 1:
输入:nums = [1,2,3,1], k = 3 输出:true 示例 2:
输入:nums = [1,0,1,1], k = 1 输出:true 示例 3:
输入:nums = [1,2,3,1,2,3], k = 2 输出:false
提示:
1 <= nums.length <= 105 -109 <= nums[i] <= 109 0 <= k <= 105
V1-基础解法
package com.github.houbb.leetcode.F200T300;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 i 和 j ,满足 nums[i] == nums[j] 且 abs(i - j) <= k 。如果存在,返回 true ;否则,返回 false 。
*
*
*
* 示例 1:
*
* 输入:nums = [1,2,3,1], k = 3
* 输出:true
* 示例 2:
*
* 输入:nums = [1,0,1,1], k = 1
* 输出:true
* 示例 3:
*
* 输入:nums = [1,2,3,1,2,3], k = 2
* 输出:false
*
*
*
*
* 提示:
*
* 1 <= nums.length <= 10^5
* -10^9 <= nums[i] <= 10^9
* 0 <= k <= 10^5
*/
public class T219_ContainsDuplicateII_V1 {
public static void main(String[] args) {
T219_ContainsDuplicateII_V1 v1 = new T219_ContainsDuplicateII_V1();
int[] nums = new int[]{1,2,3,1,2,3};
System.out.println(v1.containsNearbyDuplicate(nums, 2));
}
/**
* 思路1:暴力算法。
*
* 首先需要找到全部相同的元素?
* 1. 通过 HashMap 将值,和 index 放入 list?
* 2. abs 如何计算?直接结算就行?
* 3. 如果存在多个元素怎么办?怎么找到最小的两个元素的差值?
*
*
* @param nums 数组
* @param k 最小距离
* @return 结果
*/
public boolean containsNearbyDuplicate(int[] nums, int k) {
//1. 数据处理
Map<Integer, List<Integer>> dataMap = new HashMap<>();
for(int i = 0; i < nums.length; i++) {
int num = nums[i];
List<Integer> indexList = dataMap.getOrDefault(num, new ArrayList<>());
indexList.add(i);
// 判断距离
if(indexList.size() > 1) {
// 开始计算
int min = getMinDistance(indexList);
if(min <= k) {
return true;
}
}
dataMap.put(num, indexList);
}
return false;
}
/**
* 正常获取最小值,需要先排序。
* 但是这里其实是天然的排序的。
* 只需要计算2个之间的距离就行
*
*
* 这里多次计算,可以使用 dp 优化?
* @param otherNums 数字
* @return 结果
*/
private int getMinDistance(List<Integer> otherNums) {
int result = Integer.MAX_VALUE;
for(int i = 0; i < otherNums.size()-1; i++) {
int distance = otherNums.get(i+1) - otherNums.get(i);
if(distance < result) {
result = distance;
}
}
return result;
}
}
V2-改进最小距离
天然排序,直接2个之间即可。
/**
* 正常获取最小值,需要先排序。
* 但是这里其实是天然的排序的。
* 只需要计算2个之间的距离就行
*
*
* 这里多次计算,可以使用 dp 优化?
* @param otherNums 数字
* @return 结果
*/
private int getMinDistance(List<Integer> otherNums) {
int result = Integer.MAX_VALUE;
for(int i = 0; i < otherNums.size()-1; i++) {
int distance = otherNums.get(i+1) - otherNums.get(i);
if(distance < result) {
result = distance;
}
}
return result;
}
参考资料
https://leetcode.com/problems/contains-duplicate/submissions/