前段时间投了腾讯互娱群下的天美工作室,结果10分钟不到就收到了面试通知,约到四天后的晚上,我甚是期待,奈何这次面试给我上了一课,足足面试了我三个半小时多,而且还凉凉了,真是身心疲惫呀。
首先面试一开始,面试官给我直接说我们先来作题,我心想怕是动态规划的题就凉凉,果然面试官给了我三道题,第一题就是动态规划,看了一眼果断进军第二题。
第一题、获得目标数的总和
给你一个非负的数组nums,和一个key值,你可以再nums中每两个数中间任意加入`-`或者`+`,
使得其运算可以得到目标数key,请你返回能得到目标数key的所有方法的总和。
首先想到深度优先,遍历nums,从开头开始+
,只要小于key并且没有达到数组尾部,就继续加,直到大于key返回上一层变为-
后继续向后+
,以此类推,但是结果时间超时。而且废了我20分钟,我立刻放弃此题写下一题。后来才知道动态规划可以解决。
我已经将第一题的思路写了一篇博客,欢迎大家提供不一样的思路动态规划01背包的拓展问题
第二题、LRU的模拟实现,要求查询,插入复杂度都是O(1)
题目链接LRU缓存
这道题我用单链表实现的,面试官看完代码就问我时间复杂度,很显然不是O(1),他不是很满意。下来我自己想了想结合大佬提供的思路,使用list和unordered_map来实现
数据结构
size_t cap;//缓存容量
list<pair<int,int>> cache;//缓存块链表
unordered_map<int, list<pair<int, int>>::iterator> mp;//用来标记key值再list中迭代器的位置
思路
put的时候判断key值在mp中是否存在,不存在,则将pair<int,int> (key,value)头插到到cache的头部,如果存在,则将其取出并且插入到cache的头部。
上述执行完,只需判断当前cache.size(),是否大于容量cap,如果大于,则对list进行尾删,同时将mp中对应的key删掉。
get的时候,同样先判断当前key值在mp中是否存在,不存在则依据题目要求返回-1,否则表示存在。
接下来从mp中获取其对应的迭代器,从而获得该结点的信息,然后将该结点从这个位置删掉,再将其头插到cache中即可,再更新mp中其对应的迭代器位置即可
class LRUCache {
public:
LRUCache(int capacity)
:cap(capacity)
{
}
int get(int key)
{
auto it = mp.find(key);
if(it == mp.end()) return -1;
auto pos = it->second;//获取当前key值在cache中对应的位置
int res = pos->second;//获取value值
cache.push_front(pair<int,int> (pos->first,pos->second));//将新节点头插
cache.erase(pos);//删除旧节点
mp[key] = cache.