Contents

ARST打卡第229周[229/521]

Algorithm

lc146_LRU缓存

思路: 看数据范围,感觉必须先有一个哈希map来进行快速O(1)查找数据已经其对应下标,然后通过数组或者链表来进行左右移动数值。 但这里的后续数组链表操作如果没法 O(logn) 就会超时。

于是决定看看题解学习一下。

**原来题解是通过 hash 表的 value 设置成链表指针的地址来达成随机访问!**然后再插入队头即可..

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
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;
    }
};

Review

阿兰·德波顿:温和的成功哲学【TED演讲】

如果你认为成功的人才有才能,那么你就会"残忍"地认为失败的人都是没有才能的人,而不是认为他们是不幸的人。 这种想法将会提高社会上的自杀率。追求自我实现的发达国家的自杀率大于任何其他国家。

以人类的社会地位去评价一个人是一种罪过。

悲剧不应该只是告诉我们失败,而是应该告诉我们他们虽然失去,但是他们不是失败者。

每个人对成功的定义或多或少受到社会上的观点影响,我们应该去探索自己真正想要的生活,才能过自己想要的成功生活。

知道完全的公平和正义是不可能的,但是会不断地去追求正义。

Tips

MacOS谷歌浏览器中文字变得很细,苹方

Share-《认知觉醒》

推荐书籍 《认知觉醒》

有句话说的是,人无法赚到认知外的钱。还有句话是钱财乃身外之物。

所以我们可以知道身体和思想才是我们能够永远带着的两个东西。 因此锻炼身体和锻炼认知就是我们在世界上好好生活的两个非常重要的事情。

这本书就写了如何锻炼认知能力,开启元认知。

其中主要的观点:

  • 设置自己想要达成的事情,然后把任务分解到自己的舒适区外的一点点的位置,从而不断进步地完成目标。
  • 早起,冥想,读书,写作,运动,从而不断锻炼自己的专注力,认知力。
  • 时常记录,反思,然后不断迭代改变,才能进化成更好的自己。

一些书摘分享

  • 人的精力是有限的,只有在精力比较充沛的时候才能容易得保持专注(抵制诱惑)。所以得珍惜自己的精力,及时休息调整。
  • 当然保持专注也需要把做事情的内容调整到适宜的难度,太难的拆分成一步步可的,太容易的就调整成限时的。
  • 番茄时钟休息不能玩手机!不要知错还一直犯错了,顺便把手表也搞成消息免打扰。

国内时间管理达人李参博客中介绍的方法,还购买了她推荐的专业番茄钟来实践体验。说实话,这个方法和工具真的很棒!每次开始阅读和写作时,我只要按下计时键就不再管时间,让自己完全专注地投入其中,直至25分钟过去后提示音响起,中途除非有极特殊的事情需要中断,否则我会将其余事情全放到一边,等专注时间结束后再处理。时间一到,我会立即合上书本或让双手马上离开键盘,然后开始5分钟的休息计时。在这5分钟里,我会做与阅读或写作无关的事情,比如:看看窗外、收收衣服、拆拆包裹,等等,但刷手机、玩游戏这些被动使用注意力的事情我不推荐,因为它们仍然是消耗精力的。

当然,25分钟只是一个参考标准,我们可以根据自己的思维耐力来设定工作时段,有的人可以集中精力半小时,而有的人也许只能集中15分钟,只要到达了自己的疲劳边缘,就可以主动停下来。而且这个“主动停止”的动作一定要坚决。很多人在一开始的时候,由于精力分散得还不明显,就不愿意主动停下来,但这往往会得不偿失。主动休息犹如主动喝水,当感到很渴的时候再喝水,其实已经晚了,你想让精力保持高位,就要学会主动停下来,这甚至可以作为一个关键点。

另外,很多人在学习和工作中都不具备不受打扰的理想条件,但只要坚持“极度专注+主动休息”的模式,效果也会让你满意。不管你能工作几分钟,只要开始了,就尽力保持专注,把无关的事情都放在一边。

  • 注意力的增强回路是正向的还是负向的,很大程度上取决于你最初的选择,这也是老生常谈的道理:要事第一!

在增强回路的起点,做出有利选择所消耗的自制力是最小的,如果等负的增强回路形成,再想改变就难喽!

在初始阶段,强迫自己先做重要的事情,一旦进入正向的增强回路,你便能拥有强大的行动力——这正是增强自制力、提升行动力的秘密。

  • 一切源于“想清楚”

你陷入怠惰、懒散、空虚的情绪中动弹不得时,往往是因为你的大脑处于模糊状态。大脑要么不清楚自己想要什么;要么同时想做的事太多,无法确定最想实现的目标是什么;要么知道目标,但没想好具体要在什么时候以什么方式去实现。

不管你处在什么状态下,只要拿出笔和纸,写下目标、写下时间,你的元认知能力就能迅速提升,你就会动力满满。归结起来还是那句话:认知越清晰,行动越坚定。

正如爱因斯坦所说:“如果给我1小时解答一道决定我生死的问题,我会花55分钟弄清楚这道题到底在问什么。一旦清楚它到底在问什么,剩下的5分钟足够回答这个问题。”

聪明的思考者都知道“想清楚”才是一切的关键,在“想清楚”这件事上,他们比任何人都愿意花时间,而普通人似乎正好相反,喜欢一头扎进生活的细节洪流中,随波逐流,因为这样似乎毫不费力。于是在普通人眼里是“知易行难”,而在聪明人眼里是“知难行易”,这一点值得我们反思。

我相信,你若真的想清楚了,就会主动实践,重构自己的行动力。相信我,一旦做到了,那感觉真的不一样!

  • 成长中的悖论:想先看到结果再行动的人往往无法看到结果。耍小聪明的人会因为结果不明朗,担心付出没有回报,所以不愿行动,以致永远停留在原地。

你觉得学英语没用,是因为你看不到生活中有需要英语的地方。只有英语学好了,和英语有关的机会才会慢慢地出现在你的周围。你觉得学历没用,是因为你根本不知道学习对你的生活轨迹能带来多少改变,你只是基于当时的场景,认为自己手里只是额外多了一张纸。你觉得锻炼身体没有用,正是因为你不去运动,所以感受不到它的价值……

没错,这个世界是有认知层次的。处在下一个认知层次的人往往看不到上一个认知层次的风景,因而只能用狭隘的视角来判断:这些东西虽然很有道理,但似乎看起来并没有什么用。

  • 认知练习也需要不断实践才能成为真正的认知

  • 稀缺心态影响自己的精力,导致自己变蠢,需要目标引导,专注在一件事情上,少就是多

  • 多角度看问题,才能更加平和包容,多多练习

  • 每日反思能减少愤怒。

  • 游戏人生,不要让事情本身束缚了你的情绪和注意力,把任务拆解成小块游戏任务的形式。当然也是把必须做的不喜欢的任务,通过换一个视角,想象自己在做一件对自己有益的事情,从而达到摆脱痛苦,获得快乐的目的。

特别是“自主需求”,它是自我决定理论的关键与核心。也就是说,我们如果能主动选择和掌控所做的事情,就会产生内在动力,获取幸福。就像前文提到的 1500米跑步测试,在大多数人眼里,它是一项考核任务,没得选择,只能被动承受,但在我眼里,它却成了一件好玩的事——游戏,于是我有了选择和掌控的能力,最终得到了优势和认可。而在整个过程中,我仅仅改变了自己对事物的看法,境况就变得完全不同,这正是积极心理学的神奇之处。