From f24100382070db78e1a2b54a024fc7ea26e7b8df Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Thu, 11 Feb 2021 17:13:28 +0800 Subject: [PATCH 01/50] doc: change readme --- "\345\211\221\346\214\207offer/readme.md" | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git "a/\345\211\221\346\214\207offer/readme.md" "b/\345\211\221\346\214\207offer/readme.md" index 667914f..e38fb37 100644 --- "a/\345\211\221\346\214\207offer/readme.md" +++ "b/\345\211\221\346\214\207offer/readme.md" @@ -1,3 +1,10 @@ # 《剑指offer》题解 -你可以根据关键词搜索到 《剑指offer》上对应的 leetcode 题目。 +《剑指offer》是一本经典的面试算法书籍,包含了大量常见笔试和面试题,笔者这里编写和练习了大部分题目的题解提供大家参考。 +如果可以搜到对应的 leetcode 题目,笔者会在代码注释里添加链接,方便读者直接找到对应的题目进行练习。 + +你也可以根据关键词搜索到 《剑指offer》上对应的 leetcode 题目,尝试自己思考并且提交一下,看看能否跑通所有测试用例。 + +# 勘误 + +如果您发现缺失的题目或者忘记附上 leetcode 链接,可以直接提交 MR 笔者合并进去。如果有错误也欢迎批评指正,及时修复。 From ceb45067767cd0c33cab42059e0e5d417c3e8789 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Wed, 14 Apr 2021 13:04:56 +0800 Subject: [PATCH 02/50] docs: update readme; fix queue list doc --- README.md | 3 ++- "docs/04_\351\230\237\345\210\227/queue.md" | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 15b5991..61d3f72 100644 --- a/README.md +++ b/README.md @@ -115,10 +115,11 @@ Python 抽象程度比较高, 我们能用更少的代码来实现功能,同 ## 算法可视化 -学习算法的过程中有时候会比较抽象,这里给大家推荐一些可视化的网站,方便更直观地理解: +学习算法的过程中有时候会比较抽象,这里给大家推荐一些可视化的网站,方便更直观地理解各种算法和数据结构的执行步骤: - https://github.com/algorithm-visualizer/algorithm-visualizer - https://www.cs.usfca.edu/~galles/visualization/Algorithms.html +- https://runestone.academy/runestone/books/published/pythonds/index.html# ## 讲课形式 diff --git "a/docs/04_\351\230\237\345\210\227/queue.md" "b/docs/04_\351\230\237\345\210\227/queue.md" index ffac287..a1a2b15 100644 --- "a/docs/04_\351\230\237\345\210\227/queue.md" +++ "b/docs/04_\351\230\237\345\210\227/queue.md" @@ -22,10 +22,10 @@ 我们先来看看 list 可以不?对照这个三个需求,看看能否满足: - 1.我们选择了 list -- 2.看起来队列需要从头删除,向尾部增加元素,也就是 list.insert(0, element) 和 list.append(element) -- 3.嗯,貌似 list.insert(0, element) 会导致所有list元素后移,O(n)复杂度。append 平均倒是O(1),但是如果内存不够还要重新分配内存。 +- 2.看起来队列需要从头删除,向尾部增加元素,也就是 list.pop(0) 和 list.append(element) +- 3.嗯,貌似 list.pop(0) 会导致所有其后所有元素向前移动一个位置,O(n)复杂度。append 平均倒是O(1),但是如果内存不够还要重新分配内存。 -你看,使用了 list 的话频繁 insert(0, element) 和 append 都是非常低效的。 +你看,使用了 list 的话频繁 pop(0) 是非常低效的。 脑子再转转, 我们第二章实现了 链表 LinkedList,看看能否满足要求: - 1.这里选择 LinkedList From 8bdb901f519d3164cc5bbc55a78107f64c173acd Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Wed, 14 Apr 2021 13:10:21 +0800 Subject: [PATCH 03/50] =?UTF-8?q?docs:=20list=20=E5=AE=9E=E7=8E=B0=20queue?= =?UTF-8?q?=20=E4=B8=A4=E7=A7=8D=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "docs/04_\351\230\237\345\210\227/queue.md" | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git "a/docs/04_\351\230\237\345\210\227/queue.md" "b/docs/04_\351\230\237\345\210\227/queue.md" index a1a2b15..bae29fb 100644 --- "a/docs/04_\351\230\237\345\210\227/queue.md" +++ "b/docs/04_\351\230\237\345\210\227/queue.md" @@ -25,9 +25,10 @@ - 2.看起来队列需要从头删除,向尾部增加元素,也就是 list.pop(0) 和 list.append(element) - 3.嗯,貌似 list.pop(0) 会导致所有其后所有元素向前移动一个位置,O(n)复杂度。append 平均倒是O(1),但是如果内存不够还要重新分配内存。 -你看,使用了 list 的话频繁 pop(0) 是非常低效的。 +你看,使用了 list 的话频繁 pop(0) 是非常低效的。(当然list 实现还有另一种方式就是插入用 list.insert(0, item),删除用list.pop()) 脑子再转转, 我们第二章实现了 链表 LinkedList,看看能否满足要求: + - 1.这里选择 LinkedList - 2.删除头元素 LinkedList.popleft(),追加 append(element)。都可以满足 - 3.哇欧,这两个操作都是 O(1) 的,完美。 From 3dd66220bc952bcd9e3daa76bf0014818332facc Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Wed, 14 Apr 2021 13:14:22 +0800 Subject: [PATCH 04/50] =?UTF-8?q?fix:=2033=5FSortArrayForMinNumber=20?= =?UTF-8?q?=E9=A2=98=E7=9B=AE=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\210\220\346\234\200\345\260\217\347\232\204\346\225\260).py" | 1 + 1 file changed, 1 insertion(+) diff --git "a/\345\211\221\346\214\207offer/33_SortArrayForMinNumber(\346\212\212\346\225\260\347\273\204\346\216\222\346\210\220\346\234\200\345\260\217\347\232\204\346\225\260).py" "b/\345\211\221\346\214\207offer/33_SortArrayForMinNumber(\346\212\212\346\225\260\347\273\204\346\216\222\346\210\220\346\234\200\345\260\217\347\232\204\346\225\260).py" index 90e3c4c..b488a2f 100644 --- "a/\345\211\221\346\214\207offer/33_SortArrayForMinNumber(\346\212\212\346\225\260\347\273\204\346\216\222\346\210\220\346\234\200\345\260\217\347\232\204\346\225\260).py" +++ "b/\345\211\221\346\214\207offer/33_SortArrayForMinNumber(\346\212\212\346\225\260\347\273\204\346\216\222\346\210\220\346\234\200\345\260\217\347\232\204\346\225\260).py" @@ -3,6 +3,7 @@ 题目:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。 例如输入数组{3,32,321},则打印出这3个数字能排成的最小数字321323。 +类似的 leetcode 题目如下,不过是排成的最大的数字: https://leetcode.com/problems/largest-number/ From 513547526d2926f8e8bff36e9b83905085aa3ee5 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Wed, 14 Apr 2021 14:22:58 +0800 Subject: [PATCH 05/50] docs: update readme mooc --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 61d3f72..3c5ef17 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,11 @@ leetcode 实战教程(推荐): - [图解Python数据结构与算法-实战篇- leetcode经典题目实战](https://edu.csdn.net/course/detail/29389?event_id=1256&event_type=fission&share_username=WangPegasus&sign=22bded1300551606e3882cf6e4a265a1) +笔者的其他课程: + +- [玩转Vim 从放弃到爱不释手](https://www.imooc.com/learn/1129) +- [Python工程师面试宝典](https://coding.imooc.com/class/318.html) + ## 痛点 - 讲 Python 数据结构和算法的资料很少,中文资料更少 - 很多自学 Python 的工程师对基础不够重视,面试也发现很多数据结构和算法不过关,很多人挂在了基础的数据结构和算法上 From 86aff457b99e9fa8f338071f894d35b2b0dcff87 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Mon, 8 Nov 2021 19:21:31 +0800 Subject: [PATCH 06/50] update leetcode course link --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3c5ef17..6e9ab30 100644 --- a/README.md +++ b/README.md @@ -18,11 +18,11 @@ - [readthedoc 电子书下载](http://python-data-structures-and-algorithms.readthedocs.io/zh/latest/) - [《开源一个 Python 算法和数据结构中文教程[视频]》](https://zhuanlan.zhihu.com/p/36038003) 视频讲解示例 -leetcode 实战教程(推荐): +leetcode 实战图解教程(推荐): 如果您有一定的基础,只是想快速针对面试刷题,也可以直接参考笔者针对《剑指offer》和 leetcode 经典题目的 Python 刷题图解实战。 -- [图解Python数据结构与算法-实战篇- leetcode经典题目实战](https://edu.csdn.net/course/detail/29389?event_id=1256&event_type=fission&share_username=WangPegasus&sign=22bded1300551606e3882cf6e4a265a1) +- [图解Python数据结构与算法-实战篇- leetcode经典题目实战](https://study.163.com/course/courseMain.htm?courseId=1212203808&share=2&shareId=400000000496051) 笔者的其他课程: From d42337b918593cc7d4a35f12902ffaf3bf22091b Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Sun, 19 Dec 2021 16:23:51 +0800 Subject: [PATCH 07/50] =?UTF-8?q?leetcode=20cn=20=E5=89=91=E6=8C=87offer?= =?UTF-8?q?=20=E9=A2=98=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../readme.md" => "\345\211\221\346\214\207offer/README.md" | 6 ++++++ 1 file changed, 6 insertions(+) rename "\345\211\221\346\214\207offer/readme.md" => "\345\211\221\346\214\207offer/README.md" (77%) diff --git "a/\345\211\221\346\214\207offer/readme.md" "b/\345\211\221\346\214\207offer/README.md" similarity index 77% rename from "\345\211\221\346\214\207offer/readme.md" rename to "\345\211\221\346\214\207offer/README.md" index e38fb37..04011b5 100644 --- "a/\345\211\221\346\214\207offer/readme.md" +++ "b/\345\211\221\346\214\207offer/README.md" @@ -8,3 +8,9 @@ # 勘误 如果您发现缺失的题目或者忘记附上 leetcode 链接,可以直接提交 MR 笔者合并进去。如果有错误也欢迎批评指正,及时修复。 + +# leetcode + +目前 leetcode 中文官方网站已经得到授权,不用辛苦找题目,可以直接在这个题库链接找到大部分题目练习: + +https://leetcode-cn.com/problem-list/xb9nqhhg/ From feb61835fc053278dee35a110732305902a88b21 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Sat, 15 Jan 2022 12:50:21 +0800 Subject: [PATCH 08/50] python builtin PriorityQueue --- .../priority_queue.py" | 25 ++++++++++++++++ .../builtins.md" | 30 ++++++++++--------- 2 files changed, 41 insertions(+), 14 deletions(-) diff --git "a/docs/16_\344\274\230\345\205\210\347\272\247\351\230\237\345\210\227/priority_queue.py" "b/docs/16_\344\274\230\345\205\210\347\272\247\351\230\237\345\210\227/priority_queue.py" index 039885c..4e0340c 100644 --- "a/docs/16_\344\274\230\345\205\210\347\272\247\351\230\237\345\210\227/priority_queue.py" +++ "b/docs/16_\344\274\230\345\205\210\347\272\247\351\230\237\345\210\227/priority_queue.py" @@ -129,3 +129,28 @@ def test_priority_queue(): while not pq.is_empty(): res.append(pq.pop()) assert res == ['purple', 'orange', 'black', 'white'] + + +def test_buildin_PriorityQueue(): # python3 + # https://pythonguides.com/priority-queue-in-python/ + from queue import PriorityQueue + q = PriorityQueue() + q.put((10, 'Red balls')) + q.put((8, 'Pink balls')) + q.put((5, 'White balls')) + q.put((4, 'Green balls')) + while not q.empty(): + item = q.get() + print(item) + + +def test_buildin_heapq_as_PriorityQueue(): + import heapq + s_roll = [] + heapq.heappush(s_roll, (4, "Tom")) + heapq.heappush(s_roll, (1, "Aruhi")) + heapq.heappush(s_roll, (3, "Dyson")) + heapq.heappush(s_roll, (2, "Bob")) + while s_roll: + deque_r = heapq.heappop(s_roll) + print(deque_r) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index 40d838b..7598fc2 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -1,23 +1,25 @@ # Python 常用内置算法和数据结构 + 相信到这里大家对常用的数据结构和算法及其实现都比较熟悉了。 之前在每章的数据结构和算法中涉及到的章节我都会提到对应的 python 内置模块,一般如果内置的可以满足需求,我们优先使用内置模块, 因为在性能和容错性方面内置模块要好于我们自己实现(比如有些是 c 实现的)。本章我们不会再对每个模块的原理详细说明,仅列举出一些常见模块供大家参考, 如果有需要最好的学习方式就是参考 Python 的官方文档。很多高级的数据结构我们也可以通过 google 搜索现成的库拿来直接用。 - 常用内置数据类型:list, tuple, dict, set, frozenset -- collections -- heapq -- bisect +- collections 模块:Counter(计数器), deque(双端队列), OrderedDict(有序字典),defaultdict(默认值字典) +- heapq: 堆操作 +- bisect: 二分查找 -下边我列了一个常用的表格,如果有遗漏可以在 issue 中提出。确保你了解这些数据结构和算法的使用以及时间、空间复杂度。 +下边我列了一个常用 python 内置数据结构和算法的表格,如果有遗漏可以在 issue 中提出。确保你了解这些数据结构和算法的使用以及时间、空间复杂度。 -| 数据结构/算法 | 语言内置 | 内置库 | -|----------------|---------------------------------|---------------------------------------------------------------| -| 线性结构 | list(列表)/tuple(元祖) | array(数组,不常用)/collections.namedtuple | -| 链式结构 | | collections.deque(双端队列) | -| 字典结构 | dict(字典) | collections.Counter(计数器)/OrderedDict(有序字典)/defaultdict | -| 集合结构 | set(集合)/frozenset(不可变集合) | | -| 排序算法 | sorted | | -| 二分算法 | | bisect模块 | -| 堆算法 | | heapq模块 | -| 缓存算法 | | functools.lru_cache(Least Recent Used, python3) | +| 数据结构/算法 | 语言内置 | 内置库 | +|---------------|---------------------------------|---------------------------------------------------------------| +| 线性结构 | list(列表)/tuple(元祖) | array(数组,不常用)/collections.namedtuple | +| 链式结构 | | collections.deque(双端队列) | +| 字典结构 | dict(字典) | collections.Counter(计数器)/OrderedDict(有序字典)/defaultdict | +| 集合结构 | set(集合)/frozenset(不可变集合) | | +| 排序算法 | sorted | | +| 二分算法 | | bisect模块 | +| 堆算法 | | heapq模块 | +| 优先级队列 | | queue.PriorityQueue | +| 缓存算法 | | functools.lru_cache(Least Recent Used, python3) | From 38546f0b07c84afe4b87d4ad5afd8754a1c40dd7 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Sat, 15 Jan 2022 13:42:22 +0800 Subject: [PATCH 09/50] python builtin PriorityQueue Item --- .../priority_queue.py" | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git "a/docs/16_\344\274\230\345\205\210\347\272\247\351\230\237\345\210\227/priority_queue.py" "b/docs/16_\344\274\230\345\205\210\347\272\247\351\230\237\345\210\227/priority_queue.py" index 4e0340c..d735d47 100644 --- "a/docs/16_\344\274\230\345\205\210\347\272\247\351\230\237\345\210\227/priority_queue.py" +++ "b/docs/16_\344\274\230\345\205\210\347\272\247\351\230\237\345\210\227/priority_queue.py" @@ -154,3 +154,28 @@ def test_buildin_heapq_as_PriorityQueue(): while s_roll: deque_r = heapq.heappop(s_roll) print(deque_r) + + +# python3 没有了 __cmp__ 魔法函数 https://stackoverflow.com/questions/8276983/why-cant-i-use-the-method-cmp-in-python-3-as-for-python-2 +class Item: + def __init__(self, key, weight): + self.key, self.weight = key, weight + + def __lt__(self, other): # 看其来 heapq 实现只用了 小于 比较,这里定义了就可以 push 一个 item 类 + return self.weight < other.weight + + def __eq__(self, other): + return self.weight == other.weight + + def __str__(self): + return '{}:{}'.format(self.key,self.weight) + + +def test_heap_item(): + import heapq + pq = [] + heapq.heappush(pq, Item('c', 3)) + heapq.heappush(pq, Item('a', 1)) + heapq.heappush(pq, Item('b', 2)) + while pq: + print(heapq.heappop(pq)) From 84f80a49ef9a7ec9b79c5034a2a2fd5b4d8612a4 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Mon, 24 Jan 2022 23:28:48 +0800 Subject: [PATCH 10/50] python builtin --- .../builtins.md" | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index 7598fc2..5581eb3 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -23,3 +23,69 @@ | 堆算法 | | heapq模块 | | 优先级队列 | | queue.PriorityQueue | | 缓存算法 | | functools.lru_cache(Least Recent Used, python3) | + +# 一些坑 + +如果你经常使用 python2 or python3 刷题(比如力扣leetcode),有一些坑或者技巧需要注意: + +- python3 和 python2 的 dict 有所用不同,python3.7 之后的 dict 会保持插入顺序, python2 不要依赖 dict 迭代顺序,请使用 OrderedDict +- 正确初始化一个二维数组:`dp = [[0 for _ in range(col)] for _ in range(row)]`,不要用 `dp = [[0] * n] * m`, 否则里边都 +引用的同一个 list,修改一个都会变 +- python在数值范围建议用:`MAXINT = 2**63-1; MININT = -2**63` 。因为 python2 sys.maxint 和 python3 sys.maxsize 不统一 + + +# 链表题目调试函数 + +```py +# 编写链表题目经常用到的一些通用函数和调试函数,定义等,方便代码调试 + +class ListNode(object): + def __init__(self, val=0, next=None): + self.val = val + self.next = next + + def __str__(self): + return 'Node({})'.format(self.val) + + # 用来输出调试 + __repr__ = __str__ + + +# 缩写,单测方便写,比如构建链表 1->2->3 N(1, N(2, N(3))) +N = Node = ListNode + + +def to_list(head): + """linked list to python []""" + res = [] + curnode = head + while curnode: + res.append(curnode.val) + curnode = curnode.next + return res + + +def gen_list(nums): + """用数组生成一个链表方便测试 [1,2,3] 1->2->3 + """ + if not nums: + return None + head = ListNode(nums[0]) + pre = head + for i in range(1, len(nums)): + node = ListNode(nums[i]) + pre.next = node + pre = node + return head + + +def print_list(head): + """打印链表""" + cur = head + res = "" + while cur: + res += "{}->".format(cur.val) + cur = cur.next + res += "nil" + print(res) +``` From bd13a271338c23b32be65600c5d3983573a66028 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Wed, 26 Jan 2022 21:15:56 +0800 Subject: [PATCH 11/50] use heapq impl PriorityQueue --- .../priority_queue.py" | 12 +++- .../builtins.md" | 65 +++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) diff --git "a/docs/16_\344\274\230\345\205\210\347\272\247\351\230\237\345\210\227/priority_queue.py" "b/docs/16_\344\274\230\345\205\210\347\272\247\351\230\237\345\210\227/priority_queue.py" index d735d47..7b6071c 100644 --- "a/docs/16_\344\274\230\345\205\210\347\272\247\351\230\237\345\210\227/priority_queue.py" +++ "b/docs/16_\344\274\230\345\205\210\347\272\247\351\230\237\345\210\227/priority_queue.py" @@ -132,7 +132,10 @@ def test_priority_queue(): def test_buildin_PriorityQueue(): # python3 - # https://pythonguides.com/priority-queue-in-python/ + """ + 测试内置的 PriorityQueue + https://pythonguides.com/priority-queue-in-python/ + """ from queue import PriorityQueue q = PriorityQueue() q.put((10, 'Red balls')) @@ -145,6 +148,9 @@ def test_buildin_PriorityQueue(): # python3 def test_buildin_heapq_as_PriorityQueue(): + """ + 测试使用 heapq 实现优先级队列,保存一个 tuple 比较元素(tuple第一个元素是优先级) + """ import heapq s_roll = [] heapq.heappush(s_roll, (4, "Tom")) @@ -172,6 +178,10 @@ def __str__(self): def test_heap_item(): + """ + 测试使用 Item 类实现优先级队列,因为 heapq 内置使用的是小于运算法, + 重写魔术 < 比较方法即可实现 + """ import heapq pq = [] heapq.heappush(pq, Item('c', 3)) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index 5581eb3..9fcd281 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -32,6 +32,7 @@ - 正确初始化一个二维数组:`dp = [[0 for _ in range(col)] for _ in range(row)]`,不要用 `dp = [[0] * n] * m`, 否则里边都 引用的同一个 list,修改一个都会变 - python在数值范围建议用:`MAXINT = 2**63-1; MININT = -2**63` 。因为 python2 sys.maxint 和 python3 sys.maxsize 不统一 +- 优先级队列:使用内置的 heapq ,定义一个 Item 类实现"小于" 魔术方法就可以实现 # 链表题目调试函数 @@ -89,3 +90,67 @@ def print_list(head): res += "nil" print(res) ``` + + +# 内置库实现优先级队列的三种方式 + +```py +def test_buildin_PriorityQueue(): # python3 + """ + 测试内置的 PriorityQueue + https://pythonguides.com/priority-queue-in-python/ + """ + from queue import PriorityQueue + q = PriorityQueue() + q.put((10, 'Red balls')) + q.put((8, 'Pink balls')) + q.put((5, 'White balls')) + q.put((4, 'Green balls')) + while not q.empty(): + item = q.get() + print(item) + + +def test_buildin_heapq_as_PriorityQueue(): + """ + 测试使用 heapq 实现优先级队列,保存一个 tuple 比较元素(tuple第一个元素是优先级) + """ + import heapq + s_roll = [] + heapq.heappush(s_roll, (4, "Tom")) + heapq.heappush(s_roll, (1, "Aruhi")) + heapq.heappush(s_roll, (3, "Dyson")) + heapq.heappush(s_roll, (2, "Bob")) + while s_roll: + deque_r = heapq.heappop(s_roll) + print(deque_r) + + +# python3 没有了 __cmp__ 魔法函数 https://stackoverflow.com/questions/8276983/why-cant-i-use-the-method-cmp-in-python-3-as-for-python-2 +class Item: + def __init__(self, key, weight): + self.key, self.weight = key, weight + + def __lt__(self, other): # 看其来 heapq 实现只用了 小于 比较,这里定义了就可以 push 一个 item 类 + return self.weight < other.weight + + def __eq__(self, other): + return self.weight == other.weight + + def __str__(self): + return '{}:{}'.format(self.key,self.weight) + + +def test_heap_item(): + """ + 测试使用 Item 类实现优先级队列,因为 heapq 内置使用的是小于运算法, + 重写魔术 < 比较方法即可实现 + """ + import heapq + pq = [] + heapq.heappush(pq, Item('c', 3)) + heapq.heappush(pq, Item('a', 1)) + heapq.heappush(pq, Item('b', 2)) + while pq: + print(heapq.heappop(pq)) +``` From b5e517fd48aa0019d10e00ddf62f76299555f742 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Fri, 28 Jan 2022 00:57:57 +0800 Subject: [PATCH 12/50] builtin --- .../builtins.md" | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index 9fcd281..46b5a0d 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -12,21 +12,21 @@ 下边我列了一个常用 python 内置数据结构和算法的表格,如果有遗漏可以在 issue 中提出。确保你了解这些数据结构和算法的使用以及时间、空间复杂度。 -| 数据结构/算法 | 语言内置 | 内置库 | -|---------------|---------------------------------|---------------------------------------------------------------| -| 线性结构 | list(列表)/tuple(元祖) | array(数组,不常用)/collections.namedtuple | -| 链式结构 | | collections.deque(双端队列) | -| 字典结构 | dict(字典) | collections.Counter(计数器)/OrderedDict(有序字典)/defaultdict | -| 集合结构 | set(集合)/frozenset(不可变集合) | | -| 排序算法 | sorted | | -| 二分算法 | | bisect模块 | -| 堆算法 | | heapq模块 | -| 优先级队列 | | queue.PriorityQueue | -| 缓存算法 | | functools.lru_cache(Least Recent Used, python3) | +| 数据结构/算法 | 语言内置 | 内置库 | +|---------------|---------------------------------|-------------------------------------------------------------------------| +| 线性结构 | list(列表)/tuple(元祖) | array(数组,不常用)/collections.namedtuple | +| 链式结构 | | collections.deque(双端队列) | +| 字典结构 | dict(字典) | collections.Counter(计数器)/OrderedDict(有序字典)/defaultdict(默认字典) | +| 集合结构 | set(集合)/frozenset(不可变集合) | | +| 排序算法 | sorted | | +| 二分算法 | | bisect模块 | +| 堆算法 | | heapq模块 | +| 优先级队列 | | queue.PriorityQueue/heapq | +| 缓存算法 | | functools.lru_cache(Least Recent Used, python3) | # 一些坑 -如果你经常使用 python2 or python3 刷题(比如力扣leetcode),有一些坑或者技巧需要注意: +如果你使用 python2 or python3 刷题(比如力扣leetcode),有一些坑或者技巧需要注意: - python3 和 python2 的 dict 有所用不同,python3.7 之后的 dict 会保持插入顺序, python2 不要依赖 dict 迭代顺序,请使用 OrderedDict - 正确初始化一个二维数组:`dp = [[0 for _ in range(col)] for _ in range(row)]`,不要用 `dp = [[0] * n] * m`, 否则里边都 From 9a1ad7104eda101bf621d844c0d6a17d3ae8444c Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Wed, 2 Feb 2022 16:29:08 +0800 Subject: [PATCH 13/50] python3 functools.lru_cache and functools.cache --- .../builtins.md" | 1 + 1 file changed, 1 insertion(+) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index 46b5a0d..74ce4e6 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -33,6 +33,7 @@ 引用的同一个 list,修改一个都会变 - python在数值范围建议用:`MAXINT = 2**63-1; MININT = -2**63` 。因为 python2 sys.maxint 和 python3 sys.maxsize 不统一 - 优先级队列:使用内置的 heapq ,定义一个 Item 类实现"小于" 魔术方法就可以实现 +- python3 的 functools 模块自带了 cache(等价于lru_cache(maxsize=None)) 和 lru_cache 装饰器,在一些需要递归记忆化搜索的时候会很方便 # 链表题目调试函数 From 51a77e6d59f1a1408dff608f789479e011a6d46a Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Wed, 2 Feb 2022 16:39:27 +0800 Subject: [PATCH 14/50] python INTMAX, INTMIN --- .../builtins.md" | 69 ++++++++++++++++++- 1 file changed, 66 insertions(+), 3 deletions(-) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index 74ce4e6..def33bb 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -1,4 +1,4 @@ -# Python 常用内置算法和数据结构 +# Python 刷题常用内置算法和数据结构 相信到这里大家对常用的数据结构和算法及其实现都比较熟悉了。 之前在每章的数据结构和算法中涉及到的章节我都会提到对应的 python 内置模块,一般如果内置的可以满足需求,我们优先使用内置模块, @@ -22,7 +22,7 @@ | 二分算法 | | bisect模块 | | 堆算法 | | heapq模块 | | 优先级队列 | | queue.PriorityQueue/heapq | -| 缓存算法 | | functools.lru_cache(Least Recent Used, python3) | +| 缓存算法 | | functools.lru_cache(Least Recent Used, python3)/cache | # 一些坑 @@ -32,9 +32,29 @@ - 正确初始化一个二维数组:`dp = [[0 for _ in range(col)] for _ in range(row)]`,不要用 `dp = [[0] * n] * m`, 否则里边都 引用的同一个 list,修改一个都会变 - python在数值范围建议用:`MAXINT = 2**63-1; MININT = -2**63` 。因为 python2 sys.maxint 和 python3 sys.maxsize 不统一 -- 优先级队列:使用内置的 heapq ,定义一个 Item 类实现"小于" 魔术方法就可以实现 +- 优先级队列:使用内置queue.PriorityQueue or heapq ,定义一个 Item 类实现"小于" 魔术方法就可以实现,下边有代码演示 - python3 的 functools 模块自带了 cache(等价于lru_cache(maxsize=None)) 和 lru_cache 装饰器,在一些需要递归记忆化搜索的时候会很方便 +# python int 值范围 + +``` +# 乘方 (比较推荐,py2/3 都兼容不容易出错) +MAXINT = 2**63-1 +MININT = -2**63 + +# py3 +import sys +MAXINT = sys.maxsize +MININT = -sys.maxsize - 1 + +# py2 +sys.maxint + +# 位运算 +MAXINT = (1<<63) - 1 +MININT = ~MAXINT +``` + # 链表题目调试函数 @@ -155,3 +175,46 @@ def test_heap_item(): while pq: print(heapq.heappop(pq)) ``` + + +# lru_cache/cache 优化记忆化搜索 + +python3 functools 模块的 cache 功能和 lru_cache(maxsize=None) 一样,不过更加轻量更快。在记忆化递归搜索的时候很方便。 +举一个力扣上的例子,如果不加 cache 递归函数因为会大量重复计算直接超时,但是加一个装饰器就可以通过。 + +```py +""" +[337] 打家劫舍 III +https://leetcode-cn.com/problems/house-robber-iii/description/ +""" +from functools import cache, lru_cache # cache 等价于 functools.lru_cache(maxsize=None) + + +class Solution(object): + def rob(self, root): + """ + 思路 1:递归求解(注意不加 cache 会超时!!) + :type root: TreeNode + :rtype: int + """ + # @lru_cache(maxsize=None) + @cache # NOTE: 不加 cache 会直接超时,就只能用动态规划了 + def dfs(root): + if root is None: + return 0 + + if root.left is None and root.right is None: # 左右孩子都是空 + return root.val + # 不偷父节点,考虑偷 root 的左右孩子 + val1 = dfs(root.left) + dfs(root.right) + # 偷父节点 + val2 = root.val + if root.left: + val2 += dfs(root.left.left) + dfs(root.left.right) + if root.right: + val2 += dfs(root.right.left) + dfs(root.right.right) + return max(val1, val2) + + return dfs(root) + +``` From e9bd64dab2da50306bae86013bc6f628743a7af1 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Thu, 10 Feb 2022 23:37:16 +0800 Subject: [PATCH 15/50] python dict sort --- .../builtins.md" | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index def33bb..c2a760e 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -55,6 +55,19 @@ MAXINT = (1<<63) - 1 MININT = ~MAXINT ``` +# python dict 排序 + +```py +# 补充 python 根据 key,value 排序字典的 +d = {'d': 4, 'a': 1, 'b': 2, 'c':3} +# sort by key and reverse +dict(sorted(d.items())) # {'a': 1, 'b': 2, 'c': 3, 'd': 4} +dict(sorted(d.items(), reverse=True)) # {'d': 4, 'c': 3, 'b': 2, 'a': 1} + +# sort by value and reverse +dict(sorted(d.items(), key = lambda kv:kv[1])) # {'a': 1, 'b': 2, 'c': 3, 'd': 4} +dict(sorted(d.items(), key = lambda kv:kv[1], reverse=True)) # {'d': 4, 'c': 3, 'b': 2, 'a': 1} +``` # 链表题目调试函数 From 3f118f5c38660f1f049156da86dc4247ff5ce756 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Fri, 11 Feb 2022 19:02:48 +0800 Subject: [PATCH 16/50] debug tree code --- .../builtins.md" | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index c2a760e..059bdf3 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -231,3 +231,121 @@ class Solution(object): return dfs(root) ``` + + +# leetcode 二叉树调试函数 + +```py +""" +二叉树树相关问题调试函数 +""" + + +class TreeNode(object): # leetcode tree 节点定义 + def __init__(self, val=0, left=None, right=None): + self.val = val + self.left = left + self.right = right + + def __str__(self): + return "TreeNode:{} left:{} right:{}".format(self.val, self.left, self.right) + __repr__ = __str__ + + +def gen_tree_from_lc_input(vals_str): # [1,2,3] -> root TreeNode + """ 根据 输入生成一个 tree,返回 root 节点,注意输入字符串 + # [450] 删除二叉搜索树中的节点 + # https://leetcode-cn.com/problems/delete-node-in-a-bst/description/ + # 比如 450 题目单测代码可以这么写 + def test(): + s = Solution() + root = gen_tree_from_lc_input("[2,1]") + key = 1 + res = "[2]" + assert to_lc_tree_str(s.deleteNode(root, key)) == res + """ + import ast + valids = vals_str.replace("null", "None") + vals = ast.literal_eval(valids) + # 以下就是 gen_tree 函数的内容,为了方便单独使用不调用函数了 + if not vals: + return None + nodemap = {} + for i in range(len(vals)): + if vals[i] is not None: # 一开始写的 if vals[i],但是 0 节点就错了!!! + nodemap[i] = TreeNode(vals[i]) + else: + nodemap[i] = None + + root = nodemap[0] + for i in range(len(vals)): + l = 2*i + 1 + r = 2*i + 2 + cur = nodemap.get(i, None) + left = nodemap.get(l, None) + right = nodemap.get(r, None) + if cur: + cur.left = left + cur.right = right + return root + + +def to_lc_tree_str(root): # root TreeNode -> [1,2,3,null] + """返回层序序列化后的树字符串,可以和 leetcode 输出结果比对字符串""" + import json + if not root: + return '[]' + curnodes = [root] + res = [root.val] + while curnodes: + nextnodes = [] + for node in curnodes: + if node: + if node.left: + nextnodes.append(node.left) + res.append(node.left.val) + else: + nextnodes.append(None) + res.append(None) + if node.right: + nextnodes.append(node.right) + res.append(node.right.val) + else: + nextnodes.append(None) + res.append(None) + curnodes = nextnodes + + while res[-1] is None: # 最后空节点去掉 + res.pop() + s = json.dumps(res) + s = s.replace(" ", "") + return s + + +def gen_tree(vals): + """ + 根据层序遍历结果生成二叉树并且返回 root。 + 把题目中输入 null 换成 None + vals = [1,2,3,None,5] + """ + if not vals: + return None + nodemap = {} + for i in range(len(vals)): + if vals[i]: + nodemap[i] = TreeNode(vals[i]) + else: + nodemap[i] = None + + root = nodemap[0] + for i in range(len(vals)): + l = 2*i + 1 + r = 2*i + 2 + cur = nodemap.get(i, None) + left = nodemap.get(l, None) + right = nodemap.get(r, None) + if cur: + cur.left = left + cur.right = right + return root +``` From 652544eada2955c411e9bd6d0a79d6ff19f2d82c Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Sun, 13 Feb 2022 23:07:54 +0800 Subject: [PATCH 17/50] =?UTF-8?q?python2,3=20=E9=99=A4=E6=B3=95=E7=9A=84?= =?UTF-8?q?=E4=B8=8D=E5=90=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../builtins.md" | 1 + 1 file changed, 1 insertion(+) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index 059bdf3..ae48fe6 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -34,6 +34,7 @@ - python在数值范围建议用:`MAXINT = 2**63-1; MININT = -2**63` 。因为 python2 sys.maxint 和 python3 sys.maxsize 不统一 - 优先级队列:使用内置queue.PriorityQueue or heapq ,定义一个 Item 类实现"小于" 魔术方法就可以实现,下边有代码演示 - python3 的 functools 模块自带了 cache(等价于lru_cache(maxsize=None)) 和 lru_cache 装饰器,在一些需要递归记忆化搜索的时候会很方便 +- 除法变更:python2和 python3 除法做了变更要注意。还有负数除法。 python2 `int(6/-123)==-1`,但是 python3 `int(6/-123)==0` # python int 值范围 From 2b747d39e1e7a15c7271193a93dbc9d428c79e8e Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Wed, 16 Feb 2022 17:20:30 +0800 Subject: [PATCH 18/50] =?UTF-8?q?python2,3=20=E6=95=B4=E9=99=A4=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E7=94=A8=E5=8F=8C=E6=96=9C=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../builtins.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index ae48fe6..2176149 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -34,7 +34,7 @@ - python在数值范围建议用:`MAXINT = 2**63-1; MININT = -2**63` 。因为 python2 sys.maxint 和 python3 sys.maxsize 不统一 - 优先级队列:使用内置queue.PriorityQueue or heapq ,定义一个 Item 类实现"小于" 魔术方法就可以实现,下边有代码演示 - python3 的 functools 模块自带了 cache(等价于lru_cache(maxsize=None)) 和 lru_cache 装饰器,在一些需要递归记忆化搜索的时候会很方便 -- 除法变更:python2和 python3 除法做了变更要注意。还有负数除法。 python2 `int(6/-123)==-1`,但是 python3 `int(6/-123)==0` +- 除法变更:python2和 python3 除法做了变更要注意。还有负数除法。 python2 `int(6/-123)==-1`,但是 python3 `int(6/-123)==0`。整数除法统一用 "//" # python int 值范围 From b20a9072befbf85465f3d19f07b8e76b64d36080 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Thu, 17 Feb 2022 22:35:03 +0800 Subject: [PATCH 19/50] =?UTF-8?q?python=20=E4=BA=A4=E6=8D=A2=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E5=85=83=E7=B4=A0=E7=9A=84=E5=9D=91:nums[nums[i]-1],?= =?UTF-8?q?=20nums[i]=20=3D=20nums[i],=20nums[nums[i]-1]=20=E4=B8=8D?= =?UTF-8?q?=E5=8F=AF=E9=A2=A0=E5=80=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../builtins.md" | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index ae48fe6..afab7fc 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -34,7 +34,7 @@ - python在数值范围建议用:`MAXINT = 2**63-1; MININT = -2**63` 。因为 python2 sys.maxint 和 python3 sys.maxsize 不统一 - 优先级队列:使用内置queue.PriorityQueue or heapq ,定义一个 Item 类实现"小于" 魔术方法就可以实现,下边有代码演示 - python3 的 functools 模块自带了 cache(等价于lru_cache(maxsize=None)) 和 lru_cache 装饰器,在一些需要递归记忆化搜索的时候会很方便 -- 除法变更:python2和 python3 除法做了变更要注意。还有负数除法。 python2 `int(6/-123)==-1`,但是 python3 `int(6/-123)==0` +- 除法变更:python2和 python3 除法做了变更要注意。还有负数除法。 python2 `int(6/-123)==-1`,但是 python3 `int(6/-123)==0`。整数除法统一用 "//" # python int 值范围 @@ -350,3 +350,33 @@ def gen_tree(vals): cur.right = right return root ``` + +# python 交换列表元素的坑 + +``` +# 41. 缺失的第一个正数 https://leetcode-cn.com/problems/first-missing-positive/ +class Solution(object): + def firstMissingPositive(self, nums): + """ + 平常习惯了 python 里边交换元素 a,b=b,a 这里你可能这么写,那就中招了! + nums[i], nums[nums[i]-1] = nums[nums[i]-1], nums[i] # 这么写死循环! + 这个等价于 + x, y = nums[nums[i]-1], nums[i] + nums[i] = x # 这一步 nums[i] 已经修改了,下边一句赋值不是期望的 nums[i]了 + nums[nums[i]-1] = y + + :type nums: List[int] + :rtype: int + """ + n = len(nums) + for i in range(n): + while 1 <= nums[i] <= n and nums[nums[i]-1] != nums[i]: + # NOTE: 注意这一句交换右边有副作用的,不能颠倒!!! + # nums[i], nums[nums[i]-1] = nums[nums[i]-1], nums[i] # 这么写死循环! + nums[nums[i]-1], nums[i] = nums[i], nums[nums[i]-1] + for i in range(n): + if nums[i] != i+1: + return i+1 + + return n+1 +``` From fc05a51974cd4a5b4cfc1dd779cbcd16c25e94e0 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Thu, 17 Feb 2022 22:40:14 +0800 Subject: [PATCH 20/50] =?UTF-8?q?python=E6=95=B4=E6=95=B0=E9=99=A4?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../builtins.md" | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index afab7fc..ffa9eca 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -34,7 +34,8 @@ - python在数值范围建议用:`MAXINT = 2**63-1; MININT = -2**63` 。因为 python2 sys.maxint 和 python3 sys.maxsize 不统一 - 优先级队列:使用内置queue.PriorityQueue or heapq ,定义一个 Item 类实现"小于" 魔术方法就可以实现,下边有代码演示 - python3 的 functools 模块自带了 cache(等价于lru_cache(maxsize=None)) 和 lru_cache 装饰器,在一些需要递归记忆化搜索的时候会很方便 -- 除法变更:python2和 python3 除法做了变更要注意。还有负数除法。 python2 `int(6/-123)==-1`,但是 python3 `int(6/-123)==0`。整数除法统一用 "//" +- 除法变更:python2和 python3 除法做了变更要注意。还有负数除法。 python2 `int(6/-123)==-1`,但是 python3 `int(6/-123)==0`。 +整数除法统一用"//"。比如二分求中间值 `mid=(l+r)//2` 或者 `mid=l+(r-l)//2`,因为python天生支持大数不会溢出两种写法都行 # python int 值范围 From 2c523f7b5c957c5125fc683cdabdcef43f58b1cd Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Sat, 19 Feb 2022 10:40:52 +0800 Subject: [PATCH 21/50] python3 sort functools.cmp_to_key --- .../builtins.md" | 2 ++ 1 file changed, 2 insertions(+) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index ffa9eca..4371c8c 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -36,6 +36,8 @@ - python3 的 functools 模块自带了 cache(等价于lru_cache(maxsize=None)) 和 lru_cache 装饰器,在一些需要递归记忆化搜索的时候会很方便 - 除法变更:python2和 python3 除法做了变更要注意。还有负数除法。 python2 `int(6/-123)==-1`,但是 python3 `int(6/-123)==0`。 整数除法统一用"//"。比如二分求中间值 `mid=(l+r)//2` 或者 `mid=l+(r-l)//2`,因为python天生支持大数不会溢出两种写法都行 +- 自定义排序函数。python2 可以用 `nums.sort(cmp=lambda a, b: a - b)`,但是python3移除了cmp参数。 +python3如果想要用自定义排序函数可以使用 functools.cmp_to_key 函数改成 `nums.sort(key=cmp_to_key(lambda a, b: a - b))` # python int 值范围 From 1b7a3f88857d8c350bb30fceb805486eea3b8bed Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Sat, 19 Feb 2022 11:29:42 +0800 Subject: [PATCH 22/50] =?UTF-8?q?=E5=85=BC=E5=AE=B9leetcode=E5=92=8COJ?= =?UTF-8?q?=E7=9A=84=E6=8F=90=E4=BA=A4=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../builtins.md" | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index 4371c8c..aced85b 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -383,3 +383,52 @@ class Solution(object): return n+1 ``` + +# 兼容提交格式 + +注意牛客网有两种模式,一种是和 leetcode 一样的提交(无需处理输入),只需要提交核心代码。 +一种是 ACM 模式,还需要自己处理输入和输出。 +建议使用这种兼容写法,同样的题目可以同时提交到 牛客和leetcode。 +这道题目为例子 [679] 奖品分配 https://www.acwing.com/problem/content/681/ + +```py +# 这段代码可以直接以OJ输入模式提交,如果题目一样,直接复制 Solution 类就可以同时提交到leetcode +class Solution: + def solve(self, scores): + """ + 思路:记忆化搜索。时间O(N) + 对于旁边都比自己大的点,它肯定是1 + 对于旁边有比自己小的点,先算出比自己小的点的值再+1就好了。 + 每个点如果计算过了就记忆化,下次再计算他的时候不用重复递归直接返回。 + 参考:https://www.acwing.com/solution/acwing/content/1520/ + """ + from functools import lru_cache + n = len(scores) + + @lru_cache(maxsize=None) + def dfs(x): + left = (x-1+n) % n + right = (x+1) % n + + if scores[x] <= scores[left] and scores[x] <= scores[right]: # 注意是 <= ,下边是 < + return 1 + + l, r = 0, 0 + if scores[left] < scores[x]: + l = dfs(left) + if scores[right] < scores[x]: + r = dfs(right) + + return max(l, r) + 1 + + return sum([dfs(i) for i in range(n)]) + + +if __name__ == "__main__": # python3 提交,python3 input 都当做 str 输入 + so = Solution() # 构造 Solution 实例后续调用 + n = int(input()) + for i in range(n): + arrlen = input() + arr = list(map(int, input().split())) + print(so.solve(arr)) +``` From f7426264c188aa6188675d23f382accb789b8df4 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Sat, 19 Feb 2022 16:43:25 +0800 Subject: [PATCH 23/50] heap item implement __lt__ --- .../builtins.md" | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index aced85b..119d085 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -14,7 +14,7 @@ | 数据结构/算法 | 语言内置 | 内置库 | |---------------|---------------------------------|-------------------------------------------------------------------------| -| 线性结构 | list(列表)/tuple(元祖) | array(数组,不常用)/collections.namedtuple | +| 线性结构 | list(列表)/tuple(元组) | array(数组,不常用)/collections.namedtuple | | 链式结构 | | collections.deque(双端队列) | | 字典结构 | dict(字典) | collections.Counter(计数器)/OrderedDict(有序字典)/defaultdict(默认字典) | | 集合结构 | set(集合)/frozenset(不可变集合) | | @@ -152,6 +152,7 @@ def test_buildin_PriorityQueue(): # python3 def test_buildin_heapq_as_PriorityQueue(): """ 测试使用 heapq 实现优先级队列,保存一个 tuple 比较元素(tuple第一个元素是优先级) + 实际上是利用了元组tuple比较从第一个开始比较的性质 """ import heapq s_roll = [] @@ -169,15 +170,16 @@ class Item: def __init__(self, key, weight): self.key, self.weight = key, weight - def __lt__(self, other): # 看其来 heapq 实现只用了 小于 比较,这里定义了就可以 push 一个 item 类 + def __lt__(self, other): # heapq 源码实现只用了 小于 比较,这里定义了就可以 push 一个 item 类 return self.weight < other.weight - def __eq__(self, other): + def __eq__(self, other): # 这个可以省略,只要定义了 __lt__ 魔法函数就可以了 return self.weight == other.weight def __str__(self): return '{}:{}'.format(self.key,self.weight) +# Item.__lt__ = lambda self, other: self.weight < other.weight # 对于已有的类,直接加一句就可以实现作为 heap item 了 def test_heap_item(): """ From 9a2464d6b8a68447ee041fb1e25173ef2dcc819e Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Sun, 20 Feb 2022 11:58:46 +0800 Subject: [PATCH 24/50] python max heap --- .../builtins.md" | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index 119d085..b3f4e82 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -195,6 +195,45 @@ def test_heap_item(): print(heapq.heappop(pq)) ``` +# python 如何实现最大堆 +python自带了heapq 模块实现了最小堆(min-heaq),但是如果想要实现最大堆(max-heap),有几种实现方式: + +1. 对放入的数字取反。比如 10 放入 -10 ,然后取出来的时候再取反。个人倾向于这种,可以自己封装一个类防止来回取反搞晕 +2. 直接根据 heapq 模块的函数封装几个最大堆的函数,也是通过取反实现 +3. 新建一个对象重写 `__lt__` 魔术方法。这种方式也可以,但是重写魔术方法修改了语义不太好(个人不推荐) + +```py +# 方法1:封装一个 max heap 类 +import heapq +class MaxHeap: + """ + https://stackoverflow.com/questions/2501457/what-do-i-use-for-a-max-heap-implementation-in-python + """ + def __init__(self, capacity): + self.capacity = capacity + self.minheap = [] + + def push(self, val): + heapq.heappush(self.minheap, -val) # push取反后的数字, 1 -> -1 + + def pop(self): + val = heapq.heappop(self.minheap) + return -val # 拿出来的数字再取反 + + def max(self): + return -self.minheap[0] # min-heap 的数组最小值是 m[0],最大值取反 + +# 方法2: 重新定几个新的 max-heap 方法 +import heapq +def maxheappush(h, item): + return heapq.heappush(h, -item) + +def maxheappop(h): + return -heapq.heappop(h) + +def maxheapval(h): + return -h[0] +`````` # lru_cache/cache 优化记忆化搜索 From a7e0de41d778bde642ed2d1b2817cb32cbb39347 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Sun, 20 Feb 2022 12:04:16 +0800 Subject: [PATCH 25/50] python3 functools.cache --- .../builtins.md" | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index b3f4e82..1665c9e 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -233,7 +233,7 @@ def maxheappop(h): def maxheapval(h): return -h[0] -`````` +``` # lru_cache/cache 优化记忆化搜索 @@ -245,7 +245,8 @@ python3 functools 模块的 cache 功能和 lru_cache(maxsize=None) 一样,不 [337] 打家劫舍 III https://leetcode-cn.com/problems/house-robber-iii/description/ """ -from functools import cache, lru_cache # cache 等价于 functools.lru_cache(maxsize=None) +# cache 等价于 functools.lru_cache(maxsize=None), 不过python3版本低可能没有 cache 只有 lru_cache +from functools import cache, lru_cache class Solution(object): @@ -255,7 +256,7 @@ class Solution(object): :type root: TreeNode :rtype: int """ - # @lru_cache(maxsize=None) + # @lru_cache(maxsize=None) # 注意如果 python3 版本不是很新的话,只能用 lru_cache(maxsize=None) @cache # NOTE: 不加 cache 会直接超时,就只能用动态规划了 def dfs(root): if root is None: @@ -425,11 +426,11 @@ class Solution(object): return n+1 ``` -# 兼容提交格式 +# 兼容代码提交格式 注意牛客网有两种模式,一种是和 leetcode 一样的提交(无需处理输入),只需要提交核心代码。 一种是 ACM 模式,还需要自己处理输入和输出。 -建议使用这种兼容写法,同样的题目可以同时提交到 牛客和leetcode。 +建议使用这种兼容写法,同样的题目可以同时提交到 牛客、leetcode 和 acwing(python3)。 这道题目为例子 [679] 奖品分配 https://www.acwing.com/problem/content/681/ ```py From 96f9308fc223c45d8ad1a2ef4bd9be966de9a09d Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Fri, 4 Mar 2022 18:24:34 +0800 Subject: [PATCH 26/50] list/dict sort skill --- .../builtins.md" | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index 1665c9e..a3d79d3 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -28,9 +28,9 @@ 如果你使用 python2 or python3 刷题(比如力扣leetcode),有一些坑或者技巧需要注意: -- python3 和 python2 的 dict 有所用不同,python3.7 之后的 dict 会保持插入顺序, python2 不要依赖 dict 迭代顺序,请使用 OrderedDict +- python3 和 python2 的 dict 有所用不同,python3.7 之后的 dict 会保持插入顺序(不是字典序), python2 不要依赖 dict 迭代顺序,请使用 OrderedDict - 正确初始化一个二维数组:`dp = [[0 for _ in range(col)] for _ in range(row)]`,不要用 `dp = [[0] * n] * m`, 否则里边都 -引用的同一个 list,修改一个都会变 +引用的同一个 list,修改一个都会变。`[[val]*cols for _ in range(rows)]` 也行 - python在数值范围建议用:`MAXINT = 2**63-1; MININT = -2**63` 。因为 python2 sys.maxint 和 python3 sys.maxsize 不统一 - 优先级队列:使用内置queue.PriorityQueue or heapq ,定义一个 Item 类实现"小于" 魔术方法就可以实现,下边有代码演示 - python3 的 functools 模块自带了 cache(等价于lru_cache(maxsize=None)) 和 lru_cache 装饰器,在一些需要递归记忆化搜索的时候会很方便 @@ -59,18 +59,27 @@ MAXINT = (1<<63) - 1 MININT = ~MAXINT ``` -# python dict 排序 +# python list/dict 排序技巧 ```py -# 补充 python 根据 key,value 排序字典的 +# python 根据 key,value 排序字典 d = {'d': 4, 'a': 1, 'b': 2, 'c':3} -# sort by key and reverse +# dict sort by key and reverse dict(sorted(d.items())) # {'a': 1, 'b': 2, 'c': 3, 'd': 4} dict(sorted(d.items(), reverse=True)) # {'d': 4, 'c': 3, 'b': 2, 'a': 1} -# sort by value and reverse +# dict sort by value and reverse dict(sorted(d.items(), key = lambda kv:kv[1])) # {'a': 1, 'b': 2, 'c': 3, 'd': 4} dict(sorted(d.items(), key = lambda kv:kv[1], reverse=True)) # {'d': 4, 'c': 3, 'b': 2, 'a': 1} + +# 排序嵌套 list +l = [('a', 1), ('c', 2), ('b',3)] +sorted(l, key=lambda p:p[0]) # 根据第1个值排序,[('a', 1), ('b', 3), ('c', 2)] +sorted(l, key=lambda p:p[1]) # 根据第2个值排序,[('a', 1), ('c', 2), ('b', 3)] + +# 同时获取最大值的下标和值 +l = [1,2,5,4,3] +maxi, maxval = max(enumerate(l), key=lambda iv: iv[1]) # 2, 5 ``` # 链表题目调试函数 @@ -173,11 +182,11 @@ class Item: def __lt__(self, other): # heapq 源码实现只用了 小于 比较,这里定义了就可以 push 一个 item 类 return self.weight < other.weight - def __eq__(self, other): # 这个可以省略,只要定义了 __lt__ 魔法函数就可以了 - return self.weight == other.weight - - def __str__(self): - return '{}:{}'.format(self.key,self.weight) +# def __eq__(self, other): # 这个可以省略,只要定义了 __lt__ 魔法函数就可以了 +# return self.weight == other.weight +# +# def __str__(self): +# return '{}:{}'.format(self.key,self.weight) # Item.__lt__ = lambda self, other: self.weight < other.weight # 对于已有的类,直接加一句就可以实现作为 heap item 了 @@ -426,7 +435,7 @@ class Solution(object): return n+1 ``` -# 兼容代码提交格式 +# 兼容代码ACM/核心提交格式 注意牛客网有两种模式,一种是和 leetcode 一样的提交(无需处理输入),只需要提交核心代码。 一种是 ACM 模式,还需要自己处理输入和输出。 From 73595b9d2b13c3a73ef0af7aa8b0deb80542ea7f Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Sat, 5 Mar 2022 18:24:58 +0800 Subject: [PATCH 27/50] =?UTF-8?q?=E6=98=BE=E7=A4=BA=E5=88=A4=E6=96=AD?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E7=94=A8=20is=20None?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../builtins.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index a3d79d3..d69d081 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -327,7 +327,7 @@ def gen_tree_from_lc_input(vals_str): # [1,2,3] -> root TreeNode return None nodemap = {} for i in range(len(vals)): - if vals[i] is not None: # 一开始写的 if vals[i],但是 0 节点就错了!!! + if vals[i] is not None: # 一开始写的 if vals[i],但是 0 节点就错了! 应该显示判断是否为 None(空节点) nodemap[i] = TreeNode(vals[i]) else: nodemap[i] = None From a5ddb1b99063fed35de37fc9f0b70f0e3c0956ad Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Sun, 6 Mar 2022 12:05:49 +0800 Subject: [PATCH 28/50] =?UTF-8?q?python2,3=20=E9=99=A4=E6=B3=95=E7=9A=84?= =?UTF-8?q?=E5=9D=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../builtins.md" | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index d69d081..b3c990c 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -34,8 +34,9 @@ - python在数值范围建议用:`MAXINT = 2**63-1; MININT = -2**63` 。因为 python2 sys.maxint 和 python3 sys.maxsize 不统一 - 优先级队列:使用内置queue.PriorityQueue or heapq ,定义一个 Item 类实现"小于" 魔术方法就可以实现,下边有代码演示 - python3 的 functools 模块自带了 cache(等价于lru_cache(maxsize=None)) 和 lru_cache 装饰器,在一些需要递归记忆化搜索的时候会很方便 -- 除法变更:python2和 python3 除法做了变更要注意。还有负数除法。 python2 `int(6/-123)==-1`,但是 python3 `int(6/-123)==0`。 -整数除法统一用"//"。比如二分求中间值 `mid=(l+r)//2` 或者 `mid=l+(r-l)//2`,因为python天生支持大数不会溢出两种写法都行 +- 除法变更:python2和 python3 除法做了变更要注意。还有负数除法。 python2 `int(6/-123)==-1, int(-3/2)==-2`,但是 python3 `int(6/-123)==0, int(-3/2)==-1`。 +正数的整数除法统一用"//"。比如二分求中间值 `mid=(l+r)//2` 或者 `mid=l+(r-l)//2`,因为python天生支持大数不会溢出两种写法都行。负数整数除法统一写 int(a/b)。 +凡是遇到除法运算的题目建议统一使用 python3 提交。 - 自定义排序函数。python2 可以用 `nums.sort(cmp=lambda a, b: a - b)`,但是python3移除了cmp参数。 python3如果想要用自定义排序函数可以使用 functools.cmp_to_key 函数改成 `nums.sort(key=cmp_to_key(lambda a, b: a - b))` From f1e336c07316d56645b4a4069cbed992750a7391 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Wed, 9 Mar 2022 09:45:02 +0800 Subject: [PATCH 29/50] python 2d array --- .../builtins.md" | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index b3c990c..a4e5e33 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -29,8 +29,8 @@ 如果你使用 python2 or python3 刷题(比如力扣leetcode),有一些坑或者技巧需要注意: - python3 和 python2 的 dict 有所用不同,python3.7 之后的 dict 会保持插入顺序(不是字典序), python2 不要依赖 dict 迭代顺序,请使用 OrderedDict -- 正确初始化一个二维数组:`dp = [[0 for _ in range(col)] for _ in range(row)]`,不要用 `dp = [[0] * n] * m`, 否则里边都 -引用的同一个 list,修改一个都会变。`[[val]*cols for _ in range(rows)]` 也行 +- 正确初始化一个不可变对象的二维数组:`dp = [ [0]*col for _ in range(row) ]`,不要用 `dp = [[0] * n] * m`, 否则里边都 +引用的同一个 list,修改一个都会变。`[[0 for _ in range(col)] for _ in range(row)]` 也可以(稍慢),因为数字 0 是不可变对象 - python在数值范围建议用:`MAXINT = 2**63-1; MININT = -2**63` 。因为 python2 sys.maxint 和 python3 sys.maxsize 不统一 - 优先级队列:使用内置queue.PriorityQueue or heapq ,定义一个 Item 类实现"小于" 魔术方法就可以实现,下边有代码演示 - python3 的 functools 模块自带了 cache(等价于lru_cache(maxsize=None)) 和 lru_cache 装饰器,在一些需要递归记忆化搜索的时候会很方便 From b4f3451c1aae02a63568de909409d5f75034198c Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Thu, 10 Mar 2022 09:16:51 +0800 Subject: [PATCH 30/50] python list append list use copy --- .../builtins.md" | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index a4e5e33..191de2c 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -28,12 +28,14 @@ 如果你使用 python2 or python3 刷题(比如力扣leetcode),有一些坑或者技巧需要注意: -- python3 和 python2 的 dict 有所用不同,python3.7 之后的 dict 会保持插入顺序(不是字典序), python2 不要依赖 dict 迭代顺序,请使用 OrderedDict -- 正确初始化一个不可变对象的二维数组:`dp = [ [0]*col for _ in range(row) ]`,不要用 `dp = [[0] * n] * m`, 否则里边都 +- 字典顺序。python3 和 python2 的 dict 有所用不同,python3.7 之后的 dict 会保持插入顺序(不是字典序), python2 不要依赖 dict 迭代顺序,请使用 OrderedDict +- 矩阵。正确初始化一个不可变对象的二维数组:`dp = [ [0]*col for _ in range(row) ]`,不要用 `dp = [[0] * n] * m`, 否则里边都 引用的同一个 list,修改一个都会变。`[[0 for _ in range(col)] for _ in range(row)]` 也可以(稍慢),因为数字 0 是不可变对象 -- python在数值范围建议用:`MAXINT = 2**63-1; MININT = -2**63` 。因为 python2 sys.maxint 和 python3 sys.maxsize 不统一 +- 深浅拷贝。经常在回溯题中需要`res,path=[],[]`,path 是用来回溯的路径。找到一个结果的时候需要用 `res.append(path[:])` 而 +不是`res.append(path)#错!` ,因为这里append的path的引用,之后修改了 path 结果就是错的!(或者用copy模块,不过不如[:]语法简洁) +- int范围。python在数值范围建议用:`MAXINT = 2**63-1; MININT = -2**63` 。因为 python2 sys.maxint 和 python3 sys.maxsize 不统一 - 优先级队列:使用内置queue.PriorityQueue or heapq ,定义一个 Item 类实现"小于" 魔术方法就可以实现,下边有代码演示 -- python3 的 functools 模块自带了 cache(等价于lru_cache(maxsize=None)) 和 lru_cache 装饰器,在一些需要递归记忆化搜索的时候会很方便 +- 缓存。python3 的 functools 模块自带了 cache(等价于lru_cache(maxsize=None)) 和 lru_cache 装饰器,在一些需要递归记忆化搜索的时候会很方便 - 除法变更:python2和 python3 除法做了变更要注意。还有负数除法。 python2 `int(6/-123)==-1, int(-3/2)==-2`,但是 python3 `int(6/-123)==0, int(-3/2)==-1`。 正数的整数除法统一用"//"。比如二分求中间值 `mid=(l+r)//2` 或者 `mid=l+(r-l)//2`,因为python天生支持大数不会溢出两种写法都行。负数整数除法统一写 int(a/b)。 凡是遇到除法运算的题目建议统一使用 python3 提交。 From b2c3b3a164d840c402e699a0a21e571bc801dd83 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Thu, 10 Mar 2022 17:12:07 +0800 Subject: [PATCH 31/50] max dict value --- .../builtins.md" | 7 +++++++ 1 file changed, 7 insertions(+) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index 191de2c..ac7720d 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -83,6 +83,13 @@ sorted(l, key=lambda p:p[1]) # 根据第2个值排序,[('a', 1), ('c', 2), ('b # 同时获取最大值的下标和值 l = [1,2,5,4,3] maxi, maxval = max(enumerate(l), key=lambda iv: iv[1]) # 2, 5 + +# 获取字典对应的最大值对应的 key,value +mydict = {'A':4,'B':10,'C':0,'D':87} +maximum = max(mydict, key=mydict.get) # Just use 'min' instead of 'max' for minimum. +maxk, maxv = maximum, mydict[maximum] +# 或者 +maxk, maxv = max(mydict.items(), key=lambda k: k[1]) ``` # 链表题目调试函数 From f0a961b1bd552cf4021857b928662bfbf01c3648 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Wed, 16 Mar 2022 12:18:22 +0800 Subject: [PATCH 32/50] python3 sort list --- .../builtins.md" | 6 ++++++ 1 file changed, 6 insertions(+) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index ac7720d..20b7981 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -90,6 +90,12 @@ maximum = max(mydict, key=mydict.get) # Just use 'min' instead of 'max' for min maxk, maxv = maximum, mydict[maximum] # 或者 maxk, maxv = max(mydict.items(), key=lambda k: k[1]) + +# python3 排序list自定义函数(python2 直接用 cmp 参数) +from functools import cmp_to_key +nums = [3,2,1,4,5] +sorted(nums, key= cmp_to_key(lambda a,b: a-b) ) # [1 ,2 ,3, 4, 5] +sorted(nums, key= cmp_to_key(lambda a,b: b-a) ) # [5, 4, 3, 2, 1] ``` # 链表题目调试函数 From d051a652fb6fed55d673d54e7aa5076528ecd202 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Mon, 28 Mar 2022 10:21:33 +0800 Subject: [PATCH 33/50] python oneline issorted --- .../builtins.md" | 3 +++ 1 file changed, 3 insertions(+) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index 20b7981..1b0721e 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -96,6 +96,9 @@ from functools import cmp_to_key nums = [3,2,1,4,5] sorted(nums, key= cmp_to_key(lambda a,b: a-b) ) # [1 ,2 ,3, 4, 5] sorted(nums, key= cmp_to_key(lambda a,b: b-a) ) # [5, 4, 3, 2, 1] + +# 一行代码判断列表是否有序 +issorted = all(l[i] <= l[i+1] for i in range(len(l) - 1)) ``` # 链表题目调试函数 From 3db87a7b231e4a298f2a884b1c0f9402f1a4bd55 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Sun, 3 Apr 2022 17:58:02 +0800 Subject: [PATCH 34/50] implement lru --- .../03_\351\223\276\350\241\250/lru_cache.py" | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git "a/docs/03_\351\223\276\350\241\250/lru_cache.py" "b/docs/03_\351\223\276\350\241\250/lru_cache.py" index 426a309..0612a66 100644 --- "a/docs/03_\351\223\276\350\241\250/lru_cache.py" +++ "b/docs/03_\351\223\276\350\241\250/lru_cache.py" @@ -132,3 +132,83 @@ def test(): if __name__ == '__main__': test() + + +######################################### 使用双链表实现 LRUcache #################################################### +""" +一般面试中不会让我们直接用内置结构,所以这里提供一个自己实现的双链表+map lru 缓存。这也是力扣上的一道真题: +[146] LRU 缓存 https://leetcode-cn.com/problems/lru-cache/description/ +""" + +class ListNode: + def __init__(self, key=None, value=None): + self.key = key + self.value = value + self.prev = self.next = None + + +class List: + def __init__(self): + """循环双链表。注意增加了虚拟头尾结点 head,tail 方便处理""" + self.head = ListNode() + self.tail = ListNode() + self.head.prev = self.head.next = self.tail + self.tail.next = self.tail.prev = self.head + + def delete_node(self, node): # 删除指定节点 + node.prev.next = node.next + node.next.prev = node.prev + + def add_to_head(self, node): # 指定节点添加到 self.head 后 + nextnode = self.head.next + node.next = nextnode + node.prev = self.head + self.head.next = node + nextnode.prev = node + + +class LRUCache(object): + + def __init__(self, capacity): + """ + 思路:循环双链表 + 字典 + :type capacity: int + """ + self.map = dict() + self.ll = List() + self.capacity = capacity + + def get(self, key): + """ + :type key: int + :rtype: int + """ + if key not in self.map: + return -1 + + node = self.map[key] + self.ll.delete_node(node) + self.ll.add_to_head(node) + return node.value + + def put(self, key, value): + """ + :type key: int + :type value: int + :rtype: None + """ + if key in self.map: + node = self.map[key] + node.value = value # 修改结构体会也会修改 map 对应 value 的引用 + self.ll.delete_node(node) + self.ll.add_to_head(node) + else: + if len(self.map) >= self.capacity: # 直接用 len(self.map) ,不需要self.size 字段了 + tailnode = self.ll.tail.prev + self.ll.delete_node(tailnode) + del self.map[tailnode.key] + + node = ListNode(key, value) + self.map[key] = node + self.ll.add_to_head(node) + From cd148768b986796ca1113e594f11e22bf8aea4c8 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Fri, 8 Apr 2022 00:25:05 +0800 Subject: [PATCH 35/50] lru_cache decorator param maxsize --- .../builtins.md" | 1 + 1 file changed, 1 insertion(+) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index 1b0721e..cceed33 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -266,6 +266,7 @@ def maxheapval(h): # lru_cache/cache 优化记忆化搜索 python3 functools 模块的 cache 功能和 lru_cache(maxsize=None) 一样,不过更加轻量更快。在记忆化递归搜索的时候很方便。 +注意这里的参数 `maxsize=None` 一定要设置为 None,否则默认的 maxsize=128。 举一个力扣上的例子,如果不加 cache 递归函数因为会大量重复计算直接超时,但是加一个装饰器就可以通过。 ```py From 8152713f580e7c1435000fc614dba21227e6075c Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Fri, 8 Apr 2022 00:27:13 +0800 Subject: [PATCH 36/50] python dict implement cache --- .../builtins.md" | 1 + 1 file changed, 1 insertion(+) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index cceed33..f73330a 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -268,6 +268,7 @@ def maxheapval(h): python3 functools 模块的 cache 功能和 lru_cache(maxsize=None) 一样,不过更加轻量更快。在记忆化递归搜索的时候很方便。 注意这里的参数 `maxsize=None` 一定要设置为 None,否则默认的 maxsize=128。 举一个力扣上的例子,如果不加 cache 递归函数因为会大量重复计算直接超时,但是加一个装饰器就可以通过。 +当然了如果你用 python2 没有这个装饰器,你可以直接用 python 的 dict 来实现。(存在就返回,否则计算结果保存到 dict 里) ```py """ From 67b9f6bd34100faa5419f54cdc587d5944bd0967 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Fri, 8 Apr 2022 09:57:39 +0800 Subject: [PATCH 37/50] add oj site --- .../interview.md" | 6 ++++++ 1 file changed, 6 insertions(+) diff --git "a/docs/20_\351\235\242\350\257\225\346\214\207\345\215\227/interview.md" "b/docs/20_\351\235\242\350\257\225\346\214\207\345\215\227/interview.md" index 5958458..57d2492 100644 --- "a/docs/20_\351\235\242\350\257\225\346\214\207\345\215\227/interview.md" +++ "b/docs/20_\351\235\242\350\257\225\346\214\207\345\215\227/interview.md" @@ -41,3 +41,9 @@ leetcode 上的基础题目练练手感。 - [《程序员面试金典(第5版)》](https://book.douban.com/subject/25753386/) - [《剑指Offer》](https://book.douban.com/subject/25910559/) - [python leetCode](https://github.com/HuberTRoy/leetCodek) + +# 刷题网站 +leetcode 和牛客网是国内常用的两个刷题网站,笔者建议刷一下高频的 200 道题左右,基本可以应付大部分公司的算法面试了。 + +- https://leetcode-cn.com/ +- https://www.nowcoder.com/exam/oj From cde0457b62e7eab6ff4e9c2345d6bf7fb74031a8 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Sat, 9 Apr 2022 12:10:08 +0800 Subject: [PATCH 38/50] add min heap --- .../min_heap.py" | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 "docs/15_\345\240\206\344\270\216\345\240\206\346\216\222\345\272\217/min_heap.py" diff --git "a/docs/15_\345\240\206\344\270\216\345\240\206\346\216\222\345\272\217/min_heap.py" "b/docs/15_\345\240\206\344\270\216\345\240\206\346\216\222\345\272\217/min_heap.py" new file mode 100644 index 0000000..b424331 --- /dev/null +++ "b/docs/15_\345\240\206\344\270\216\345\240\206\346\216\222\345\272\217/min_heap.py" @@ -0,0 +1,66 @@ +# python3 +class MinHeap: + def __init__(self): + """ + 这里提供一个最小堆实现。如果面试不让用内置的堆非让你自己实现的话,考虑用这个简版的最小堆实现。 + 一般只需要实现 heqppop,heappush 两个操作就可以应付面试题了 + parent: (i-1)//2。注意这么写 int((n-1)/2), python3 (n-1)//2当n=0结果是-1而不是0 + left: 2*i+1 + right: 2*i+2 + 参考: + https://favtutor.com/blogs/heap-in-python + https://runestone.academy/ns/books/published/pythonds/Trees/BinaryHeapImplementation.html + https://www.askpython.com/python/examples/min-heap + """ + self.pq = [] + + def min_heapify(self, nums, k): + """递归调用,维持最小堆特性""" + l = 2*k+1 # 左节点位置 + r = 2*k+2 # 右节点 + if l < len(nums) and nums[l] < nums[k]: + smallest = l + else: + smallest = k + if r < len(nums) and nums[r] < nums[smallest]: + smallest = r + if smallest != k: + nums[k], nums[smallest] = nums[smallest], nums[k] + self.min_heapify(nums, smallest) + + def heappush(self, num): + """列表最后就加入一个元素,之后不断循环调用维持堆特性""" + self.pq.append(num) + n = len(self.pq) - 1 + # 注意必须加上n>0。因为 python3 (n-1)//2 当n==0 的时候结果是-1而不是0! + while n > 0 and self.pq[n] < self.pq[(n-1)//2]: # parent 交换 + self.pq[n], self.pq[(n-1)//2] = self.pq[(n-1)//2], self.pq[n] # swap + n = (n-1)//2 + + def heqppop(self): # 取 pq[0],之后和pq最后一个元素pq[-1]交换之后调用 min_heapify(0) + minval = self.pq[0] + last = self.pq[-1] + self.pq[0] = last + self.min_heapify(self.pq, 0) + self.pq.pop() + return minval + + def heapify(self, nums): + n = int((len(nums)//2)-1) + for k in range(n, -1, -1): + self.min_heapify(nums, k) + + +def test_MinHeqp(): + import random + l = list(range(1, 9)) + random.shuffle(l) + pq = MinHeap() + for num in l: + pq.heappush(num) + res = [] + for _ in range(len(l)): + res.append(pq.heqppop()) # 利用 heqppop,heqppush 实现堆排序 + + def issorted(l): return all(l[i] <= l[i+1] for i in range(len(l) - 1)) + assert issorted(res) From 7af4629e1fda7e0d381b4dafd7ceddc234cbb0b7 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Thu, 14 Apr 2022 13:28:15 +0800 Subject: [PATCH 39/50] python3 accumulate --- .../builtins.md" | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index f73330a..0727bd0 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -62,7 +62,7 @@ MAXINT = (1<<63) - 1 MININT = ~MAXINT ``` -# python list/dict 排序技巧 +# python list/dict 排序等技巧 ```py # python 根据 key,value 排序字典 @@ -99,6 +99,10 @@ sorted(nums, key= cmp_to_key(lambda a,b: b-a) ) # [5, 4, 3, 2, 1] # 一行代码判断列表是否有序 issorted = all(l[i] <= l[i+1] for i in range(len(l) - 1)) + +# python3 一行代码求前缀和 +from itertools import accumulate +presums = list(accumulate([1,2,3])) # [1, 3, 6] ``` # 链表题目调试函数 From 5d63cf3332328a0e5fe06eb38e8b01d01006216a Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Tue, 26 Apr 2022 09:31:07 +0800 Subject: [PATCH 40/50] =?UTF-8?q?python=20sys.setrecursionlimit=20?= =?UTF-8?q?=E9=98=B2=E6=AD=A2=E6=A0=88=E6=BA=A2=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../builtins.md" | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index 0727bd0..4d00568 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -42,6 +42,25 @@ - 自定义排序函数。python2 可以用 `nums.sort(cmp=lambda a, b: a - b)`,但是python3移除了cmp参数。 python3如果想要用自定义排序函数可以使用 functools.cmp_to_key 函数改成 `nums.sort(key=cmp_to_key(lambda a, b: a - b))` +# python 递归暴栈(栈溢出) + +python 递归函数默认递归深度比较小,你可以通过 `sys.getrecursionlimit()` 函数打印出来。 +我在 mac 机器上测试的时候,以下结果 python2 输出 1000。这就导致一些递归函数测试用例稍微多一些就会报错。 +(一个用例超过上千个数据就会报错了) + +```py +import sys +print(sys.getrecursionlimit()) # 我的 mac 机器上输出 1000 +``` + +可以把以下代码设置最大栈深度,放到文件开头,在牛客上提交代码的时候可以避免一些递归代码报错。 +(leetcode 似乎给设置了,类似的题目发现力扣上提交不会栈溢出但是在牛客就会) + +```py +import sys +sys.setrecursionlimit(100000) # 设置函数栈深度足够大,避免栈溢出错误 +``` + # python int 值范围 ``` From 5c765440b73d04a70b401e1aa22253432d883d15 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Wed, 27 Apr 2022 12:34:35 +0800 Subject: [PATCH 41/50] pytyhon matrix sum --- .../builtins.md" | 3 +++ 1 file changed, 3 insertions(+) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index 4d00568..5c1acf4 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -122,6 +122,9 @@ issorted = all(l[i] <= l[i+1] for i in range(len(l) - 1)) # python3 一行代码求前缀和 from itertools import accumulate presums = list(accumulate([1,2,3])) # [1, 3, 6] + +# 一行代码求矩阵和 https://stackoverflow.com/questions/10713150/how-to-sum-a-2d-array-in-python +allsum = sum(map(sum, matrix)) # 或者 allsum = sum((sum(row) for row in matrix)) ``` # 链表题目调试函数 From d6d0c41cadc777f509ff5ef1de885a86c9449b58 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Wed, 27 Apr 2022 16:28:55 +0800 Subject: [PATCH 42/50] =?UTF-8?q?python=20=E8=B4=9F=E6=95=B0=E4=BD=8D?= =?UTF-8?q?=E8=BF=90=E7=AE=97=E7=9A=84=E5=9D=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../builtins.md" | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index 5c1acf4..659404f 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -64,7 +64,7 @@ sys.setrecursionlimit(100000) # 设置函数栈深度足够大,避免栈溢出 # python int 值范围 ``` -# 乘方 (比较推荐,py2/3 都兼容不容易出错) +# 乘方 (比较推荐⭐️,py2/3 都兼容不容易出错) MAXINT = 2**63-1 MININT = -2**63 @@ -81,6 +81,23 @@ MAXINT = (1<<63) - 1 MININT = ~MAXINT ``` +# python 负数位运算的坑 +1. Python3 中的整型是补码形式存储的 +2. Python3 中 bin 一个负数(十进制表示),输出的是它的原码的二进制表示加上个负号 +3. 为了获得负数(十进制表示)的补码,需要手动将其和十六进制数 0xffffffff 进行按位与操作,得到结果是个十六进制数,再交给 bin() 进行输出, +得到的才是你想要的补码表示。 + +```py +# 整数转换 https://leetcode-cn.com/problems/convert-integer-lcci/ +class Solution: + def convertInteger(self, A: int, B: int) -> int: + return bin((A & 0xffffffff) ^ (B & 0xffffffff)).count('1') +``` + +参考: +- https://www.runoob.com/w3cnote/python-negative-storage.html +- https://leetcode-cn.com/problems/convert-integer-lcci/solution/python3-zhu-yi-qi-dui-yu-fu-shu-de-cun-chu-fang-sh/ + # python list/dict 排序等技巧 ```py @@ -452,7 +469,7 @@ def gen_tree(vals): return root ``` -# python 交换列表元素的坑 +# python 交换列表元素的坑(交换副作用) ``` # 41. 缺失的第一个正数 https://leetcode-cn.com/problems/first-missing-positive/ @@ -474,7 +491,7 @@ class Solution(object): while 1 <= nums[i] <= n and nums[nums[i]-1] != nums[i]: # NOTE: 注意这一句交换右边有副作用的,不能颠倒!!! # nums[i], nums[nums[i]-1] = nums[nums[i]-1], nums[i] # 这么写死循环! - nums[nums[i]-1], nums[i] = nums[i], nums[nums[i]-1] + nums[nums[i]-1], nums[i] = nums[i], nums[nums[i]-1] # 有副作用的放前边 for i in range(n): if nums[i] != i+1: return i+1 From 9e4c22401bea275b8fa68d74a1862f08f2b0067e Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Wed, 27 Apr 2022 17:22:49 +0800 Subject: [PATCH 43/50] leetcode 260 --- ...1\347\232\204\346\225\260\345\255\227).py" | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git "a/\345\211\221\346\214\207offer/40_NumbersAppearOnce(\346\225\260\347\273\204\344\270\255\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\346\225\260\345\255\227).py" "b/\345\211\221\346\214\207offer/40_NumbersAppearOnce(\346\225\260\347\273\204\344\270\255\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\346\225\260\345\255\227).py" index 30ada80..fa6f8fc 100644 --- "a/\345\211\221\346\214\207offer/40_NumbersAppearOnce(\346\225\260\347\273\204\344\270\255\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\346\225\260\345\255\227).py" +++ "b/\345\211\221\346\214\207offer/40_NumbersAppearOnce(\346\225\260\347\273\204\344\270\255\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\346\225\260\345\255\227).py" @@ -31,6 +31,7 @@ class Solution1: def singleNumber(self, nums): """ + 类似题:求只出现一次的数字,其他都出现两次。 :type nums: List[int] :rtype: int """ @@ -58,12 +59,45 @@ def get_single_num(nums): while single & mask == 0: mask = mask << 1 - print(mask,'||||||||||||||||||') + print(mask, '||||||||||||||||||') left = [i for i in nums if i & mask] right = [i for i in nums if not(i & mask)] return [get_single_num(left), get_single_num(right)] +class Solution(object): + def singleNumber(self, nums): + """ + 思路:异或。 + + 136 题做过只出现一次的一个数字,本题有两个只出现一次的数字。 + 核心在于把数组分成两个。怎么分组呢? + + 假设只出现一次的数字式 x1,x2,所有元素异或结果是 x。一定有 x=x1^x2。 + x不能是0,否则x1==x2,就不是只出现一次的数字了。 + *可以用位运算 x&-x 取出x 二进制位最低位的 1,设其实是第 L 位置。* + 可以据此分类数组,一组是二进制第 L位置为 0 的数字,一组L 位置为 1的数字。 + x1,x2会分别出现在两个组中。这样第一组全部异或得到x1, 第二组全部异或得到 x2 + + :type nums: List[int] + :rtype: List[int] + """ + x = 0 + for num in nums: + x ^= num + + low1pos = x & -x # 这里也可以用移位运算,x&-x 不太好想,类似上边那个解法 + x1, x2 = 0, 0 + + for num in nums: + if num & low1pos: + x1 ^= num + else: + x2 ^= num + + return x1, x2 + + def test(): s = Solution() assert s.singleNumber([1, 2, 1, 3, 2, 5]) == [3, 5] From 433680bbe517c028fb87c7c0ab6b9a0f62c72ab3 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Thu, 28 Apr 2022 13:27:24 +0800 Subject: [PATCH 44/50] visualization website --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 6e9ab30..0d2a994 100644 --- a/README.md +++ b/README.md @@ -121,9 +121,12 @@ Python 抽象程度比较高, 我们能用更少的代码来实现功能,同 ## 算法可视化 学习算法的过程中有时候会比较抽象,这里给大家推荐一些可视化的网站,方便更直观地理解各种算法和数据结构的执行步骤: +遇到一个算法或数据结构,你可以 google 搜索 "名称+ visualization" 找到一些可视化网站方便理解,比如学习跳跃表的时候笔者就 +可以通过 goole "skip list visualization" 搜到一些可视化网站帮助你理解它的工作原理。 - https://github.com/algorithm-visualizer/algorithm-visualizer - https://www.cs.usfca.edu/~galles/visualization/Algorithms.html +- https://cmps-people.ok.ubc.ca/ylucet/DS/Algorithms.html - https://runestone.academy/runestone/books/published/pythonds/index.html# ## 讲课形式 From 8fc6d7d04e611cb1b8eb0f30f540812a2ec1560b Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Thu, 28 Apr 2022 18:22:34 +0800 Subject: [PATCH 45/50] python list and dict skills --- .../builtins.md" | 53 +++++++++++-------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index 659404f..cb57671 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -98,19 +98,9 @@ class Solution: - https://www.runoob.com/w3cnote/python-negative-storage.html - https://leetcode-cn.com/problems/convert-integer-lcci/solution/python3-zhu-yi-qi-dui-yu-fu-shu-de-cun-chu-fang-sh/ -# python list/dict 排序等技巧 +# python list 技巧 ```py -# python 根据 key,value 排序字典 -d = {'d': 4, 'a': 1, 'b': 2, 'c':3} -# dict sort by key and reverse -dict(sorted(d.items())) # {'a': 1, 'b': 2, 'c': 3, 'd': 4} -dict(sorted(d.items(), reverse=True)) # {'d': 4, 'c': 3, 'b': 2, 'a': 1} - -# dict sort by value and reverse -dict(sorted(d.items(), key = lambda kv:kv[1])) # {'a': 1, 'b': 2, 'c': 3, 'd': 4} -dict(sorted(d.items(), key = lambda kv:kv[1], reverse=True)) # {'d': 4, 'c': 3, 'b': 2, 'a': 1} - # 排序嵌套 list l = [('a', 1), ('c', 2), ('b',3)] sorted(l, key=lambda p:p[0]) # 根据第1个值排序,[('a', 1), ('b', 3), ('c', 2)] @@ -120,18 +110,11 @@ sorted(l, key=lambda p:p[1]) # 根据第2个值排序,[('a', 1), ('c', 2), ('b l = [1,2,5,4,3] maxi, maxval = max(enumerate(l), key=lambda iv: iv[1]) # 2, 5 -# 获取字典对应的最大值对应的 key,value -mydict = {'A':4,'B':10,'C':0,'D':87} -maximum = max(mydict, key=mydict.get) # Just use 'min' instead of 'max' for minimum. -maxk, maxv = maximum, mydict[maximum] -# 或者 -maxk, maxv = max(mydict.items(), key=lambda k: k[1]) - -# python3 排序list自定义函数(python2 直接用 cmp 参数) +# python3 排序list自定义函数(python2 直接用 cmp 参数, python3 需要用 cmp_to_key 转成 key 参数) from functools import cmp_to_key nums = [3,2,1,4,5] -sorted(nums, key= cmp_to_key(lambda a,b: a-b) ) # [1 ,2 ,3, 4, 5] -sorted(nums, key= cmp_to_key(lambda a,b: b-a) ) # [5, 4, 3, 2, 1] +sorted(nums, key=cmp_to_key(lambda a,b: a-b) ) # [1 ,2 ,3, 4, 5] +sorted(nums, key=cmp_to_key(lambda a,b: b-a) ) # [5, 4, 3, 2, 1] # 一行代码判断列表是否有序 issorted = all(l[i] <= l[i+1] for i in range(len(l) - 1)) @@ -140,10 +123,36 @@ issorted = all(l[i] <= l[i+1] for i in range(len(l) - 1)) from itertools import accumulate presums = list(accumulate([1,2,3])) # [1, 3, 6] -# 一行代码求矩阵和 https://stackoverflow.com/questions/10713150/how-to-sum-a-2d-array-in-python +# 一行代码求矩阵元素总和 https://stackoverflow.com/questions/10713150/how-to-sum-a-2d-array-in-python allsum = sum(map(sum, matrix)) # 或者 allsum = sum((sum(row) for row in matrix)) ``` +# python dict 技巧 + +```py +# python 根据 key,value 排序字典 +d = {'d': 4, 'a': 1, 'b': 2, 'c':3} +# dict sort by **key** and reverse +dict(sorted(d.items())) # {'a': 1, 'b': 2, 'c': 3, 'd': 4} +dict(sorted(d.items(), reverse=True)) # {'d': 4, 'c': 3, 'b': 2, 'a': 1} + +# dict sort by **value** and reverse +dict(sorted(d.items(), key = lambda kv:kv[1])) # {'a': 1, 'b': 2, 'c': 3, 'd': 4} +dict(sorted(d.items(), key = lambda kv:kv[1], reverse=True)) # {'d': 4, 'c': 3, 'b': 2, 'a': 1} + +# 获取字典对应的最大值对应的 key,value +mydict = {'A':4,'B':10,'C':0,'D':87} +maximum = max(mydict, key=mydict.get) # Just use 'min' instead of 'max' for minimum. +maxk, maxv = maximum, mydict[maximum] +# 或者 +maxk, maxv = max(mydict.items(), key=lambda k: k[1]) + +# 支持默认值的有序字典 (OrderedDict and defaultdict) +# https://stackoverflow.com/questions/6190331/how-to-implement-an-ordered-default-dict +od = OrderedDict() # collections.OrderedDict() +od[i] = od.get(i, 0) + 1 # 间接实现了 defaultdict(int) ,同时保持了插入字典的 key 顺序 +``` + # 链表题目调试函数 ```py From 10074160050ae47a884eef7332a2fc2ea41a61ff Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Thu, 28 Apr 2022 18:25:04 +0800 Subject: [PATCH 46/50] =?UTF-8?q?OrderedDict=20=E6=8F=92=E5=85=A5=E9=A1=BA?= =?UTF-8?q?=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../builtins.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index cb57671..be78927 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -147,7 +147,7 @@ maxk, maxv = maximum, mydict[maximum] # 或者 maxk, maxv = max(mydict.items(), key=lambda k: k[1]) -# 支持默认值的有序字典 (OrderedDict and defaultdict) +# 支持默认值的有序字典 (OrderedDict and defaultdict) (注意是 key 插入顺序不是字典序) # https://stackoverflow.com/questions/6190331/how-to-implement-an-ordered-default-dict od = OrderedDict() # collections.OrderedDict() od[i] = od.get(i, 0) + 1 # 间接实现了 defaultdict(int) ,同时保持了插入字典的 key 顺序 From 9bf19c59a7cf95b0c683f9b16d671e92cc3fa5d7 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Thu, 5 May 2022 11:47:19 +0800 Subject: [PATCH 47/50] lru comment --- "docs/03_\351\223\276\350\241\250/lru_cache.py" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/docs/03_\351\223\276\350\241\250/lru_cache.py" "b/docs/03_\351\223\276\350\241\250/lru_cache.py" index 0612a66..e1683bb 100644 --- "a/docs/03_\351\223\276\350\241\250/lru_cache.py" +++ "b/docs/03_\351\223\276\350\241\250/lru_cache.py" @@ -197,7 +197,7 @@ def put(self, key, value): :type value: int :rtype: None """ - if key in self.map: + if key in self.map: # 更新不会改变元素个数,这里不用判断是否需要剔除 node = self.map[key] node.value = value # 修改结构体会也会修改 map 对应 value 的引用 self.ll.delete_node(node) From 4eb9fe797f8d9e38df30c9352819e7dec37b970a Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Sun, 15 May 2022 16:42:45 +0800 Subject: [PATCH 48/50] =?UTF-8?q?=E4=B8=80=E8=A1=8C=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E5=88=A4=E6=96=AD=E5=85=83=E7=B4=A0=E6=98=AF=E5=90=A6=E5=9C=A8?= =?UTF-8?q?=E7=9F=A9=E9=98=B5=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../builtins.md" | 2 ++ 1 file changed, 2 insertions(+) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index be78927..53c89dc 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -125,6 +125,8 @@ presums = list(accumulate([1,2,3])) # [1, 3, 6] # 一行代码求矩阵元素总和 https://stackoverflow.com/questions/10713150/how-to-sum-a-2d-array-in-python allsum = sum(map(sum, matrix)) # 或者 allsum = sum((sum(row) for row in matrix)) +# 一行代码判断一个元素是否在矩阵中,比如判断 1 是否在矩阵matrix中 +any(1 in row for row in matrix) ``` # python dict 技巧 From 2c8a81b284f78964ebb7a7e83abf920067928f33 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Fri, 3 Jun 2022 15:28:23 +0800 Subject: [PATCH 49/50] =?UTF-8?q?sort=20=E5=B5=8C=E5=A5=97=E6=8E=92?= =?UTF-8?q?=E5=BA=8F=E6=8A=80=E5=B7=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../builtins.md" | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index 53c89dc..d9f0aba 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -101,10 +101,11 @@ class Solution: # python list 技巧 ```py -# 排序嵌套 list +# 排序嵌套 list,比如元素值是一个 tuple 或者 list l = [('a', 1), ('c', 2), ('b',3)] sorted(l, key=lambda p:p[0]) # 根据第1个值排序,[('a', 1), ('b', 3), ('c', 2)] sorted(l, key=lambda p:p[1]) # 根据第2个值排序,[('a', 1), ('c', 2), ('b', 3)] +sorted(l, key=lambda p:(-p[0], p[1])) # 先根据第一个倒排,如果相等再根据第二个正排序 # 同时获取最大值的下标和值 l = [1,2,5,4,3] From 3469a79c34b6c08ae52797c3974b49fbfa8cca51 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Mon, 13 Jun 2022 09:53:41 +0800 Subject: [PATCH 50/50] one line get max matrix val --- .../builtins.md" | 2 ++ 1 file changed, 2 insertions(+) diff --git "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" index d9f0aba..a38b5ef 100644 --- "a/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" +++ "b/docs/19_python\345\206\205\347\275\256\345\270\270\347\224\250\347\256\227\346\263\225\345\222\214\346\225\260\346\215\256\347\273\223\346\236\204/builtins.md" @@ -128,6 +128,8 @@ presums = list(accumulate([1,2,3])) # [1, 3, 6] allsum = sum(map(sum, matrix)) # 或者 allsum = sum((sum(row) for row in matrix)) # 一行代码判断一个元素是否在矩阵中,比如判断 1 是否在矩阵matrix中 any(1 in row for row in matrix) +# 一行代码获取矩阵最大、最小值 +maxval = max(map(max, matrix)) ``` # python dict 技巧