Cho mảng số nguyên, kiểm tra xem có tồn tại hai chỉ số khác nhau i và j sao cho:
|nums[i] - nums[j]| <= t(chênh lệch giá trị không quát).|i - j| <= k(khoảng cách chỉ số không quák).
Ví dụ: nums = [1,2,3,1], k = 3, t = 0 → trả về true vì nums[0] = nums[3] = 1 và |0-3| = 3 <= k.
Thuật toán giải quyết (Cửa sổ trượt + Multiset)
- Duy trì một
multisetchứa tối đakphần tử gần nhất. - Duyệt mảng từ trái sang phải:
- Tìm iterator
xtrỏ đến phần tử đầu tiên>= nums[i](lower_bound). - Nếu
xtồn tại và*x <= nums[i] + t→ trả vềtrue. - Nếu
xkhông phải phần tử đầu tiên, kiểm tra phần tử trước đó (prev(x)): nếu*prev(x) + t >= nums[i]→ trả vềtrue. - Chèn
nums[i]vào multiset. - Nếu kích thước multiset >
k→ xóanums[i - k]. - Kết thúc vòng lặp → trả về
false.
Ví dụ minh họa (C++)
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
multiset<long long> s;
int n = nums.size();
for (int i = 0; i < n; i++) {
auto x = s.lower_bound((long long)nums[i] - t);
if (x != s.end() && *x <= (long long)nums[i] + t) return true;
s.insert(nums[i]);
if ((int)s.size() > k) s.erase(nums[i - k]);
}
return false;
}
};
int main() {
Solution ob;
vector<int> v = {1, 2, 3, 1};
cout << ob.containsNearbyAlmostDuplicate(v, 3, 0);
}
Đầu vào
[1,2,3,1] 3 0
Đầu ra
1