适时break,避免无效操作
据我所知,leetcode可能是按最难那个用例给你打分的,非难题的用时好坏不完全看复杂度,因为可能都差不多,O(n/2)和O(n)虽然都是O(n),但是反应到成绩上是不同的,所以,尽可能的在条件足够的情况下提前break循环,是能增加成绩的。
933题,没有break耗时是有break的三倍多,所以,在复杂度之外,不要忽视小技巧。
class RecentCounter {
public:
const int backtrace_time = 3000;
deque<int> request_timestamp;
RecentCounter(){}
int ping(int t) {
request_timestamp.emplace_back(t);
for (auto it = request_timestamp.begin(); it != request_timestamp.end();++it){
if (*it < t - backtrace_time)
{
request_timestamp.pop_front();
}else{
// break;//有没有这个break至关重要
}
}
return request_timestamp.size();
}
};
合并遍历,减少遍历次数
(相似的技巧还包括,O(kn)的情况下,比如左遍历一次右遍历一次,预处理数据,最后再遍历一次,用到预处理结果,如果第二次遍历能融入到最后一次遍历,也能提速)
class Solution {
public:
vector<vector<int>> findDifference(vector<int>& nums1, vector<int>& nums2) {
vector<set<int>> sets(2);
vector<set<int>> tmp_ans(2);
vector<vector<int>> ans(2);
for(auto n:nums1){
sets[0].insert(n);
}
for(auto n:nums2){
sets[1].insert(n);
if(!sets[0].count(n)){
tmp_ans[1].insert(n);
}
}
for(auto n:nums1){
if(!sets[1].count(n)){
tmp_ans[0].insert(n);
}
}
for (int i = 0; i < tmp_ans.size();++i){
for (std::set<int>::iterator it = tmp_ans[i].begin(); it != tmp_ans[i].end(); ++it) {
ans[i].emplace_back(*it);
}
}
return ans;
}
};
使用更简单的结构体
同样模拟栈,同样用pop_back(),用Vetor可能会比deque快一些。
至少我提交能从8ms提升到6ms和4ms,虽然leetcode运行时间有点玄学。