ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Leetcode 220:Contains Duplicate III

2021-07-11 09:54:16  阅读:221  来源: 互联网

标签:遍历 nums int 复杂度 Contains Duplicate 绝对值 III TreeSet


Leetcode 220:Contains Duplicate III

Given an array of integers, find out whether there are two distinct indices i and j in the array such that the absolute difference between nums[i] and nums[j] is at most t and the absolute difference between i and j is at most k.

说人话:

在整数数组 nums 中,是否存在两个下标 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值小于等于 t ,且满足 i 和 j 的差的绝对值也小于等于 ķ 。

如果存在则返回 true,不存在返回 false。

示例1:

image-20210205200238631

示例2:

image-20210205200254639

[法1] 暴力法

思路

暴力法的思路就是双层遍历数据 nums,然后检查是否有满足 nums [i] 和 nums [j] 的差的绝对值小于等于 t ,且满足 i 和 j 的差的绝对值也小于等于 ķ 的情况,如果有就返回 true,如果遍历完数组还没有,就返回 false。

代码
class Solution {
    public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {

        for(int i=0;i<nums.length-1;i++){
            for(int j=i+1;j<nums.length;j++){
              	//注意这里为了避免整数 int 溢出,需要转换为 long 类型
                if(Math.abs((long)nums[i]-(long)nums[j])<=(long)t && j-i<=k){
                    return true;
                }
            }
        }
        return false;
    }
}
提交结果
image-20210205201830636
代码分析
  • 时间复杂度:O(n2)
  • 空间复杂度:O(1)
改进思路

我们需要将时间复杂度 O(n2) 降为 O(n) 或者 O(nlogn),也就是希望可以扫描一遍数组便解决问题。从题目要求的两个条件来看:

  • i 和 j 的差的绝对值小于等于 ķ 的情况
  • 滑动窗口
  • nums [i] 和 nums [j] 的差的绝对值小于等于 t
    • 利用查找表找是否有满足 v-t <= v <= v+t 的元素,这样就需要具有顺序性的查找表,那么就可以用 Tree,又由于数据的不可重复性(i != j),那么就可以用 Set,综合起来我们可以用 TreeSet 来辅助解决本问题。

[法2] 查找表

思路
image-20210205202154084
  • 遍历数组 nums[i],边遍历边将元素放到 TreeSet 中
  • 遍历到 nums[i] 的时候,检查 TreeSet 中是否存在 v-t <= v <= v+t 的元素
    • v >= v-t 可以用 treeSet.ceiling(v-t) 来判断是否存在( ceiling(v-t) 是找出 TreeSet 中大于或等于 v-t 的最小元素)
  • 如果存在,则返回 true
  • 如果不存在,则将 nums[i] 放入 TreeSet 中
  • 放入 nums[i] 后检查 TreeSet 中元素个数是否超过 k
  • 如果超过 k,就删除窗口左边的第一个元素 nums[i-k]
  • 直至遍历完整个数组
代码
class Solution {
    public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {

        //为了防止溢出,需要用 long 类型
        TreeSet<Long> treeSet = new TreeSet<>();

        //set中元素个数
        int count = 0;

        //遍历数组
        for(int i=0;i<nums.length;i++){
            //判断是否存在元素 x >= nums[i]-t 
            Long number = treeSet.ceiling((long)nums[i]-(long)t);
            //如果存在,还需要这个元素 x <= nums[i]+t
            if(number != null && number <= (long)nums[i]+(long)t){
                return true;
            }else{
                //不存在就继续往 TreeSet 中扔元素
                treeSet.add((long)nums[i]);
                count ++;

                //检查是否越出窗口
                if(count > k){
                    treeSet.remove((long)nums[i-k]);
                    count --;
                }
            }

        }
        return false;
    }
}
提交结果
image-20210205203756156
代码分析
  • 时间复杂度:时间复杂度:因为 TreeSet 每一个 add 操作的时间复杂度是 O(logn),故整体时间复杂度是 O(nlogn)
  • 空间复杂度:O(k)

标签:遍历,nums,int,复杂度,Contains,Duplicate,绝对值,III,TreeSet
来源: https://blog.51cto.com/u_15298624/3035439

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有