好久没写总结的说,然后前段时间都忙着在写项目,刷题很少刷,那今天就来写一篇题解吧。
反转链表
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值对应的是双向链表的结点,
遵循最近使用的结点离表头越近,越早使用的离表尾越远的原则,当容量超出最大限制时,
去除表尾的结点,同时别忘记去除哈希表中的值。