LeetCode—220. 存在重复元素 III

220. 存在重复元素 III

题目描述:
给你一个整数数组 nums 和两个整数 k 和 t 。请你判断是否存在 两个不同下标 i 和 j,使得 abs(nums[i] - nums[j]) <= t ,同时又满足 abs(i - j) <= k 。

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

考察重点:滑动窗口,桶排序

方法概括:滑动窗口:循环i向后一位,则删除一个之前存在桶中的第i-k元素。桶排序:根据特定条件将不同元素放入不同队列中(本题中用的是hashmap)

/**
桶排序思想:
    以t + 1 作为桶基准来区分元素
    如数列 1 4 8 9 12 14 16         如果t为3 则t+1为4   bucket = n / (t+1)
    放入桶 0 1 2 2 3  3  4          桶只存放满足满足条件并且靠后的元素(索引2 索引3 同样在桶2,因为是向后遍历,所以存相对靠后的索引3元素即可)
*/
func ContainsNearbyAlmostDuplicate(nums []int, k int, t int) bool {
	numslen := len(nums)
	bucket := make(map[int]int, numslen)
	for i := 0; i < numslen; i++ {
		id := getId(nums[i], t)
		_, ok := bucket[id]
		if ok { //如果相同桶中有元素,直接返回
			return true
		}
		v, ok := bucket[id+1]
		if ok && abs(nums[i]-v) <= t { //如果是相邻桶中有元素,考虑有6/3=2 5/3=1这种情况  所以还需要具体比较两元素是否差值<=t
			return true
		}
		v, ok = bucket[id-1]
		if ok && abs(nums[i]-v) <= t {
			return true
		}
		bucket[id] = nums[i]
		if i >= k { //精髓:滑动窗口,一边向后遍历,一边删除当前位置之前k位,即不满足i-j <= k的元素
			delete(bucket, getId(nums[i-k], t))
		}
	}
	return false
}

func abs(n int) int {
	if n >= 0 {
		return n
	} else {
		return -n
	}
}

func getId(n int, k int) int {
	if n >= 0 {
		return n / (k + 1)
	}
	return n/(k+1) - 1 //精髓:因为如果abs(n) < k ,比如-2 / 3 与 2 / 3 都会返回0,而负值-1则会将-2/3返回-1。由此将-2与2区分开来
} //同时因为所有负数统一-1,也不会影响其他负数。比如-4/3 将返回-2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ostrich5yw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值