LeetCode日记2020.2.11
今天为队列专题。
363 矩形区域不超过K的最大数值和(hard)
参考“前缀和”二分搜索的题解,写了一个列区间分治版本的解法,对于本题来说列区间分治并不会带来时间复杂度的减小。
class Solution {
public:
int maxSumSubmatrix(vector<vector<int>>& matrix, int k) {
for(const auto& row: matrix)
{
preSum.push_back(vector<int>(1,0));
auto& rowPreSum = preSum.back();
for(const auto& i: row)
{
rowPreSum.push_back(rowPreSum.back() + i);
}
}
colS = vector<int>(matrix.size(), 0);
maxI = numeric_limits<int>::min();
maxSumK(0, matrix.front().size(), k);
return maxI;
}
bool maxSumK(int beg, int End, int k)
{
if(beg + 1 == End)
{
for(int i=0;i<colS.size();++i)
colS[i] = preSum[i][End] - preSum[i][beg];
if(findMax(k))
return true;
}
else
{
int mid = (beg + End) / 2;
if(maxSumK(beg, mid, k))
return true;
if(maxSumK(mid, End, k))
return true;
int subBeg = beg;
while(subBeg < mid)
{
for(int subEnd = mid + 1; subEnd <= End; ++subEnd)
{
for(int i=0;i<colS.size();++i)
colS[i] = preSum[i][subEnd] - preSum[i][subBeg];
if(findMax(k))
return true;
}
++subBeg;
}
}
return false;
}
bool findMax(int k)
{
set<int> biSort;
int sum = 0;
biSort.insert(0);
for(const auto& i: colS)
{
sum += i;
auto iter = biSort.lower_bound(sum - k);
if(iter != biSort.end())
{
int subSum = sum - *iter;
if(subSum > maxI && subSum <= k)
{
maxI = subSum;
if(subSum == k)
return true;
}
}
biSort.insert(sum);
}
return false;
}
vector<vector<int>> preSum;
vector<int> colS;
int maxI;
};
933 最近的请求次数(mid)
class RecentCounter {
public:
RecentCounter() {
}
int ping(int t) {
++cnt;
deq.push_back(t);
int start = t - 3000;
while(deq.front() < start)
{
deq.pop_front();
--cnt;
}
return cnt;
}
deque<int> deq;
int cnt = 0;
};
/**
* Your RecentCounter object will be instantiated and called as such:
* RecentCounter* obj = new RecentCounter();
* int param_1 = obj->ping(t);
*/
621 任务调度器(mid)
自己写的模拟运行的方法,题解中的“桶”思想更为接近题目本质。
class Solution {
public:
int leastInterval(vector<char>& tasks, int n) {
priority_queue<int> deq;
int p[26];
memset(p, 0, sizeof(p));
for(const auto& c: tasks)
++p[c-'A'];
for(int i=0;i<26;++i)
{
if(p[i]!=0)
deq.push(p[i]);
}
int time = 0;
deque<int> cache(n + 1, 0);
int cacheSize = deq.size();
while(cacheSize > 0)
{
auto ca = cache.front();
cache.pop_front();
if(ca!=0)
deq.push(ca);
if(!deq.empty())
{
auto t = deq.top();
deq.pop();
cache.push_back(--t);
if(t == 0)
--cacheSize;
}
else
cache.push_back(0);
++time;
}
return time;
}
};
641 设计循环双段队列(mid)
class MyCircularDeque {
public:
/** Initialize your data structure here. Set the size of the deque to be k. */
MyCircularDeque(int k) {
deq.resize(k + 1);
size = k + 1;
beg = 0;
End = 0;
}
/** Adds an item at the front of Deque. Return true if the operation is successful. */
bool insertFront(int value) {
if(isFull())
return false;
beg = (--beg + size) % size;
deq[beg] = value;
return true;
}
/** Adds an item at the rear of Deque. Return true if the operation is successful. */
bool insertLast(int value) {
if(isFull())
return false;
deq[End] = value;
End = (++End)%size;
return true;
}
/** Deletes an item from the front of Deque. Return true if the operation is successful. */
bool deleteFront() {
if(isEmpty())
return false;
beg = (++beg)%size;
return true;
}
/** Deletes an item from the rear of Deque. Return true if the operation is successful. */
bool deleteLast() {
if(isEmpty())
return false;
End = (--End + size)%size;
return true;
}
/** Get the front item from the deque. */
int getFront() {
if(isEmpty())
return -1;
return deq[beg];
}
/** Get the last item from the deque. */
int getRear() {
if(isEmpty())
return -1;
return deq[(End - 1 + size)%size];
}
/** Checks whether the circular deque is empty or not. */
bool isEmpty() {
return beg == End;
}
/** Checks whether the circular deque is full or not. */
bool isFull() {
return (End + 1)%size == beg;
}
vector<int> deq;
int beg;
int End;
int size;
};
/**
* Your MyCircularDeque object will be instantiated and called as such:
* MyCircularDeque* obj = new MyCircularDeque(k);
* bool param_1 = obj->insertFront(value);
* bool param_2 = obj->insertLast(value);
* bool param_3 = obj->deleteFront();
* bool param_4 = obj->deleteLast();
* int param_5 = obj->getFront();
* int param_6 = obj->getRear();
* bool param_7 = obj->isEmpty();
* bool param_8 = obj->isFull();
*/