题目描述(简单难度)

219. Contains Duplicate II - 图1

判断是否有重复的数字出现,并且两个数字最多相隔 k

解法一 暴力

两层循环,判断当前数字后的 k 个数字是否有重复数字。

  1. public boolean containsNearbyDuplicate(int[] nums, int k) {
  2. int n = nums.length;
  3. for (int i = 0; i < n; i++) {
  4. for (int j = 1; j <= k; j++) {
  5. if (i + j >= n) {
  6. break;
  7. }
  8. if (nums[i] == nums[i + j]) {
  9. return true;
  10. }
  11. }
  12. }
  13. return false;
  14. }

解法二 map

利用 hashmapkey 存储值,value 存储下标。遍历数组,如果出现重复的值,判断下标的关系。

  1. public boolean containsNearbyDuplicate(int[] nums, int k) {
  2. HashMap<Integer, Integer> map = new HashMap<>();
  3. int n = nums.length;
  4. for (int i = 0; i < n; i++) {
  5. if (map.containsKey(nums[i])) {
  6. int index = map.get(nums[i]);
  7. if (i - index <= k) {
  8. return true;
  9. }
  10. }
  11. //更新当前值的下标
  12. map.put(nums[i], i);
  13. }
  14. return false;
  15. }

解法三 set

没想到用 set 也能做,参考 这里

因为下标相差不能超过 k,所以我们 set 中只存储 k+1 个连续的数,超过以后就将 set 中的第一个数删除。

  1. public boolean containsNearbyDuplicate(int[] nums, int k) {
  2. HashSet<Integer> set = new HashSet<>();
  3. int n = nums.length;
  4. int i = 0;
  5. //将 k + 1 个数存入 set
  6. for (; i <= k && i < n; i++) {
  7. if (set.contains(nums[i])) {
  8. return true;
  9. }
  10. set.add(nums[i]);
  11. }
  12. for (; i < n; i++) {
  13. //移除 set 中第一个数
  14. set.remove(nums[i - k - 1]);
  15. //判断 set 中是否有当前数
  16. if (set.contains(nums[i])) {
  17. return true;
  18. }
  19. //将当前数加入
  20. set.add(nums[i]);
  21. }
  22. return false;
  23. }

当然上边的代码,可以利用 set.add 的返回值来简化代码。

如果要加入的数在 set 中已经存在,那么 add 就会返回 false。我们就不需要调用 set.contains 了。

  1. public boolean containsNearbyDuplicate(int[] nums, int k) {
  2. HashSet<Integer> set = new HashSet<>();
  3. int n = nums.length;
  4. for (int i = 0; i < n; i++) {
  5. if (i > k) {
  6. set.remove(nums[i - k - 1]);
  7. }
  8. if (!set.add(nums[i])) {
  9. return true;
  10. }
  11. }
  12. return false;
  13. }

前两种解法都比较容易想到,解法三通过一个滑动窗口解决问题,很巧妙。

windliang wechat

添加好友一起进步~

如果觉得有帮助的话,可以点击 这里 给一个 star 哦 ^^

如果想系统的学习数据结构和算法,强烈推荐一个我之前学过的课程,可以点击 这里 查看详情