力扣刷题01(反转链表+滑动窗口+LRU缓存机制)

本文介绍了两种常见的算法问题:反转链表和滑动窗口。在反转链表部分,展示了如何通过迭代实现链表的反转。对于滑动窗口,讲解了如何利用双指针找到字符串中最长无重复字符子串的长度。此外,还涉及LRUCache(最近最少使用缓存)的实现,结合哈希表和双向链表,实现高效缓存淘汰策略。
摘要由CSDN通过智能技术生成

好久没写总结的说,然后前段时间都忙着在写项目,刷题很少刷,那今天就来写一篇题解吧。

 反转链表

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* p;
        p=head;
        ListNode* q=nullptr;
        while(p){
            ListNode* next = p->next;//记录当前位置的下一位
            p->next=q;//将当前位置的链条与上一位链接
            q=p;//更新上一位
            p=next;//移到下一个位置继续之前的操作
        }
        return q;
    }
};

 滑动窗口

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s==""){//特判无字符的情况
            return 0;
        }
       map<char,int>a;
       int sum=0;
       int flag;
       for(int i=0,j=0;j<s.length();j++){
           if(a.find(s[j])!=a.end()){//如果有相同字符时,更新i下标
                i=max(a[s[j]],i);
           }
           sum=max(sum,j-i+1);//更新sum值
           a[s[j]]=j+1;//将value值设为该字符下标+1,使易获取字符位置

       }
        return sum;
    }
};

一开始用的暴力,果然不对,时间超限,之后用到了窗口滑动,通过更新i,j两个下标来寻找长度最大值

struct Link{//创建双向链表结点
    int k,v;
    struct Link* prev,*next;
};
class LRUCache {
private:
    int Maxsize;
    int size=0;
    struct Link*head,*tail;
    map<int,Link*>num;
public:
    LRUCache(int capacity) {
        head=new Link();//双向链表初始化
        tail=new Link();
        head->next=tail;
        tail->prev=head;
        Maxsize=capacity;//设置最大值
    }

    int get(int key) {

        if(num.find(key)==num.end()){
        //如果没有该关键字,则输出-1
            return -1;
        }
        Link *p;//将该使用到的结点插入链表头部
        p=num[key];
        p->prev->next=p->next;
        p->next->prev=p->prev;
        Link *temp=head->next;
        head->next=p;
        p->prev=head;
        p->next=temp;
        temp->prev=p;
        return p->v;
    }

    void put(int key, int value) {
        if(num.find(key)!=num.end()){//如果map中已有该关键字,则改动value值
            num[key]->v=value;
            Link *p;
        p=num[key];//将该结点移到最前
        p->prev->next=p->next;
        p->next->prev=p->prev;
        Link *temp=head->next;
        head->next=p;
        p->prev=head;
        p->next=temp;
        temp->prev=p;
            return;
        }
        size++;//长度加一
         Link *p;
            p=new Link();//加入该结点,加入表头
            p->k=key;
            p->v=value;
            p->next=head->next;
            p->next->prev=p;
            head->next=p;
            p->prev=head;
            num[key]=p;
        if(size>Maxsize){//如超出最大容量,则移除最早使用过的结点,即表尾的结点
            int k=tail->prev->k;
            tail->prev=tail->prev->prev;
            tail->prev->next=tail;
            num.erase(k);//从map表中移除该结点
        }
    }
};

该题主要是哈希表和双向链表的结合使用,哈希表的key值对应的是双向链表的结点,
遵循最近使用的结点离表头越近,越早使用的离表尾越远的原则,当容量超出最大限制时,
去除表尾的结点,同时别忘记去除哈希表中的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值