[leetcode]Contains Duplicate III
leetcode , C++ map 。
に言及
Given an array of integers, find out whether there are two distinct indices i and j in the array such that the difference between nums[i] and nums[j] is at most t and the difference between i and j is at most k.
1つの配列numsを与えて、2つの異なる数(下付きはそれぞれi、j)が存在するかどうかを判断し、それらは以下の2つの条件を満たす.
考え方1:二層遍歴(暴力法)
この考え方は比較的簡単で、leetcodeのこの問題もこのような方法を採用することはできないと思います.やはり、次のコードを提出するとタイムアウトになります.
class Solution {
public:
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
bool res = false;
int ns = nums.size();
for(int i = 0; i < ns - 1; i++)
{
//int max = 0;
for(int j = i + 1; j < ns && j <= i + k; j++)
{
long result = nums[i] - nums[j];
if(result > INT_MAX || result <= INT_MIN) return false;
if(abs(nums[i] - nums[j]) <= t)
{
return true;
}
}
}
return res;
}
};
考え方2:Binary Search Treeを利用して、無意味な検索を削減する
この考え方は,C++におけるmapデータ構造の特性を利用してnumsデータ中の
(nums[i] - t, nums[i] + t)
の範囲内の数を探索し,その下付き文字が条件1を満たすか否かを判断する.コードに合わせて見てみましょう.class Solution {
private:
bool overflow(int one, int two)//
{
long res = one - two;
if(res > INT_MAX || res <= INT_MIN) return true;
else return false;
}
public:
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
if(t < 0) return false;
if(k < 1) return false;
bool res = false;
int ns = nums.size();
map<int, int> hmap; // map
for(int i = 0; i < ns; i++)
{
//int max = 0;
map<int, int>::iterator it = hmap.find(nums[i]);
if(it != hmap.end()) // i nums[i]
{
if(abs(it->second - i) <= k) return true; // 。
it->second = i; // 1, 。 ,it , 。 i nums i 。
}
else
{
hmap[nums[i]] = i; // ,
}
// map , nums[i] ( ) 。 (nums[i] - t, nums[i] + t) 。
map<int, int>::iterator temp_it = hmap.find(nums[i]);
if(temp_it != hmap.begin()) // it begin , 。
{
temp_it--;
while(temp_it != hmap.begin())
{
if(overflow(temp_it->first, nums[i])) return false;
if(abs(temp_it->first - nums[i]) > t) break; // 2 ,
if(abs(temp_it->second - i) <= k) return true;
temp_it--;
}
begin
if(temp_it == hmap.begin())
{
if(overflow(temp_it->first, nums[i])) return false;
if(abs(temp_it->first - nums[i]) <= t)
{
if(abs(temp_it->second - i) <= k) return true;
}
}
}
// nums[i] + t 。
temp_it = hmap.find(nums[i]);
temp_it++;
while(temp_it != hmap.end())
{
if(overflow(temp_it->first, nums[i])) return false;
if(abs(temp_it->first - nums[i]) > t) break;
if(abs(temp_it->second - i) <= k) return true;
temp_it++;
}
}
return res;
}
};
まとめ
この問題を通じてmapの以下のいくつかの特性をまとめることができます.
log
レベルである.