错题本 LeetCode 146 LFU Cache、KMP算法匹配

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第三题来再刷下。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值