题目:

给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最大为 ķ。

示例 1:

输入: nums = [1,2,3,1], k = 3, t = 0
输出: true
示例 2:

输入: nums = [1,0,1,1], k = 1, t = 2
输出: true
示例 3:

输入: nums = [1,5,9,1,5,9], k = 2, t = 3
输出: false

解答:

首先这题用例挺TM蠢的,题目说了t和k为绝对值,居然还有k为负数的用例,劳资又不是ACM选手,只是想刷个算法题而已。。

1.桶排序:

照着官方题解写的。不过有几个用例过不去,如t==0的特殊情况,利用len(list)!=len(set(list))可判断,还有t<0、k<0的(sb)用例额外判断一下,以及某些极其分散的用例,如[200000000000,-2222222222222222],2,2这样的。我是判断一下llog(l)和max-min的大小关系(l是数组长度,max、min分别为数组最大最小数),若llogl小,那就直接排序解决,不然用桶排序的话要生成的桶太多了,而且几乎全部是无用的桶。

复杂度O(n)

代码:

 from math import log
class Solution:
def containsNearbyAlmostDuplicate(self, nums, k, t) :
l=len(nums)
if l< or t< or k<:
return False
if (t==):
return len(nums)!=len(set(nums))
_max=max(nums)
_min=min(nums)
if l*log(l)<_max-_min:
for i in range(l):
for j in range(max(i-k,),i):
if abs(nums[i]-nums[j])<=t:
return True
return False
hashtable=[[]for i in range((_max-_min)//t+1)]
for i in range(l):
x=nums[i]
m=(x-_min)//t
for p in hashtable[m]:
if abs(p[]-i)<=k and abs(p[]-x)<=t:
return True
le,ri=m-,m+
if le>=:
for y in hashtable[le]:
if abs(y[]-i)<=k and abs(y[]-x)<=t:
return True
if ri<len(hashtable):
for z in hashtable[ri]:
if abs(z[]-i)<=k and abs(z[]-x)<=t:
return True
hashtable[m].append((i,x))
return False

2.二叉搜索树+滑动窗口:

由于对于两个数的索引差有绝对值<=k的限制,所以考虑维护一个长度k的窗口进行滑动。但由于窗口内的元素是无序的,如果对于每个窗口我们都进行排序,复杂度会太高。所以考虑用有序集合(C++里的set或者multi_set),窗口大小k由我们自己维护,窗口内的有序性交给set进行维护。每当我们滑动窗口时,考察右边移入窗口的新数字nums[i],因为窗口内的数字和当前索引i的索引差的绝对值一定满足<=k的要求,那么如果窗口内有相同的数字就可以返回true。如果没有,查找窗口内有无满足大小介于[nums[i]-t,nums[i]+t]范围内的数字,如果有则返回true。这里利用C++的lower_bound和upper_bound函数。

map/set.lower_bound(num),返回大于等于num的第一个迭代器

map/set.upper_bound(num),返回大于num的第一个迭代器

带模板的lower_bound格式是这样的:lower_bound<容器迭代器类型,容器元素类型>(起始迭代器,尾迭代器,元素),如:

lower_bound<vector<int>::iterator,int>(p.begin(),p.end(),);

upper_bound模板函数类似。

这个方法还是挺巧妙的,以前没有见过,记录下,滑动窗口不一定专属于线性结构。

复杂度:O(n logk)

代码:

比较坑爹的是有几个大数用例,得加long,不然AC不了。

 class Solution {
public:
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
if(t< or k<){return false;}
set<long> st;
for (int i = ; i < nums.size(); ++i) {
if (st.count(nums[i])) {
return true;
}
auto it = st.upper_bound(nums[i]);
if (it != st.end() and *it - nums[i] <= t) {
return true;
}
it = st.lower_bound(long(nums[i]) - t);
if (it != st.end() and *it<nums[i]) {
return true;
}
st.insert(nums[i]);
if (st.size() == k+) {
st.erase(nums[i-k]);
}
}
return false;
}
};

2020-02-17 15:30:19

220. 存在重复元素 III的更多相关文章

  1. Java实现 LeetCode 220 存在重复元素 III(三)

    220. 存在重复元素 III 给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最 ...

  2. Leetcode 220.存在重复元素III

    存在重复元素III 给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最大为 ķ. ...

  3. [LeetCode]220. 存在重复元素 III

    题目链接:https://leetcode-cn.com/problems/contains-duplicate-iii/ 题目描述: 给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使 ...

  4. 【每日算法】存在重复元素 III

    题目描述 这是 LeetCode 上的 220. 存在重复元素 III, 难度为 [中等] 给你一个整数数组 nums 和两个整数 k 和 t .请你判断是否存在 两个不同下标 i 和 j,使得 ab ...

  5. [LeetCode] 220. Contains Duplicate III 包含重复元素 III

    Given an array of integers, find out whether there are two distinct indices i and j in the array suc ...

  6. [Swift]LeetCode220. 存在重复元素 III | Contains Duplicate III

    Given an array of integers, find out whether there are two distinct indices i and j in the array suc ...

  7. LeetCode220 存在重复元素 III

    给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最大为 ķ. 示例 1: 输入: ...

  8. Leetcode 存在重复元素 (219,220)

    219. 存在重复元素 II 给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的绝对值最大为 k. / ...

  9. [LeetCode] 217. Contains Duplicate 包含重复元素

    Given an array of integers, find if the array contains any duplicates. Your function should return t ...

随机推荐

  1. css样式-区域内文字不会被选中

    要注意浏览器的兼容性: -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none;

  2. Hadoop学习之路(9)ZooKeeper安装

    文章目录 1.环境准备 1.1下载zooKeeper 1.3安装zooKeeper 1.4配置zooKeeper环境变量 1.5 修改zookeeper集群配置文件 1.6 创建myid文件 1.7 ...

  3. gulp常用插件之del使用

    更多gulp常用插件使用请访问:gulp常用插件汇总 del这是一款删除文件的工具. 更多使用文档请点击访问del工具官网. 安装 npm install del API del(patterns, ...

  4. 用cookie存值

    ////用Request获取到客户端Cookie 判断是否为空 //if (Request.Cookies["CheckTime"] == null) //{ // //创建Coo ...

  5. kubernetes nodePort、targetPort、port、containerPort图解

    1. nodePort 外部机器可访问的端口. 比如一个Web应用需要被其他用户访问,那么需要配置type=NodePort,而且配置nodePort=,那么其他机器就可以通过浏览器访问scheme: ...

  6. 给静态网站的链接添加nofollow属性

    给网站的链接添加nofollow属性对SEO非常有效,如果是动态网站,实现的方法比较多,但是对于静态网站来说只能借助CSS或者JS来实现,单纯的CSS实现需要覆盖所有的链接出现位置:JS与CSS结合则 ...

  7. Linux下tomcat端口被占用

    首先查看占用端口的程序 netstat -alnp | grep 8080 然后出现 tcp6 2 0 :::8080 :: LISTEN 1392/java 杀死端口号 kill -9 1392(进 ...

  8. 3行java代码实现百度站长主动推送

    个人博客 地址:http://www.wenhaofan.com/article/push-link-seo 介绍 当网站新增了一个网页之后,此时这个网页是不能够立马被百度收录的,如果想以最快的速度被 ...

  9. Java基本语法--运算符

    运算符是一种特殊的符号,用以表示数据的运算.赋值和比较等.本篇博客详细介绍Java基本语法中的运算符,主要包括算术运算符.赋值运算符.比较运算符(关系运算符).逻辑运算符.位运算符.三元运算符. Ja ...

  10. Python标准库之sys模块

    获取Python解释器的版本信息 import sys print(sys.version) #输出 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 17:00:18) ...