LeetCode 刷题笔记---(四)
LeetCode刷题笔记---(四)
今天应该能把字节刷完,然后再刷一两道就去完成别的任务
ID:31
讲道理,如果nums长度不大的话,可以直接拿出所有数,然后作为一个十进制数,全排列出所有结果,然后取出后一个结果的排列就行
但是nums.length可以到100,这样显然不太行了
尝试了一下,不太会
看完题解后,自己写了一遍,会了,但依旧磕磕绊绊,复盘一下
其实我写的也是对的,只不过,找到升序之后我直接进行了交换,忘记从尾部开始重新找值交换
-
从后往前找到升序序列,没找到就sort一下返回答案
-
找到后,从后往前找打第一个大于升序前节点的值,进行交换
- 现在升序后节点开始都是降序了,需要重新排列一下,我就直接双指针swap了
answer:
class Solution {
public:
void nextPermutation(vector<int>& nums) {
int n = nums.size();
if(n==1)return;
int j=n;
while(j--){
if(j>0&&nums[j]>nums[j-1]){
break;
}
}
if(j<0){
sort(nums.begin(),nums.end());
}else{
int i=n;
while(i--&&i>j){
if(nums[i]>nums[j-1])break;
}
swap(nums[i],nums[j-1]);
n--;
while(n>0&&n>j){
swap(nums[n],nums[j]);
n--;j++;
}
}
}
};
这道题给我的提示是,下次可以先画图,再充分思考,每次直接思考很可能只能做对部分情况
ID:310
题目有点长,我直接示例了
思路历程:把所有点都拿出来,然后放入map,然后BFS,记录深度,如果深度变小,就清空之前的结果,将当前根节点存入,如果深度一致,就追加
细节:map里面放无向路径
唉,还是超时了,暴力求解感觉有点慢,感觉在其中如果提早加判断会好一点(没啥用
超时答案
class Solution {
public:
vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
map<int,vector<int>> hash;
vector<int> res;
queue<int> que;
int mindp=20000;
if(n==1)return {0};
for(auto c : edges){
hash[c[0]].push_back(c[1]);
hash[c[1]].push_back(c[0]);
}
for(auto c:hash){
que.push(c.first);
int depth=0;
map<int,int> visit;
while(!que.empty()){
int count=que.size();
while(count--){
int tmp=que.front();que.pop();
visit[tmp]=1;
for(int node:hash[tmp]){
if(visit.find(node)==visit.end())que.push(node);
}
}
depth++;
}
if(mindp>=depth){
if(mindp>depth)res={};
res.push_back(c.first);
mindp=depth;
}
}
return res;
}
};
看题解吧
一开始真的看不懂,后来换了个思路理解了一下,醍醐灌顶
如果所有节点都在一条线上,那么我拎起线上一点,线会折起来,我希望折起来后的长度最短,是不是拎起中点最好。
哪怕有其他线搭在这根线上,只要我能保证这条线是最长的,就能符合要求
那么问题是怎么找到这无向无环图里最长的路径呢?
任意点出发,找到最远点a,从a出发找到最远点b,ab即最长路径。
算法导论提供了证明
举个特殊例子方便大家理解的话,可以看作是椭圆边上的节点出发,如何找到椭圆上的最长弦。
点c会先找到点a,然后点a会找到点b,ab即为最长路径(这个只可意会,因为细想是有bug的)
但是这样其实比较麻烦,因为无向图你去找最远路径比较难,要记录父亲节点才能逆向推回来
我们可以再思考一下,拎起来的点可以是中点(奇数个)可以是两个点(偶数),然后从边缘剪枝(度为1)
class Solution {
public:
vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
map<int, vector<int>> hash;
vector<int> res;
queue<int> que;
vector<int> du(n, 0);
int mindp = 20000;
if (n == 1)
return {0};
for (auto c : edges) {
hash[c[0]].push_back(c[1]);
hash[c[1]].push_back(c[0]);
du[c[0]]++;
du[c[1]]++;
}
for (int i = 0; i < n; i++) {
if (du[i] == 1)
que.push(i);
}
int rest = n;
while (rest > 2) {
int count = que.size();
while (count--) {
int tmp = que.front();
que.pop();
rest--;
du[tmp] = 0;
for (int c : hash[tmp]) {
du[c]--;
if (du[c] == 1)
que.push(c);
}
}
}
while (!que.empty()) {
res.push_back(que.front());
que.pop();
}
return res;
}
};
泪目了,终于过了
重新写那道LRU内存
c++在定义结构体时,记得提前写好构造函数,例如
struct DLinkedNode {
int key, value;
DLinkedNode* prev;
DLinkedNode* next;
//以下为构造函数
DLinkedNode(): key(0), value(0), prev(nullptr), next(nullptr) {}
DLinkedNode(int _key, int _value): key(_key), value(_value), prev(nullptr), next(nullptr) {}
};
对应类也一样,比如
LRUCache(int _capacity): capacity(_capacity), size(0) {
// 使用伪头部和伪尾部节点
head = new DLinkedNode();
tail = new DLinkedNode();
head->next = tail;
tail->prev = head;
}
提前写好双向链表的基本操作(插入节点至开头)(删除节点)--> 移动节点
struct DLinkedNode {
int key, value;
DLinkedNode* prev;
DLinkedNode* next;
DLinkedNode(): key(0), value(0), prev(nullptr), next(nullptr) {}
DLinkedNode(int _key, int _value): key(_key), value(_value), prev(nullptr), next(nullptr) {}
};
class LRUCache {
private:
unordered_map<int, DLinkedNode*> cache;
DLinkedNode* head;
DLinkedNode* tail;
int size;
int capacity;
public:
LRUCache(int _capacity): capacity(_capacity), size(0) {
// 使用伪头部和伪尾部节点
head = new DLinkedNode();
tail = new DLinkedNode();
head->next = tail;
tail->prev = head;
}
int get(int key) {
if (!cache.count(key)) {
return -1;
}
// 如果 key 存在,先通过哈希表定位,再移到头部
DLinkedNode* node = cache[key];
moveToHead(node);
return node->value;
}
void put(int key, int value) {
if (!cache.count(key)) {
// 如果 key 不存在,创建一个新的节点
DLinkedNode* node = new DLinkedNode(key, value);
// 添加进哈希表
cache[key] = node;
// 添加至双向链表的头部
addToHead(node);
++size;
if (size > capacity) {
// 如果超出容量,删除双向链表的尾部节点
DLinkedNode* removed = removeTail();
// 删除哈希表中对应的项
cache.erase(removed->key);
// 防止内存泄漏
delete removed;
--size;
}
}
else {
// 如果 key 存在,先通过哈希表定位,再修改 value,并移到头部
DLinkedNode* node = cache[key];
node->value = value;
moveToHead(node);
}
}
void addToHead(DLinkedNode* node) {
node->prev = head;
node->next = head->next;
head->next->prev = node;
head->next = node;
}
void removeNode(DLinkedNode* node) {
node->prev->next = node->next;
node->next->prev = node->prev;
}
void moveToHead(DLinkedNode* node) {
removeNode(node);
addToHead(node);
}
DLinkedNode* removeTail() {
DLinkedNode* node = tail->prev;
removeNode(node);
return node;
}
};
今天3题写了好久
尤其是中间那道,一开始真想不明白...
力扣字节专题完结撒花!
继续加油吧