1. 最长公共前缀 LeetCode 14
最优时间:\(O(mn)\),m 字符串平均长度,n 字符串数量;空间\(O(1)\),原地处理 思路:拿第一个字符串当基准,逐个字符比对其余所有字符串,遇到不匹配 / 越界直接截断返回。
cpp
#include <vector>
#include <string>
using namespace std;
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
if(strs.empty()) return "";
// 以第一个串为基准
for(int i = 0; i < strs[0].size(); ++i){
char c = strs[0][i];
for(int j = 1; j < strs.size(); ++j){
// 当前串长度不够i 或者字符不等,直接截取前缀返回
if(i >= strs[j].size() || strs[j][i] != c){
return strs[0].substr(0,i);
}
}
}
return strs[0];
}
};
2.LRU 缓存 LeetCode 146
最优解法:哈希表 + 双向链表
- get/put 均摊 \(O(1)\)
- std::list 双向链表;unordered_map 保存 key 到链表迭代器映射
- list 头部:最近使用;尾部:最久未使用,满容量删除尾部
cpp
#include <unordered_map>
#include <list>
using namespace std;
class LRUCache {
private:
int cap;
// key,value
list<pair<int,int>> l;
// key -> list迭代器
unordered_map<int, list<pair<int,int>>::iterator> mp;
public:
LRUCache(int capacity) {
cap = capacity;
}
int get(int key) {
auto it = mp.find(key);
if(it == mp.end()){
return -1;
}
// 取出节点,移动到链表头部(标记最近访问)
auto node_it = it->second;
int val = node_it->second;
l.erase(node_it);
l.push_front({key,val});
mp[key] = l.begin();
return val;
}
void put(int key, int value) {
auto it = mp.find(key);
// 1.key已经存在:删除旧节点,头部插入新值
if(it != mp.end()){
l.erase(it->second);
}else{
// 2.不存在,容量满,删掉最久未使用(链表尾部)
if(l.size() >= cap){
auto last = l.back();
mp.erase(last.first);
l.pop_back();
}
}
l.push_front({key,value});
mp[key] = l.begin();
}
};