难度:中等。
标签:设计,哈希表,字符串,二分查找。
使用了哈希表+结构体存储数据,使用二分来查找数据。结果还是超时了,44/46用例没过。
开始没看完题,以为set的时间戳是任意的,不按照时间顺序严格递增,所以写了找第一个大于等于当前时间戳的戳。
超时代码:
class TimeMap {
struct Item{
string value;
int time;
Item(string v, int t){
value = v;
time = t;
}
};
unordered_map<string, vector<Item>> data;
// 找第一个大于等于now的时间戳
int findLastIndex(vector<Item> items, int now){
int n = items.size();
int left = 0, right = n - 1, ans = n;
while(left <= right){
int mid = (left + right) / 2;
if(items[mid].time == now)return mid;
else if(items[mid].time > now){
ans = mid;
right = mid - 1;
}
else{
left = mid + 1;
}
}
return ans;
}
public:
/** Initialize your data structure here. */
TimeMap() {
}
void set(string key, string value, int timestamp) {
data[key].emplace_back(Item(value, timestamp));
}
string get(string key, int timestamp) {
if(data[key].size() == 0)return "";
if(data[key][0].time > timestamp)return "";
int idx = findLastIndex(data[key], timestamp);
if(idx != data[key].size() && data[key][idx].time == timestamp)return data[key][idx].value;
else return data[key][idx - 1].value;
}
};
/**
* Your TimeMap object will be instantiated and called as such:
* TimeMap* obj = new TimeMap();
* obj->set(key,value,timestamp);
* string param_2 = obj->get(key,timestamp);
*/
优化!
将findLastIndex换成找最后一个小于等于now的时间戳。
将struct改为pair。
还是超时。
超时代码:
class TimeMap {
unordered_map<string, vector<pair<int, string>>> data;
// 找最后一个小于等于now的时间戳
int findLastIndex(vector<pair<int, string>> items, int now){
int n = items.size();
int left = 0, right = n - 1, ans = -1;
while(left <= right){
int mid = (left + right) / 2;
if(items[mid].first == now)return mid;
else if(items[mid].first > now){
right = mid - 1;
}
else{
ans = mid;
left = mid + 1;
}
}
return ans;
}
public:
/** Initialize your data structure here. */
TimeMap() {
}
void set(string key, string value, int timestamp) {
data[key].emplace_back(pair{timestamp, value});
}
string get(string key, int timestamp) {
if(data[key].size() == 0)return "";
if(data[key][0].first > timestamp)return "";
int idx = findLastIndex(data[key], timestamp);
return data[key][idx].second;
}
};
想不到了,看题解。
题解也是这个思路,为什么我超时了?
原因:函数的参数有vector<pair<int, string>>,传入使用的不是&,实参到形参的转换非常耗时。
因此加个引用就可以了。
去掉函数的正确解法:
class TimeMap {
unordered_map<string, vector<pair<int, string>>> data;
public:
/** Initialize your data structure here. */
TimeMap() {
}
void set(string key, string value, int timestamp) {
data[key].emplace_back(pair{timestamp, value});
}
string get(string key, int timestamp) {
if(data[key].size() == 0)return "";
if(data[key][0].first > timestamp)return "";
int left = 0, right = data[key].size() - 1, ans = -1;
while(left <= right){
int mid = (left + right) / 2;
if(data[key][mid].first == timestamp){
ans = mid;
break;
}
else if(data[key][mid].first > timestamp){
right = mid - 1;
}
else{
ans = mid;
left = mid + 1;
}
}
return data[key][ans].second;
}
};
结果:
函数参数加引用的正确解法:
class TimeMap {
unordered_map<string, vector<pair<int, string>>> data;
// 找最后一个小于等于now的时间戳
int findLastIndex(vector<pair<int, string>>& items, int now){
int n = items.size();
int left = 0, right = n - 1, ans = -1;
while(left <= right){
int mid = (left + right) / 2;
if(items[mid].first == now)return mid;
else if(items[mid].first > now){
right = mid - 1;
}
else{
ans = mid;
left = mid + 1;
}
}
return ans;
}
public:
/** Initialize your data structure here. */
TimeMap() {
}
void set(string key, string value, int timestamp) {
data[key].emplace_back(pair{timestamp, value});
}
string get(string key, int timestamp) {
if(data[key].size() == 0)return "";
if(data[key][0].first > timestamp)return "";
int idx = findLastIndex(data[key], timestamp);
return data[key][idx].second;
}
};
结果:
对比两个的结果,函数调用的进栈出栈可能消耗了部分内存。