题目:
给你一个整数数组 nums 和两个整数 k 和 t 。请你判断是否存在 两个不同下标 i 和 j,使得 abs(nums[i] - nums[j]) <= t ,同时又满足 abs(i - j) <= k **。
如果存在则返回 true,不存在返回 false。
解法:
比较差值相关考虑分桶思想。每个桶大小为t + 1(因为需要把0 ~ 9分到一个桶,t需要为10).根据num获取桶的index
|index-1|index|index-1|
如果两个数在一个index中,则必然存在abs(nums[i] - nums[j]) <= t,如果在当前桶中没有数,则比较当前的数和相邻桶中存储的数的差值是否 <= t。
index依次增加,并移除i-k及之前的index所在的桶。
func containsNearbyAlmostDuplicate(nums []int, k int, t int) bool {
slideMap := make(map[int]int)
for i := 0; i < len(nums); i ++ {
id := getId(nums[i], t + 1)
if _, ok := slideMap[id]; ok {
return true
}
if val, ok := slideMap[id + 1]; ok && abs(val, nums[i]) <= t{
return true
}
if val, ok := slideMap[id - 1]; ok && abs(val, nums[i]) <= t{
return true
}
slideMap[id] = nums[i]
if i >= k {
delete(slideMap, getId(nums[i - k], t + 1))
}
}
return false
}
func getId(x, w int) int {
// w = 10 则x=[0,9],[10,19],[20,29]在一个index
// index=0, 1, 2
if x >= 0 {
return x / w
}
// [-1,-9] 的index=0,将index - 1置为index = -1
return (x / w) - 1
}
func abs(a, b int) int {
if a > b {
return a - b
}
return b - a
}