LeetCode 146 这道题伤我三遍了。之前一直没有勇气去解决。这次终于有机会了。那我们就来KO它。
哈希表+双向链表。双向链表模拟Cache空间。之所以是要用双向链表是因为单向链表查找前置节点时需要O(n)时间复杂度,无法满足需求。
代码如下:
class LinkNode {
public:
int key;
int val;
LinkNode* prev;
LinkNode* next;
LinkNode(int _key, int _val): key(_key), val(_val), prev(nullptr), next(nullptr) {};
};
class LRUCache {
private:
int size = 0;
int maxSize;
LinkNode* virHead;
LinkNode* virTail;
map<int, LinkNode*> mymap;
public:
LRUCache(int capacity) {
virHead = new LinkNode(0,0);
virTail = new LinkNode(0,0);
virHead->next = virTail;
virTail->prev = virHead;
maxSize = capacity;
}
int get(int key) {
if (mymap[key]) {
LinkNode* cur = mymap[key];
cur->prev->next = cur->next;
cur->next->prev = cur->prev;
cur->next = virHead->next;
cur->prev = virHead;
virHead->next->prev = cur;
virHead->next = cur;
return cur->val;
}
else return -1;
}
void put(int key, int value) {
if (mymap[key]) {
LinkNode* cur = mymap[key];
cur->prev->next = cur->next;
cur->next->prev = cur->prev;
cur->next = virHead->next;
cur->prev = virHead;
virHead->next->prev = cur;
virHead->next = cur;
cur->val = value;
}
else {
LinkNode* newNode = new LinkNode(key, value);
size++;
newNode->next = virHead->next;
newNode->prev = virHead;
virHead->next->prev = newNode;
virHead->next = newNode;
if (size > maxSize) {
LinkNode* cur = virTail->prev;
virTail->prev = cur->prev;
cur->prev->next = virTail;
cur->prev = nullptr;
cur->next = nullptr;
mymap[cur->key] = nullptr;
}
mymap[key] = newNode;
}
}
};
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache* obj = new LRUCache(capacity);
* int param_1 = obj->get(key);
* obj->put(key,value);
*/
LeetCode 28 重刷
更进一步理解了考试中没写出来KMP算法的原因——对于next数组本身定义理解不够透彻。KMP数组是在不匹配时下标j能够回退的最小距离的反映,是0~j字符串最长公共前后缀(即0~next[j]和j-next[j]相同前提下next[j]能取得到的最大数)。这个值可以暴力求解。三重循环即可解决。第一重循环放每个下标,第二重循环放可能的公共前后缀长度,第三重循环放循环遍历判断是否符合最长公共前后缀的定义。
也可用二重循环,随着i的移动,
若i和j相同,将next[i]赋为j+1并移动i;
若不相同但j > 0,i--,j = next[j-1];之后随着循环i++继续比较;
若上述都不满足,随着循环i++即可
代码如下:
class Solution {
public:
int strStr(string haystack, string needle) {
int i = 1, j = 0;
vector<int> next(needle.size(), 0);
for (; i < needle.size(); i++) {
while (needle[i] == needle[j]) {
next[i] = j + 1;
i++;
j++;
if (i == needle.size() || j == needle.size()) break;
}
if (i == needle.size()) break;
if (j > 0) {
j = next[j - 1];
i--;
}
}
j = 0;
i = 0;
for (; i < haystack.size(); i++) {
while (haystack[i] == needle[j]) {
i++; j++;
if (i == haystack.size() || j == needle.size()) break;
}
if (i == haystack.size() || j == needle.size()) break;
if (j > 0) {
j = next[j - 1];
i--;
}
}
if (j == needle.size()) return i - needle.size();
else return -1;
}
};
第三题都没来得及看,考完之后整个人都很低落。现在整理了下之后好多了,还是基础不够扎实了。第三题类似CCF那种第三题,题目比较长。改天找几套CCF第三题来再刷下。