当前位置: 首页 > news >正文

云南做网站公司哪家好/互联网平台推广

云南做网站公司哪家好,互联网平台推广,b2c网站平台建设费用,网络营销策划方案展示1、问题描述 给定一个整数数组nums,k,t,判断数组中是否存在两个不同的索引i,j,使得nums[i]和nums[j]之差的绝对值不超过t,i和j之差的绝对值不超过k。 例如: 输入: nums [1,2,3,1], k 3, t …

1、问题描述

给定一个整数数组nums,k,t,判断数组中是否存在两个不同的索引i,j,使得nums[i]和nums[j]之差的绝对值不超过t,i和j之差的绝对值不超过k。
例如:

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

2、解题思路

解决这道题需要找到一组满足以下两个条件的iiijjj

  1. ∣i−j∣≤k|i - j| \le kijk
  2. ∣nums[i]−nums[j]∣≤t|nums[i] - nums[j]| \le tnums[i]nums[j]t

有很多的方法可以实现这一目标:
方法1:在滑动窗口内线性搜索
思想:每一个元素与它之前的kkk个元素进行比较,查看它们的数值之差的绝对值是否在ttt以内。具体实现时,维持一个大小为kkk的滑动窗口,在这种情况下,第一个条件始终是满足的,只需要通过线性搜索检查第二个条件是否满足就可以了。

复杂度分析:
时间复杂度:O(n×min(k,n))O(n\times min(k,n))O(n×min(k,n)),其中每次搜索都需要花费O(min(k,n))O(min(k,n))O(min(k,n))的时间,需要注意的是,每次搜索最多需要比较nnn次,哪怕kkknnn大。
空间复杂度:O(1)O(1)O(1),额外开辟的空间为常数个。

方法2:将滑动窗口元素组织成自平衡的二叉搜索树
分析:方法1真正的瓶颈在于检查第二个条件是否满足时需要扫描滑动窗口内的所有元素,因此,我们需要考虑有没有比全扫描更好的方法;

  • 一种可能的想法是始终维持窗口内的元素有序,然后检查左右边界之差是否满足第二个条件,这种方法我们虽然可以在logklogklogk的时间内找到元素插入位置, 但将该元素插入到正确位置时还是需要移动O(k)O(k)O(k)个元素,所以时间复杂度还是O(k)O(k)O(k)
  • 另一种想法是将滑动窗口内的元素组织成一个自平衡的二叉搜索树setsetset(大小为kkk)。然后对于数组numsnumsnums中的每个元素xxx,在setsetset中找到小于等于xxx的最大数ggg和大于等于xxx的最小数ttt,如果x−g<=tx-g<=txg<=t或者s−x<=ts-x<=tsx<=t成立,则说明滑动窗口中含有满足第二个条件的两个元素,否则不含有。

思想:

初始化一棵空的自平衡的二叉搜索树set;
遍历nums中的每个元素x,并进行如下操作:在set上查找大于等于x的最小数s,如果s-x<=t , 则返回true;在set上查找小于等于x的最大数g,如果x-g<=t,  则返回true;在set中插入x;如果set的大小超过了k,则从set中去除最早加入树中的那个数;返回false;

复杂度分析:
我们需要遍历这个长度为nnn的数组,对于每次遍历,搜索、插入和删除操作都需要花费O(logk)O(logk)O(logk)时间,故时间复杂度为O(nlogk)O(nlogk)O(nlogk)
空间复杂度:存储二叉搜索树所占的额外空间,为O(k)O(k)O(k)

需要注意的是:

  • 当数组中的元素非常大的时候,进行数学运算可能造成溢出(比如2147483647 - (-1))。所以可以考虑使用支持大数的数据类型,例如 long。

  • C++ 中的 std::set,std::set::upper_bound 和 std::set::lower_bound 分别等价于 Java 中的 TreeSet,TreeSet::ceiling 和 TreeSet::floor。Python 标准库不提供自平衡 BST。

方法3:利用桶的思想在线性时间内解决问题
分析:受桶排序思想的启发,可以利用桶在线性时间内解决该问题。
桶排序的思想如下所示:
将元素划分到不同桶中,接着把每个桶再独立的使用不同的排序算法进行排序,最后按照桶的顺序收集所有元素便得到了一个有序数组。
比如对大小在1到100之间的8个数进行排序,首先,我们创建5个桶(区间),这5个桶分别包含的区间是[1,20]、[21,40]、[41,60]、[61,80]、[81,100][1,20]、[21,40]、[41,60]、[61,80]、[81,100][1,20][21,40][41,60][61,80][81,100],这8个数中的任意一个都必然在一个桶中,对于值为xxx的元素来说,其桶标签为x/wx/wx/w,这里w=20w=20w=20。接着我们对每个桶内元素进行排序,最后按照桶的顺序收集所有元素。

接着我们通过一个与本问题及其相似的问题来引入算法的详细步骤:
我们把每个元素看成是一个人的生日,假设你的生日是3月份的某一天,现在需要知道班级中是否有人生日和你的生日间隔在t=30t=30t=30之内,在这里,我们假设每个月为30天,很明显,我们只需要检查所有生日在2月份、3月份、和4月份的同学就可以了。
之所以能这么做的原因在于,每个人的生日都属于一个桶,我们把这个桶称之为月份。每个桶包含的区间范围都是t,这能极大对简化我们的问题。很显然,任何不在同一个桶或相邻桶的两个元素之间的距离一定是大于t的。

我们把上述提到的桶的思想运用到这个问题中来,我们设计一些桶,让它们包含区间...,[−2t−2,−t−2],[−t−1,−1],[0,t],[t+1,2t+1],.....,[-2t-2,-t-2],[-t-1,-1],[0,t],[t+1,2t+1],.....,[2t2,t2],[t1,1],[0,t],[t+1,2t+1],...。我们把桶当作窗口,于是每次只需要检查xxx所属的桶和相邻桶的元素,终于,我们可以在常量时间内解决在窗口内搜索的问题了。需要注意的是,本问题中每个桶都只包含一个元素,因为如果超过一个元素,则说明有两个元素的距离在t之内,可以直接得到问题的答案了。

思想:

初始化一个空桶map;
遍历nums的每个元素x,并进行如下操作:获取元素x所属的桶编号m=getid(x,w);如果桶m中已经含有一个元素,则直接返回true;如果桶m-1中含有一个元素y,并且y与x的距离小于t,则返回true;如果桶m+1中含有一个元素z,并且z与x的距离小于t,则返回true;把<m,x>插入map(在桶m为空,并且相邻桶没有重复元素的情况下);如果x的索引i大于k,从map中删除<getid(nums[i-k],w),nums[i-k]>;

复杂度分析:
时间复杂度:对于这n个元素中的任意一个来说,最多只需要做3次搜索、1次插入、1次删除,而这些操都是常量时间的,故时间复杂度为O(n)O(n)O(n);
空间复杂度:需要开辟的额外空间主要是散列表,其大小和所包含的元素个数有关,故空间复杂度为O(k)O(k)O(k).

3、代码实现

#include<map>
#include<cmath>
class Solution {public://获取x所在的桶的id,由于-3/5=0,而我们需要-3/5 = -1long getId(long x, long w){return x < 0 ? (x + 1)/w - 1 : x/w;}long Abs(long a , long b){return a < b ? b-a : a-b;}bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {if(t < 0){return false;}map<long, long> bucket;long w = (long)t + 1;// map<long,long>::iterator iter;for(int i = 0; i < nums.size(); i++){// cout<<"第"<<i<<"步:"<<endl;// for(iter = bucket.begin(); iter != bucket.end(); iter++){//     cout<<"<"<<iter->first<<","<<iter->second<<">"<<endl;// }long id = getId(nums[i],w);if(bucket.find(id) != bucket.end()){return true;}if(bucket.find(id-1) != bucket.end() && Abs(bucket[id-1],nums[i]) <= t){return true;}if(bucket.find(id+1) != bucket.end() && Abs(bucket[id+1],nums[i]) <= t){return true;}bucket[id] = nums[i];if(i >= k){bucket.erase(bucket.find(getId(nums[i-k],w)));}}return false;}};

【附加】leetcode同类型题目
217. 存在重复元素
219. 存在重复的元素 II

http://www.lbrq.cn/news/100441.html

相关文章:

  • 淘宝天猫做网站咨询/常用的网络推广方式有哪些
  • 定制开发网站的公司/一个新产品策划方案
  • seo网站推广公司/百度提交工具
  • 如何做企业交易网站/搜索引擎广告形式有
  • 网站后台管理系统怎么用/页面关键词优化
  • 一次性核酸病毒采样管价格/北京seo百科
  • 域名备案期间 网站访问/实时积分榜
  • 海尔集团的电子商务网站建设/嘉兴seo
  • 一个好的产品怎么推广/申泽seo
  • wordpress 视频 slider/湖南企业seo优化推荐
  • 免费在线网站建设/百度精简版入口
  • 织梦做商城类网站教程/seo优化是什么
  • crm系统软件排名/重庆seo教程
  • 淘宝客做网站教程/9个广州seo推广神技
  • 网站建设 自动生成/百度一下百度主页
  • 一个专门做试题的网站/怎么网上宣传自己的产品
  • 网站建设公司主营业务/新的网站怎么推广
  • 网站开发常用的开发工具/公司网页制作
  • 目前国内有哪些网站做家具回收/代做百度收录排名
  • 软件网站开发合同/个人seo外包
  • 品牌网吴为简介/霸榜seo
  • 申通物流的网站建设/关键词优化公司
  • 网站建设需求分析要做的事/在线优化工具
  • 网站建设绵阳辉煌电商/949公社招聘信息
  • 梧州做网站建设/苏州疫情最新消息
  • wordpress 全站 下载/网络营销方式对比分析
  • 微企免费网站建设/seo做关键词怎么收费的
  • ps做网站 字体多大/网站的推广方法
  • 家乡网站建设策划书模板/口碑营销策略
  • 视频剪辑找什么公司/免费seo网站诊断
  • [react] class Component and function Component
  • FileCodeBox 文件快递柜 一键部署
  • MFC随笔—不使用对话框资源模板创建对话框
  • 虚幻基础:曲线
  • 整体设计 之定稿 “凝聚式中心点”原型 --整除:智能合约和DBMS的在表层挂接 能/所 依据的深层套接 之2
  • k8s下的网络通信与认证