From 52a10c0c6195c1bd55bfa86b488a329856b4ca7a Mon Sep 17 00:00:00 2001 From: Ti Gong Date: Sun, 7 Jul 2019 20:11:05 +0800 Subject: [PATCH 01/69] fix a bug in linked_list.py --- "docs/03_\351\223\276\350\241\250/linked_list.py" | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git "a/docs/03_\351\223\276\350\241\250/linked_list.py" "b/docs/03_\351\223\276\350\241\250/linked_list.py" index cb5608b..bf46571 100644 --- "a/docs/03_\351\223\276\350\241\250/linked_list.py" +++ "b/docs/03_\351\223\276\350\241\250/linked_list.py" @@ -77,7 +77,10 @@ def remove(self, value): # O(n) if curnode.value == value: prevnode.next = curnode.next if curnode is self.tailnode: # NOTE: 注意更新 tailnode - self.tailnode = prevnode + if prevnode is self.root: + self.tailnode = None + else: + self.tailnode = prevnode del curnode self.length -= 1 return 1 # 表明删除成功 From 22d0fe63d9f537feb3227362ca5042708d8efaa2 Mon Sep 17 00:00:00 2001 From: PeasusWang <291374108@qq.com> Date: Tue, 20 Aug 2019 10:52:49 +0800 Subject: [PATCH 02/69] update book link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c4ff77f..31a7173 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ [csdn 学院:Python数据结构与算法教程](https://edu.csdn.net/course/detail/8332) -[网上阅读《Python 算法与数据结构教程 》](http://ningning.today/python_data_structures_and_algorithms/) +[网上阅读《Python 算法与数据结构教程 》](http://pegasuswang.github.io/python_data_structures_and_algorithms/) [github 链接](https://github.com/PegasusWang/python_data_structures_and_algorithms) From a75f55779fe5561a2152bef9caae4d3441d5b4f6 Mon Sep 17 00:00:00 2001 From: PeasusWang <291374108@qq.com> Date: Tue, 8 Oct 2019 18:03:08 +0800 Subject: [PATCH 03/69] fix lru_cache function error --- "docs/03_\351\223\276\350\241\250/lru_cache.py" | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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 7e77a03..426a309 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" @@ -62,8 +62,9 @@ def f(n): 只需要让 root 的前一个指向这个被删除节点,然后让之前的最后一个节点也指向它就行了。 使用了循环双端链表之后,我们的操作就都是 O(1) 的了。这也就是使用一个 dict 和一个 循环双端链表 实现LRU 的思路。 -不过一般我们使用内置的 OrderedDict(原理和这个类似)就好了,要实现一个循环双端链表是一个不简单的事情。 +不过一般我们使用内置的 OrderedDict(原理和这个类似)就好了,要实现一个循环双端链表是一个不简单的事情,因为链表操作很容易出错。 +补充:其实 lru 有个缺点就是额外的链表比较占用空间,如果你感兴趣的话可以看看 redis 如何实现的 lru 算法 """ @@ -112,7 +113,7 @@ def _(n): def f_use_lru(n): if n <= 1: # 0 or 1 return n - return f(n - 1) + f(n - 2) + return f_use_lru(n - 1) + f_use_lru(n - 2) def test(): From d20f9126a48e705b447f000fa33f275f2d259777 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Fri, 18 Oct 2019 19:08:48 +0800 Subject: [PATCH 04/69] Create LICENSE --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c4910bd --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 PegasusWang + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From dfffaf408bc9eab54457a327e7963b2011900059 Mon Sep 17 00:00:00 2001 From: PeasusWang <291374108@qq.com> Date: Sat, 19 Oct 2019 11:30:07 +0800 Subject: [PATCH 05/69] update gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index e70d4d9..43c172d 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ # python __pycache__/ *.py[cod] +*.pyc *$py.class .python-version @@ -30,4 +31,4 @@ site/ .vscode/ # pytest -.pytest_cache/ \ No newline at end of file +.pytest_cache/ From 3a2f4d838cdc18b849bf75f17f1719e62d4381e8 Mon Sep 17 00:00:00 2001 From: PeasusWang <291374108@qq.com> Date: Sun, 20 Oct 2019 11:09:08 +0800 Subject: [PATCH 06/69] =?UTF-8?q?hashtable=20=E4=BB=A3=E7=A0=81=E6=B3=A8?= =?UTF-8?q?=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "docs/07_\345\223\210\345\270\214\350\241\250/hashtable.md" | 1 + "docs/07_\345\223\210\345\270\214\350\241\250/hashtable.py" | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git "a/docs/07_\345\223\210\345\270\214\350\241\250/hashtable.md" "b/docs/07_\345\223\210\345\270\214\350\241\250/hashtable.md" index 50a0ae7..efccb63 100644 --- "a/docs/07_\345\223\210\345\270\214\350\241\250/hashtable.md" +++ "b/docs/07_\345\223\210\345\270\214\350\241\250/hashtable.md" @@ -178,3 +178,4 @@ class HashTable(object): - 《Data Structures and Algorithms in Python》11 章 Hash Tables - 《算法导论》第三版 11 章散列表,了解几种哈希冲突的解决方式,以及为什么我们选择二次探查而不是线性探查法? - 介绍 c 解释器如何实现的 python dict对象:[Python dictionary implementation](http://www.laurentluce.com/posts/python-dictionary-implementation/) +- [Python hash function implement](https://stackoverflow.com/questions/2070276/where-can-i-find-source-or-algorithm-of-pythons-hash-function) diff --git "a/docs/07_\345\223\210\345\270\214\350\241\250/hashtable.py" "b/docs/07_\345\223\210\345\270\214\350\241\250/hashtable.py" index 2904b06..d90721a 100644 --- "a/docs/07_\345\223\210\345\270\214\350\241\250/hashtable.py" +++ "b/docs/07_\345\223\210\345\270\214\350\241\250/hashtable.py" @@ -31,7 +31,7 @@ class Slot(object): """定义一个 hash 表 数组的槽 注意,一个槽有三种状态,看你能否想明白。相比链接法解决冲突,二次探查法删除一个 key 的操作稍微复杂。 1.从未使用 HashMap.UNUSED。此槽没有被使用和冲突过,查找时只要找到 UNUSED 就不用再继续探查了 - 2.使用过但是 remove 了,此时是 HashMap.EMPTY,该探查点后边的元素扔可能是有key + 2.使用过但是 remove 了,此时是 HashMap.EMPTY,该探查点后边的元素仍然可能是有key的,需要继续查找 3.槽正在使用 Slot 节点 """ @@ -82,12 +82,12 @@ def _find_slot_for_insert(self, key): def _slot_can_insert(self, index): return (self._table[index] is HashTable.EMPTY or self._table[index] is HashTable.UNUSED) - def __contains__(self, key): # in operator + def __contains__(self, key): # in operator,实现之后可以使用 in 操作符判断 index = self._find_key(key) return index is not None def add(self, key, value): - if key in self: + if key in self: # update index = self._find_key(key) self._table[index].value = value return False From 517461cbd12490d00c1a39e5f2696ca13f6082fd Mon Sep 17 00:00:00 2001 From: PegasusWang Date: Sun, 20 Oct 2019 16:38:38 +0800 Subject: [PATCH 07/69] docs: differences hashtable slot EMPTY vs UNUSED --- .../hashtable.py" | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git "a/docs/07_\345\223\210\345\270\214\350\241\250/hashtable.py" "b/docs/07_\345\223\210\345\270\214\350\241\250/hashtable.py" index 2904b06..233aeda 100644 --- "a/docs/07_\345\223\210\345\270\214\350\241\250/hashtable.py" +++ "b/docs/07_\345\223\210\345\270\214\350\241\250/hashtable.py" @@ -28,7 +28,7 @@ def __iter__(self): class Slot(object): - """定义一个 hash 表 数组的槽 + """定义一个 hash 表数组的槽(slot 这里指的就是数组的一个位置) 注意,一个槽有三种状态,看你能否想明白。相比链接法解决冲突,二次探查法删除一个 key 的操作稍微复杂。 1.从未使用 HashMap.UNUSED。此槽没有被使用和冲突过,查找时只要找到 UNUSED 就不用再继续探查了 2.使用过但是 remove 了,此时是 HashMap.EMPTY,该探查点后边的元素扔可能是有key @@ -60,10 +60,15 @@ def _hash(self, key): return abs(hash(key)) % len(self._table) def _find_key(self, key): + """ + 解释一个 slot 为 UNUSED 和 EMPTY 的区别 + 因为使用的是二次探查的方式,假如有两个元素 A,B 冲突了,首先A hash 得到是 slot 下标5,A 放到了第5个槽,之后插入 B 因为冲突了,所以继续根据二次探查方式放到了 slot8。 + 然后删除 A,槽 5 被置为 EMPTY。然后我去查找 B,第一次 hash 得到的是 槽5,但是这个时候我还是需要第二次计算 hash 才能找到 B。但是如果槽是 UNUSED 我就不用继续找了,我认为 B 就是不存在的元素。这个就是 UNUSED 和 EMPTY 的区别。 + """ index = self._hash(key) _len = len(self._table) while self._table[index] is not HashTable.UNUSED: - if self._table[index] is HashTable.EMPTY: + if self._table[index] is HashTable.EMPTY: # 注意如果是 EMPTY,继续寻找下一个槽 index = (index*5 + 1) % _len continue elif self._table[index].key == key: @@ -75,7 +80,7 @@ def _find_key(self, key): def _find_slot_for_insert(self, key): index = self._hash(key) _len = len(self._table) - while not self._slot_can_insert(index): + while not self._slot_can_insert(index): # 直到找到一个可以用的槽 index = (index*5 + 1) % _len return index From 54b8b2f75b70ed57a2b8677697f4470a4225f516 Mon Sep 17 00:00:00 2001 From: PegasusWang Date: Sun, 20 Oct 2019 17:38:49 +0800 Subject: [PATCH 08/69] fix https://github.com/PegasusWang/python_data_structures_and_algorithms/issues/19 --- .../hashtable.py" | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git "a/docs/07_\345\223\210\345\270\214\350\241\250/hashtable.py" "b/docs/07_\345\223\210\345\270\214\350\241\250/hashtable.py" index ffbd6d4..312465c 100644 --- "a/docs/07_\345\223\210\345\270\214\350\241\250/hashtable.py" +++ "b/docs/07_\345\223\210\345\270\214\350\241\250/hashtable.py" @@ -29,7 +29,7 @@ def __iter__(self): class Slot(object): """定义一个 hash 表数组的槽(slot 这里指的就是数组的一个位置) - 注意,一个槽有三种状态,看你能否想明白。相比链接法解决冲突,二次探查法删除一个 key 的操作稍微复杂。 + 注意,一个槽有三种状态,看你能否想明白。相比链接法解决冲突,探查法删除一个 key 的操作稍微复杂。 1.从未使用 HashMap.UNUSED。此槽没有被使用和冲突过,查找时只要找到 UNUSED 就不用再继续探查了 2.使用过但是 remove 了,此时是 HashMap.EMPTY,该探查点后边的元素仍然可能是有key的,需要继续查找 3.槽正在使用 Slot 节点 @@ -65,23 +65,28 @@ def _find_key(self, key): 因为使用的是二次探查的方式,假如有两个元素 A,B 冲突了,首先A hash 得到是 slot 下标5,A 放到了第5个槽,之后插入 B 因为冲突了,所以继续根据二次探查方式放到了 slot8。 然后删除 A,槽 5 被置为 EMPTY。然后我去查找 B,第一次 hash 得到的是 槽5,但是这个时候我还是需要第二次计算 hash 才能找到 B。但是如果槽是 UNUSED 我就不用继续找了,我认为 B 就是不存在的元素。这个就是 UNUSED 和 EMPTY 的区别。 """ - index = self._hash(key) + origin_index = index = self._hash(key) # origin_index 判断是否又走到了起点,如果查找一圈了都找不到则无此元素 _len = len(self._table) while self._table[index] is not HashTable.UNUSED: if self._table[index] is HashTable.EMPTY: # 注意如果是 EMPTY,继续寻找下一个槽 - index = (index*5 + 1) % _len + index = (index * 5 + 1) % _len + if index == origin_index: + break continue - elif self._table[index].key == key: + if self._table[index].key == key: # 找到了key return index else: - index = (index*5 + 1) % _len + index = (index * 5 + 1) % _len # 没有找到继续找下一个位置 + if index == origin_index: + break + return None def _find_slot_for_insert(self, key): index = self._hash(key) _len = len(self._table) - while not self._slot_can_insert(index): # 直到找到一个可以用的槽 - index = (index*5 + 1) % _len + while not self._slot_can_insert(index): # 直到找到一个可以用的槽 + index = (index * 5 + 1) % _len return index def _slot_can_insert(self, index): From 552e7c14ecde4f8cb57390e7a52d1ede9200e1f4 Mon Sep 17 00:00:00 2001 From: PegasusWang Date: Sun, 20 Oct 2019 17:52:13 +0800 Subject: [PATCH 09/69] add linked list single node unittest --- "docs/03_\351\223\276\350\241\250/linked_list.py" | 7 +++++++ 1 file changed, 7 insertions(+) diff --git "a/docs/03_\351\223\276\350\241\250/linked_list.py" "b/docs/03_\351\223\276\350\241\250/linked_list.py" index bf46571..78abea5 100644 --- "a/docs/03_\351\223\276\350\241\250/linked_list.py" +++ "b/docs/03_\351\223\276\350\241\250/linked_list.py" @@ -188,6 +188,12 @@ def test_linked_list_remove(): ll.remove(7) print(list(ll)) +def test_single_node(): + ll = LinkedList() + ll.append(0) + ll.remove(0) + ll.appendleft(1) + assert list(ll) == [1] def test_linked_list_reverse(): ll = LinkedList() @@ -206,6 +212,7 @@ def test_linked_list_append(): if __name__ == '__main__': + test_single_node() test_linked_list() test_linked_list_append() test_linked_list_reverse() From 9b1c0ee3d0ebe9b47dad5163842655de18ab9ffc Mon Sep 17 00:00:00 2001 From: PegasusWang Date: Sun, 20 Oct 2019 17:53:15 +0800 Subject: [PATCH 10/69] doc: https://github.com/PegasusWang/python_data_structures_and_algorithms/pull/21 --- "docs/03_\351\223\276\350\241\250/linked_list.py" | 1 + 1 file changed, 1 insertion(+) diff --git "a/docs/03_\351\223\276\350\241\250/linked_list.py" "b/docs/03_\351\223\276\350\241\250/linked_list.py" index 78abea5..b64eb1c 100644 --- "a/docs/03_\351\223\276\350\241\250/linked_list.py" +++ "b/docs/03_\351\223\276\350\241\250/linked_list.py" @@ -189,6 +189,7 @@ def test_linked_list_remove(): print(list(ll)) def test_single_node(): + # https://github.com/PegasusWang/python_data_structures_and_algorithms/pull/21 ll = LinkedList() ll.append(0) ll.remove(0) From 7524e5b2d77b1c931eb0c3912f997949d49f10cf Mon Sep 17 00:00:00 2001 From: PegasusWang Date: Sun, 20 Oct 2019 18:02:02 +0800 Subject: [PATCH 11/69] update readme: please show failure case --- README.md | 2 +- "docs/07_\345\223\210\345\270\214\350\241\250/hashtable.py" | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 31a7173..9bfc6ce 100644 --- a/README.md +++ b/README.md @@ -301,9 +301,9 @@ def test(): 如果读者关于代码、视频、讲义有任何疑问,欢迎一起讨论 请注意以下几点: -- 优先在网易云课堂的讨论区提问,方便别的同学浏览。如果未购买视频,也可以直接在 github 里提出 issue,笔者有空会给大家解答和讨论。 - 描述尽量具体,视频或者代码哪一部分有问题?请尽量把涉及章节和代码贴出来,方便定位问题。 - 如果涉及到代码,提问时请保持代码的格式 +- 如果直接提了代码bug,最好有相关测试用例展示失败 test case,方便复现问题 ## 本电子书制作和写作方式 diff --git "a/docs/07_\345\223\210\345\270\214\350\241\250/hashtable.py" "b/docs/07_\345\223\210\345\270\214\350\241\250/hashtable.py" index 312465c..f1df5e2 100644 --- "a/docs/07_\345\223\210\345\270\214\350\241\250/hashtable.py" +++ "b/docs/07_\345\223\210\345\270\214\350\241\250/hashtable.py" @@ -29,6 +29,8 @@ def __iter__(self): class Slot(object): """定义一个 hash 表数组的槽(slot 这里指的就是数组的一个位置) + hash table 就是一个 数组,每个数组的元素(也叫slot槽)是一个对象,对象包含两个属性 key 和 value。 + 注意,一个槽有三种状态,看你能否想明白。相比链接法解决冲突,探查法删除一个 key 的操作稍微复杂。 1.从未使用 HashMap.UNUSED。此槽没有被使用和冲突过,查找时只要找到 UNUSED 就不用再继续探查了 2.使用过但是 remove 了,此时是 HashMap.EMPTY,该探查点后边的元素仍然可能是有key的,需要继续查找 From 0d099503264cecd5915303c2b17c099f639c3c79 Mon Sep 17 00:00:00 2001 From: PegasusWang Date: Sun, 20 Oct 2019 18:13:32 +0800 Subject: [PATCH 12/69] update 163 course image --- 163_course.png | Bin 0 -> 304699 bytes README.md | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 163_course.png diff --git a/163_course.png b/163_course.png new file mode 100644 index 0000000000000000000000000000000000000000..9fce0380e7db817f6641e91ef4a7ff3d9a164e78 GIT binary patch literal 304699 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 z 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

483cbuLf;Hwc%qVWaMr`>jkt- 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

AyrC1M`0#7Lg%O(yFNMt~ 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

si5W}i&j3y9CWrrZ?#*OI?w;1NT9H6#EwXl*?` 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

    ZqGDbpxq>F-hyT#`eu;l@TnWG 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

    gpy7J1TyyS?LGDq>)k>CC?Jw9m|pZueQP z_!LvCa==5J#C045(Umt9(eiB*f_K-2SEuQ9;FM|Ob7A2-HNAY2*vR{5Ac*cITjvQI zghl)~9Corf1VPkEsMc@($2}B_F@a$lmF0UH*l92V@e$@^Q56yDBWpgW)xU`ABsd#1 zouX7?;eRJ$U7&gE-`_DLw-<>WiDw64ek;*`)}?4*p!ZT{VedqvBlB2xf|cJg0`SXv zx;@x)>|1ulFynqD6*sWm?z|}Ppw9v4djK`-nlz)NvQpbCes#l>LjjgsPaR!O?_w7-Gb^J{in}%35dkRd=`v~IQl;*^0#$DjPzuG?S z^2ES$IeO*#tm^k02Tt4OsUkDey0SJlL7m1$g0oQSuSvs8_bq8vcP8( zi|o4Q)*ZdD6==a0I5IL>HC0~XVJe*t&gpe5@Byu_IGc!_1&^sN@2J25_j@-@kW60C z&ziC}DBqB!Ut8GQB4nxQ^|thzXg4?I(y)^X9vU}0*?P6TV(e!p($f=0(%X%(r=M!q zq@YZddgs4vsEk}+>ct8;)p59w=9|7931biU9z3l9j*UD%!-b!7|FR?HPi%iHzozt* zeSo!qJbW%hC+1^Nz;8LW_yDXdIzr~vG!l0MBG5Fa2;H#kH=C@s30b*frp9`B-N)^$ zsd)_=Du(@6Ubx-|4BSH)Eg)UCZOeILefgR>%ThE?RdbNGqrU&qw<*o8;DnCJ3}{M| zUzeeSgG9R!RUeC2HrLU`PC(9HOwD@@TXt<5n)-Q4fbZh2!L;bMF%P5d`p*y=Lqs-O&v&eU?{YCTekS<)#`r7^ z?WelpTnIyX=T{U_AWeOB4 zMl?5*99_GHq;q%Sshh7kUJy4Y|4*>IsujaFA?m30)}Te#1+PH*9f>(e%LWd$>{Z@ z1dm=Ab7yCYiqi`&E&b@_I5Q?{b~WB?Skb@H8gTb6GYPe2Ns{=Luhsl3!Q|CjyN?Ga z_BM37GaC6%gnso>Ue0PQs^4MUGOxR75br*0;mUPV2}R<fJcMZ7Mf~KkJZ@VnR;*qzeFl&ats~-LfMcO8 ze)6pCtkWlE{*No_U$!J6@JD=4zDiCG$Q0Ux>o#0gcyV_jF^7aFQ?miilx_ z|M4~aF$)tJ91hUZwRQT|QU8REl?vAh*NjhdV^YSMFmFzjlk)!s{ns1(e!jecVtC-6 z^}?V{f(-Bov~(+CPJNk$@xuQbHsVd6U!mwS!rwrQJCm|W&k9n`r1bhAw=|v+Vr~5A z-_8q~e`}@e{{4#Zu3*{E2#+^`r}~(cTIzh;R$M!(r^1A}!f~jKd~g;`BIy|;ys(>Z z{@*N@e?JydFc<-yJdL_K>Ho>p_~#o30D(e)4?w`SCE@Sq7WA=b_ah7TR?h#k?f*$W zeIiSXdGlnkYFqQ~=jq{+gl8g7t@)FGBTVw#AF;Kd-U8jfpSv=nyoDYP?hugmbC zALyx}ea|w4;(+b{HJASX1^j2`9D#Ne}3S`PmAEk*{X!`{=W~A$WsJ= zxegb+lm6G0^Dn#%90bGr^4o5nz4;4+m1qEhfvIYXe?$KUWPyr;Nc0E42~$m7ew>kD z9e+(db2DktYpy`^H)KM8$u4-RUSA

    )DgY2Ry^lHB4uhR}IGvw}K@LT4 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 literal 0 HcmV?d00001 diff --git a/README.md b/README.md index 9bfc6ce..d95a5ab 100644 --- a/README.md +++ b/README.md @@ -301,7 +301,7 @@ def test(): 如果读者关于代码、视频、讲义有任何疑问,欢迎一起讨论 请注意以下几点: -- 描述尽量具体,视频或者代码哪一部分有问题?请尽量把涉及章节和代码贴出来,方便定位问题。 +- 描述尽量具体,视频或者代码哪一部分有问题(可以具体到文档或者代码行数)?请尽量把涉及章节和代码贴出来,方便定位问题。 - 如果涉及到代码,提问时请保持代码的格式 - 如果直接提了代码bug,最好有相关测试用例展示失败 test case,方便复现问题 @@ -331,4 +331,4 @@ mkdocs gh-deploy # 部署到自己的 github pages 扫码加入课程: -![扫码加入课程返现30%](https://camo.githubusercontent.com/a217604a83d60fdc610ba91e5c771664a4645a79/687474703a2f2f376b747574792e636f6d312e7a302e676c622e636c6f7564646e2e636f6d2f53637265656e25323053686f74253230323031382d30362d3032253230617425323032302e33372e34362e706e67) +![扫码加入课程](./163_course.png) From 7ede0ba196ce456289a1e93722fc53403e96be84 Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Thu, 31 Oct 2019 12:58:45 +0800 Subject: [PATCH 13/69] Create FUNDING.yml --- .github/FUNDING.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..89fa887 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms + +github: [PegasusWang] +custom: ["https://www.paypal.me/pegasuswang"] From 024bd6b778e9762aabe524c4e58826ff71ba3c90 Mon Sep 17 00:00:00 2001 From: PegasusWang Date: Sat, 14 Dec 2019 17:23:46 +0800 Subject: [PATCH 14/69] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d95a5ab..59cf292 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ - 网上很多视频教程不够循序渐进,不成系统 ## 作者简介 -曾就职于[知乎](https://www.zhihu.com/people/pegasus-wang/activities),任后端工程师,多年 Python 开发经验。 +曾就职于[知乎](https://www.zhihu.com/people/pegasus-wang/activities),现腾讯后端工程师,多年 Python 开发经验。 知乎专栏: From 6b50e4d1285923b70c79bd49a12f0b95740d573b Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Sun, 14 Jun 2020 09:23:13 +0800 Subject: [PATCH 15/69] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=89=91=E6=8C=87offer?= =?UTF-8?q?=20python=20=E9=A2=98=E8=A7=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...5\347\232\204\346\237\245\346\211\276).py" | 48 +++++++ ...7\346\215\242\347\251\272\346\240\274).py" | 36 +++++ ...3\345\215\260\351\223\276\350\241\250).py" | 59 ++++++++ ...2\344\272\214\345\217\211\346\240\221).py" | 63 +++++++++ ...6\347\216\260\351\230\237\345\210\227).py" | 56 ++++++++ ...0\345\260\217\346\225\260\345\255\227).py" | 41 ++++++ ...1\347\232\204\344\270\252\346\225\260).py" | 48 +++++++ ...\347\232\204n\344\275\215\346\225\260).py" | 31 ++++ ...6\350\241\250\350\212\202\347\202\271).py" | 43 ++++++ ...7\345\201\266\351\241\272\345\272\217).py" | 43 ++++++ ...k\344\270\252\350\212\202\347\202\271).py" | 87 ++++++++++++ ...3\350\275\254\351\223\276\350\241\250).py" | 73 ++++++++++ ...1\345\272\217\351\223\276\350\241\250).py" | 98 +++++++++++++ ...4\345\255\220\347\273\223\346\236\204).py" | 55 ++++++++ ...1\346\240\221\351\225\234\345\203\217).py" | 132 ++++++++++++++++++ ...2\346\227\213\347\237\251\351\230\265).py" | 81 +++++++++++ ...5\346\225\260\347\232\204\346\240\210).py" | 101 ++++++++++++++ ...1\345\207\272\345\272\217\345\210\227).py" | 85 +++++++++++ ...0\344\272\214\345\217\211\346\240\221).py" | 72 ++++++++++ ...5\345\216\206\345\272\217\345\210\227).py" | 51 +++++++ ...0\344\270\200\344\270\252\345\200\274).py" | 84 +++++++++++ ...4\345\220\221\351\223\276\350\241\250).py" | 65 +++++++++ ...2\345\205\250\346\216\222\345\210\227).py" | 125 +++++++++++++++++ ...2\347\232\204\346\225\260\345\255\227).py" | 121 ++++++++++++++++ ...47\232\204 k \344\270\252\346\225\260).py" | 86 ++++++++++++ ...4\346\234\200\345\244\247\345\222\214).py" | 46 ++++++ ...0\347\232\204\346\254\241\346\225\260).py" | 49 +++++++ ...0\345\260\217\347\232\204\346\225\260).py" | 74 ++++++++++ ...4_UglyNumber(\344\270\221\346\225\260).py" | 113 +++++++++++++++ ...1\347\232\204\345\255\227\347\254\246).py" | 52 +++++++ ...4\351\200\206\345\272\217\345\257\271).py" | 65 +++++++++ ...4\345\205\261\347\273\223\347\202\271).py" | 98 +++++++++++++ ...0\347\232\204\346\254\241\346\225\260).py" | 88 ++++++++++++ ...1\346\240\221\346\267\261\345\272\246).py" | 101 ++++++++++++++ ...1\347\232\204\346\225\260\345\255\227).py" | 72 ++++++++++ ...3\346\225\260\345\272\217\345\210\227).py" | 51 +++++++ 36 files changed, 2593 insertions(+) create mode 100644 "\345\211\221\346\214\207offer/03_FindInPartiallySortedMatrix(\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276).py" create mode 100644 "\345\211\221\346\214\207offer/04_ReplaceBlank(\346\233\277\346\215\242\347\251\272\346\240\274).py" create mode 100644 "\345\211\221\346\214\207offer/05_PrintListInReversedOrder(\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250).py" create mode 100644 "\345\211\221\346\214\207offer/06_ConstructBinaryTree(\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221).py" create mode 100644 "\345\211\221\346\214\207offer/07_QueueWithTwoStacks(\347\224\250\344\270\244\344\270\252\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227).py" create mode 100644 "\345\211\221\346\214\207offer/08_MinNumberInRotatedArray(\346\227\213\350\275\254\346\225\260\347\273\204\346\234\200\345\260\217\346\225\260\345\255\227).py" create mode 100644 "\345\211\221\346\214\207offer/10_NumberOf1InBinary(\344\272\214\350\277\233\345\210\266\344\270\2551\347\232\204\344\270\252\346\225\260).py" create mode 100644 "\345\211\221\346\214\207offer/12_Print1ToMaxOfNDigits(\346\211\223\345\215\2601\345\210\260\346\234\200\345\244\247\347\232\204n\344\275\215\346\225\260).py" create mode 100644 "\345\211\221\346\214\207offer/13_DeleteNodeInList(O1\346\227\266\351\227\264\345\210\240\351\231\244\351\223\276\350\241\250\350\212\202\347\202\271).py" create mode 100644 "\345\211\221\346\214\207offer/14_ReorderArray(\350\260\203\346\225\264\345\245\207\345\201\266\351\241\272\345\272\217).py" create mode 100644 "\345\211\221\346\214\207offer/15_KthNodeFromEnd(\351\223\276\350\241\250\345\200\222\346\225\260\347\254\254k\344\270\252\350\212\202\347\202\271).py" create mode 100644 "\345\211\221\346\214\207offer/16_ReverseList(\347\277\273\350\275\254\351\223\276\350\241\250).py" create mode 100644 "\345\211\221\346\214\207offer/17_MergeSortedLists(\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250).py" create mode 100644 "\345\211\221\346\214\207offer/18_SubstructureInTree(\346\240\221\347\232\204\345\255\220\347\273\223\346\236\204).py" create mode 100644 "\345\211\221\346\214\207offer/19_MirrorOfBinaryTree(\344\272\214\345\217\211\346\240\221\351\225\234\345\203\217).py" create mode 100644 "\345\211\221\346\214\207offer/20_PrintMatrix(\350\236\272\346\227\213\347\237\251\351\230\265).py" create mode 100644 "\345\211\221\346\214\207offer/21_MinInStack(\345\214\205\345\220\253min \345\207\275\346\225\260\347\232\204\346\240\210).py" create mode 100644 "\345\211\221\346\214\207offer/22_StackPushPopOrder(\346\240\210\347\232\204\345\216\213\345\205\245\345\274\271\345\207\272\345\272\217\345\210\227).py" create mode 100644 "\345\211\221\346\214\207offer/23_BfsTree(\345\261\202\345\272\217\344\273\216\344\270\212\345\276\200\344\270\213\346\211\223\345\215\260\344\272\214\345\217\211\346\240\221).py" create mode 100644 "\345\211\221\346\214\207offer/24_SquenceOfBST(\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227).py" create mode 100644 "\345\211\221\346\214\207offer/25_PathInTree(\344\272\214\345\217\211\346\240\221\345\222\214\344\270\272\346\237\220\344\270\200\344\270\252\345\200\274).py" create mode 100644 "\345\211\221\346\214\207offer/27_ConvertBinarySearchTree(\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\275\254\346\210\220\345\217\214\345\220\221\351\223\276\350\241\250).py" create mode 100644 "\345\211\221\346\214\207offer/28_StringPermutation(\345\255\227\347\254\246\344\270\262\345\205\250\346\216\222\345\210\227).py" create mode 100644 "\345\211\221\346\214\207offer/29_MoreThanHalfNumber(\346\225\260\347\273\204\344\270\255\345\207\272\347\216\260\346\254\241\346\225\260\350\266\205\350\277\207\344\270\200\345\215\212\347\232\204\346\225\260\345\255\227).py" create mode 100644 "\345\211\221\346\214\207offer/30_KLeastNumbers(\346\234\200\345\260\217\347\232\204 k \344\270\252\346\225\260).py" create mode 100644 "\345\211\221\346\214\207offer/31_GreatestSumOfSubarrays(\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204\346\234\200\345\244\247\345\222\214).py" create mode 100644 "\345\211\221\346\214\207offer/32_NumberOf1(\344\273\2161\345\210\260n\346\225\264\346\225\260\344\270\2551\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260).py" create mode 100644 "\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" create mode 100644 "\345\211\221\346\214\207offer/34_UglyNumber(\344\270\221\346\225\260).py" create mode 100644 "\345\211\221\346\214\207offer/35_FirstNotRepeatingChar(\347\254\254\344\270\200\344\270\252\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\345\255\227\347\254\246).py" create mode 100644 "\345\211\221\346\214\207offer/36_InversePairs(\346\225\260\347\273\204\344\270\255\347\232\204\351\200\206\345\272\217\345\257\271).py" create mode 100644 "\345\211\221\346\214\207offer/37_FirstCommonNodesInLists(\344\270\244\344\270\252\351\223\276\350\241\250\347\232\204\347\254\254\344\270\200\344\270\252\345\205\254\345\205\261\347\273\223\347\202\271).py" create mode 100644 "\345\211\221\346\214\207offer/38_NumberOfK(\346\225\260\345\255\227\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260).py" create mode 100644 "\345\211\221\346\214\207offer/39_1_TreeDepth(\344\272\214\345\217\211\346\240\221\346\267\261\345\272\246).py" create mode 100644 "\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" create mode 100644 "\345\211\221\346\214\207offer/41_1_TwoNumbersWithSum(\345\222\214\344\270\272s\347\232\204\344\270\244\344\270\252\346\225\260\345\255\227VS\345\222\214\344\270\272s\347\232\204\350\277\236\347\273\255\346\255\243\346\225\260\345\272\217\345\210\227).py" diff --git "a/\345\211\221\346\214\207offer/03_FindInPartiallySortedMatrix(\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276).py" "b/\345\211\221\346\214\207offer/03_FindInPartiallySortedMatrix(\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276).py" new file mode 100644 index 0000000..2023573 --- /dev/null +++ "b/\345\211\221\346\214\207offer/03_FindInPartiallySortedMatrix(\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276).py" @@ -0,0 +1,48 @@ +""" +剑指offer 第三题。从左到右升序从上到下升序数组,判断是否能找到一个值 +思路: +从右上角开始找,大于 target 排除当前列。小于 target 排除当前行 +""" + + +class Solution: + def solve(self, matrix, target): + if not matrix or not matrix[0]: + return False + leny = len(matrix) + + x = 0 + y = leny - 1 + + while x >= 0 and y >= 0: + if matrix[x][y] == target: + return True + elif matrix[x][y] > target: + y -= 1 + else: + x += 1 + return False + + +def test(): + s = Solution() + matrix = [ + [1, 2, 8, 9], + [2, 4, 9, 12], + [4, 7, 10, 13], + [6, 8, 11, 15], + ] + assert s.solve(matrix, 0) is False + assert s.solve(matrix, 1) is True + assert s.solve(matrix, 7) is True + assert s.solve(matrix, 5) is False + + # empty + matrix = [ + [], + ] + assert s.solve(matrix, 0) is False + + +if __name__ == '__main__': + test() diff --git "a/\345\211\221\346\214\207offer/04_ReplaceBlank(\346\233\277\346\215\242\347\251\272\346\240\274).py" "b/\345\211\221\346\214\207offer/04_ReplaceBlank(\346\233\277\346\215\242\347\251\272\346\240\274).py" new file mode 100644 index 0000000..f809497 --- /dev/null +++ "b/\345\211\221\346\214\207offer/04_ReplaceBlank(\346\233\277\346\215\242\347\251\272\346\240\274).py" @@ -0,0 +1,36 @@ +""" +替换字符串中的空格 +题目:请实现一个函数,把字符串中的每个空格替换成"%20"。例如输入“We are happy.”,则输出“We%20are%20happy.” +""" + + +class Solution: + def solve(self, string): + """因为 python string 不可变对象,和其他的语言用字符串数组能直接修改有点区别""" + res = [] + for char in string: + if char == ' ': + res.append('%20') + else: + res.append(char) + return ''.join(res) + + def solve2(self, string): + """ + 思路: + 先遍历一次计算替换后的总长度 + 从后往前替换,防止从前往后需要 + """ + pass + + +def test(): + s = Solution() + ss = 'We are happy.' + assert s.solve(ss) == 'We%20are%20happy.' + + assert s.solve('') == '' + + +if __name__ == '__main__': + test() diff --git "a/\345\211\221\346\214\207offer/05_PrintListInReversedOrder(\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250).py" "b/\345\211\221\346\214\207offer/05_PrintListInReversedOrder(\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250).py" new file mode 100644 index 0000000..4a0f74f --- /dev/null +++ "b/\345\211\221\346\214\207offer/05_PrintListInReversedOrder(\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250).py" @@ -0,0 +1,59 @@ +""" +面试题5:从尾到头打印链表 +题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值。链表结点定义如下: +""" +from collections import deque + + +class Stack: + def __init__(self): + self.items = deque() + + def push(self, val): + return self.items.append(val) + + def pop(self): + return self.items.pop() + + def empty(self): + return len(self.items) == 0 + + +class Node: + def __init__(self, val, next=None): + self.val, self.next = val, next + + +class Solution: + def solve(self, headnode): + """ + 思路:用一个栈保存所有节点,之后一个一个 pop + """ + val_s = Stack() + cur_node = headnode + while cur_node: + val_s.push(cur_node.val) + cur_node = cur_node.next + while not val_s.empty(): + print(val_s.pop()) + + def solve2(self, headnode): + """ + 能用栈就可以使用递归。这一点需要能联想到 + """ + curnode = headnode + if curnode: + self.solve2(curnode.next) + print(curnode.val) # 注意 print 放到 递归之后才是倒序 + + +def test(): + s = Solution() + linklist = Node(0, Node(1)) + s.solve2(linklist) + + # linklist = Node(0) + # s.solve2(linklist) + +if __name__ == '__main__': + test() diff --git "a/\345\211\221\346\214\207offer/06_ConstructBinaryTree(\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221).py" "b/\345\211\221\346\214\207offer/06_ConstructBinaryTree(\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221).py" new file mode 100644 index 0000000..c328ed4 --- /dev/null +++ "b/\345\211\221\346\214\207offer/06_ConstructBinaryTree(\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221).py" @@ -0,0 +1,63 @@ +""" +面试题6:重建二叉树 +题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 +例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建出图2.6所示的二叉树并输出它的头结点。二叉树结点的定义如下: +""" + + +class Node: + def __init__(self, val, left=None, right=None): + self.val, self.left, self.right = val, left, right + + +class Solution: + def __init__(self): + self.pres = [] + self.inorders = [] + + def solve(self, prevals, invals): + """ + 思路:先序找到根,然后可以找到中序遍历根的位置确定左子树和右子树,递归处理 + """ + if not prevals or not invals: + return None + root_val = prevals[0] + root = Node(root_val) + inorder_root_idx = invals.index(root_val) + left_length = inorder_root_idx + right_length = len(invals) - inorder_root_idx - 1 + + if left_length: + root.left = self.solve(prevals[1:1 + left_length], invals[:inorder_root_idx]) + + if right_length: + root.right = self.solve(prevals[left_length + 1:], invals[inorder_root_idx + 1:]) + return root + + def inorder(self, subtree): + if subtree: + self.inorder(subtree.left) + self.inorders.append(subtree.val) + self.inorder(subtree.right) + + def preorder(self, subtree): + if subtree: + self.pres.append(subtree.val) + self.preorder(subtree.left) + self.preorder(subtree.right) + + +def test(): + s = Solution() + prevals = [1, 2, 4, 7, 3, 5, 6, 8] + invals = [4, 7, 2, 1, 5, 3, 8, 6] + root = s.solve(prevals, invals) + s.inorder(root) + assert s.inorders == invals + + s.preorder(root) + assert s.pres == prevals + + +if __name__ == '__main__': + test() diff --git "a/\345\211\221\346\214\207offer/07_QueueWithTwoStacks(\347\224\250\344\270\244\344\270\252\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227).py" "b/\345\211\221\346\214\207offer/07_QueueWithTwoStacks(\347\224\250\344\270\244\344\270\252\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227).py" new file mode 100644 index 0000000..6deb686 --- /dev/null +++ "b/\345\211\221\346\214\207offer/07_QueueWithTwoStacks(\347\224\250\344\270\244\344\270\252\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227).py" @@ -0,0 +1,56 @@ +""" +面试题7:用两个栈实现队列 +题目:用两个栈实现一个队列。队列的声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能。 +""" + +from collections import deque + + +class Stack: + def __init__(self): + self.items = deque() + + def push(self, val): + return self.items.append(val) + + def pop(self): + return self.items.pop() + + def empty(self): + return len(self.items) == 0 + + def __len__(self): + return len(self.items) + + +class Queue: + def __init__(self): + self.s1 = Stack() + self.s2 = Stack() + + def append(self, val): + self.s1.push(val) + + def pop(self): + if len(self.s2): + return self.s2.pop() + while len(self.s1): + val = self.s1.pop() + self.s2.push(val) + return self.s2.pop() + + +def test(): + q = Queue() + q.append(1) + q.append(2) + q.append(3) + assert q.pop() == 1 + q.append(4) + assert q.pop() == 2 + assert q.pop() == 3 + assert q.pop() == 4 + + +if __name__ == '__main__': + test() diff --git "a/\345\211\221\346\214\207offer/08_MinNumberInRotatedArray(\346\227\213\350\275\254\346\225\260\347\273\204\346\234\200\345\260\217\346\225\260\345\255\227).py" "b/\345\211\221\346\214\207offer/08_MinNumberInRotatedArray(\346\227\213\350\275\254\346\225\260\347\273\204\346\234\200\345\260\217\346\225\260\345\255\227).py" new file mode 100644 index 0000000..72373ea --- /dev/null +++ "b/\345\211\221\346\214\207offer/08_MinNumberInRotatedArray(\346\227\213\350\275\254\346\225\260\347\273\204\346\234\200\345\260\217\346\225\260\345\255\227).py" @@ -0,0 +1,41 @@ +""" +面试题8:旋转数组的最小数字 +题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。 +例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 +""" + + +class Solution: + def findMin(self, array): + """ + 思路:二分 + 关键点:旋转数组的第一个数字是前半部分最小的,也是后半部分最大的 + """ + if len(array) == 1: + return array[0] + first = array[0] + size = len(array) + beg = 1 + end = size + + while beg < end: + mid = (beg + end) // 2 + if array[mid] > first: + beg = mid + 1 + else: + end = mid + if beg == size: + return first + else: + return array[beg] + + +def test(): + s = Solution() + assert s.findMin([0]) == 0 + assert s.findMin([1, 2]) == 1 # 注意这个特殊case + assert s.findMin([3, 4, 5, 1, 2]) == 1 + + +if __name__ == '__main__': + test() diff --git "a/\345\211\221\346\214\207offer/10_NumberOf1InBinary(\344\272\214\350\277\233\345\210\266\344\270\2551\347\232\204\344\270\252\346\225\260).py" "b/\345\211\221\346\214\207offer/10_NumberOf1InBinary(\344\272\214\350\277\233\345\210\266\344\270\2551\347\232\204\344\270\252\346\225\260).py" new file mode 100644 index 0000000..0c8cfff --- /dev/null +++ "b/\345\211\221\346\214\207offer/10_NumberOf1InBinary(\344\272\214\350\277\233\345\210\266\344\270\2551\347\232\204\344\270\252\346\225\260).py" @@ -0,0 +1,48 @@ +""" +面试题10:二进制中1的个数 +题目:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如把9表示成二进制是1001,有2位是1。因此如果输入9,该函数输出2。"" +""" + + +class Solution: + def solve_wrong(self, num): + """ + 不断右移,每次和1做与运算,结果为1就加1. + NOTE:但是输入负数会死循环。 + """ + cnt = 0 + while num: + if num & 1: + cnt += 1 + num >>= 1 + return cnt + + def solve(self, num): + """ + 不太能想出来:把一个数字不断和它的 num-1 与运算,能做几次就有几个 1 + 用一条语句判断一个整数是不是2的整数次方。一个整数如果是2的整数次方,那么它的二进制表示中有且只有一位是1, + 而其他所有位都是0。根据前面的分析,把这个整数减去1之后再和它自己做与运算,这个整数中唯一的1就会变成0。 + """ + cnt = 0 + while num: + num = (num - 1) & num + cnt += 1 + return cnt + + def solve_py(self, num): + """python有一种比较 tricky 的方式来做 + """ + s = format(num, 'b') + return s.counts('1') + + +def test(): + s = Solution() + assert s.solve(9) == 2 + assert s.solve(1) == 1 + assert s.solve(8) == 1 + assert s.solve(0) == 0 + + +if __name__ == '__main__': + test() diff --git "a/\345\211\221\346\214\207offer/12_Print1ToMaxOfNDigits(\346\211\223\345\215\2601\345\210\260\346\234\200\345\244\247\347\232\204n\344\275\215\346\225\260).py" "b/\345\211\221\346\214\207offer/12_Print1ToMaxOfNDigits(\346\211\223\345\215\2601\345\210\260\346\234\200\345\244\247\347\232\204n\344\275\215\346\225\260).py" new file mode 100644 index 0000000..f9214cd --- /dev/null +++ "b/\345\211\221\346\214\207offer/12_Print1ToMaxOfNDigits(\346\211\223\345\215\2601\345\210\260\346\234\200\345\244\247\347\232\204n\344\275\215\346\225\260).py" @@ -0,0 +1,31 @@ +""" +面试题12:打印1到最大的n位数 +题目:输入数字n,按顺序打印出从1最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的3位数即999。 + +思路:不能上来直接模拟。时间复杂度太大。 +因为 python 其实支持大数字运算,不需要像其他语言一样使用数组模拟大数。 +""" + + +class Solution: + def solve(self, n): + """递归的思路输出所有排列""" + nums = [0] * n + self._solve(nums, 0, n) + + def _solve(self, nums, beg, end): + if beg == end: + print(nums) + return + for i in range(10): + nums[beg] = i + self._solve(nums, beg + 1, end) + + +def test(): + s = Solution() + s.solve(9) + + +if __name__ == '__main__': + test() diff --git "a/\345\211\221\346\214\207offer/13_DeleteNodeInList(O1\346\227\266\351\227\264\345\210\240\351\231\244\351\223\276\350\241\250\350\212\202\347\202\271).py" "b/\345\211\221\346\214\207offer/13_DeleteNodeInList(O1\346\227\266\351\227\264\345\210\240\351\231\244\351\223\276\350\241\250\350\212\202\347\202\271).py" new file mode 100644 index 0000000..8c58c90 --- /dev/null +++ "b/\345\211\221\346\214\207offer/13_DeleteNodeInList(O1\346\227\266\351\227\264\345\210\240\351\231\244\351\223\276\350\241\250\350\212\202\347\202\271).py" @@ -0,0 +1,43 @@ +""" +面试题13:在O(1)时间删除链表结点 +题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。链表结点与函数的定义如下: + +https://leetcode.com/problems/delete-node-in-a-linked-list/ +""" + + +class Node: + def __init__(self, val, next=None): + self.val, self.next = val, next + + +class Solution: + def solve(self, headnode, target_node): + """ + 传统方法是从头遍历到要删除的节点,然后让前一个节点指向下一个节点。 + 思路:把下一个节点节点复制到当前节点就好了。但是要注意只有一个节点的情况 + - 链表只有一个节点 + - 链表有多个节点并且不是尾节点 + - 链表有多个节点并且是尾节点(此时不存在下一个节点了,需要从头遍历) + """ + if not headnode or not target_node: + return + + if target_node.next: + next_node = target_node.next + target_node.next = next_node.next + target_node.val = next_node.val + del next_node + + elif target_node == headnode: + headnode.next = None + del target_node + + else: # O(n) 删除 + cur_node = headnode + while cur_node: + if cur_node.next == target_node: + cur_node.next = target_node.next + del target_node + break + cur_node = cur_node.next diff --git "a/\345\211\221\346\214\207offer/14_ReorderArray(\350\260\203\346\225\264\345\245\207\345\201\266\351\241\272\345\272\217).py" "b/\345\211\221\346\214\207offer/14_ReorderArray(\350\260\203\346\225\264\345\245\207\345\201\266\351\241\272\345\272\217).py" new file mode 100644 index 0000000..9487332 --- /dev/null +++ "b/\345\211\221\346\214\207offer/14_ReorderArray(\350\260\203\346\225\264\345\245\207\345\201\266\351\241\272\345\272\217).py" @@ -0,0 +1,43 @@ +""" +面试题14:调整数组顺序使奇数位于偶数前面 +题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分 + +https://www.lintcode.com/problem/partition-array-by-odd-and-even/description +""" + + +class Solution: + """ + @param: nums: an array of integers + @return: nothing + """ + + def partitionArray(self, nums): + """ + 和快排的 partition 比较类似,只不过一个是根据数据的大小,一个是根据是否是 奇数和偶数 + """ + beg, end = 0, len(nums)-1 + while True: + while beg < end and nums[beg] % 2 == 1: + beg += 1 + while beg < end and nums[end] % 2 == 0: + end -= 1 + if beg >= end: + break + else: + nums[beg], nums[end] = nums[end], nums[beg] + + +def test(): + s = Solution() + ll = [1, 2, 3, 4] + s.partitionArray(ll) + assert ll == [1, 3, 2, 4] + + ll = [] + s.partitionArray(ll) + assert ll == [] + + +if __name__ == '__main__': + test() diff --git "a/\345\211\221\346\214\207offer/15_KthNodeFromEnd(\351\223\276\350\241\250\345\200\222\346\225\260\347\254\254k\344\270\252\350\212\202\347\202\271).py" "b/\345\211\221\346\214\207offer/15_KthNodeFromEnd(\351\223\276\350\241\250\345\200\222\346\225\260\347\254\254k\344\270\252\350\212\202\347\202\271).py" new file mode 100644 index 0000000..8ea8b4d --- /dev/null +++ "b/\345\211\221\346\214\207offer/15_KthNodeFromEnd(\351\223\276\350\241\250\345\200\222\346\225\260\347\254\254k\344\270\252\350\212\202\347\202\271).py" @@ -0,0 +1,87 @@ +""" +面试题15:链表中倒数第k个结点 +题目:输入一个链表,输出该链表中倒数第k个结点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾结点是倒数第1个结点。 +例如一个链表有6个结点,从头结点开始它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个结点是值为4的结点。 + +https://leetcode.com/problems/remove-nth-node-from-end-of-list/ +""" + +# Definition for singly-linked list. + + +class Node: + def __init__(self, x=None, next=None): + self.val = x + self.next = next + + def __str__(self): + return '{}'.format(self.val) + __repr__ = __str__ + + +class Solution: + def removeNthFromEnd(self, head, n): + """ + 思路:这一题的约束是只需要遍历一次。可以两个指针,相差 k 步 + + + :type head: ListNode + :type n: int + :rtype: ListNode + """ + # 做麻烦了,具体看 leetcode 这一题题解。加上root指向head 更容易做 + curnode = head + prenode = behind_node = head + for i in range(n-1): + curnode = curnode.next + while curnode.next: + curnode = curnode.next + prenode = behind_node + behind_node = behind_node.next + if prenode == behind_node == head: + newhead = head.next + del head + return newhead + elif prenode != behind_node: + prenode.next = behind_node.next + del behind_node + return head + + def to_list(self, head): + res = [] + cur_node = head + while cur_node: + res.append(cur_node.val) + cur_node = cur_node.next + return res + + +def test(): + s = Solution() + linklist = Node(1) + head = s.removeNthFromEnd(linklist, 1) + assert s.to_list(head) == [] + + linklist = Node(1, Node(2)) + head = s.removeNthFromEnd(linklist, 1) + assert s.to_list(head) == [1] + + linklist = Node(1, Node(2)) + head = s.removeNthFromEnd(linklist, 2) + assert s.to_list(head) == [2] + + linklist = Node(1, Node(2, Node(3, Node(4, Node(5))))) + head = s.removeNthFromEnd(linklist, 2) + assert s.to_list(head) == [1, 2, 3, 5] + + linklist = Node(1, Node(2, Node(3, Node(4, Node(5))))) + head = s.removeNthFromEnd(linklist, 1) + assert s.to_list(head) == [1, 2, 3, 4] + + linklist = Node(1, Node(2, Node(3, Node(4, Node(5))))) + head = s.removeNthFromEnd(linklist, 5) + assert s.to_list(head) == [2, 3, 4, 5] + + +if __name__ == '__main__': + test() diff --git "a/\345\211\221\346\214\207offer/16_ReverseList(\347\277\273\350\275\254\351\223\276\350\241\250).py" "b/\345\211\221\346\214\207offer/16_ReverseList(\347\277\273\350\275\254\351\223\276\350\241\250).py" new file mode 100644 index 0000000..a488e8b --- /dev/null +++ "b/\345\211\221\346\214\207offer/16_ReverseList(\347\277\273\350\275\254\351\223\276\350\241\250).py" @@ -0,0 +1,73 @@ +""" +定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。链表结点定义如下: +leetcode: +https://leetcode.com/problems/reverse-linked-list/ +""" + +# Definition for singly-linked list. + + +class Node: + def __init__(self, x, next=None): + self.val = x + self.next = next + + +class Solution: + + def reverseList(self, head): + """ + :type head: ListNode + :rtype: ListNode + """ + if not head or not head.next: + return head + newhead = self.reverseList(head.next) + nextnode = head.next # head -> nextnode + nextnode.next = head # head <- nextnode + head.next = None # None -< head <= nextnode + return newhead + + def reverseList_iter(self, head): + """ + :type head: ListNode + :rtype: ListNode + """ + prenode = None + curnode = head + while curnode: + nextnode = curnode.next + curnode.next = prenode + prenode = curnode + curnode = nextnode + return prenode # 注意返回的是 prenode + + def to_list(self, head): + res = [] + curnode = head + while curnode: + res.append(curnode.val) + curnode = curnode.next + return res + + +def test(): + s = Solution() + ll = Node(1, Node(2, Node(3, Node(4)))) + head = s.reverseList(ll) + assert s.to_list(head) == [4, 3, 2, 1] + + ll = Node(1) + head = s.reverseList(ll) + assert s.to_list(head) == [1] + + +def test_rec(): + s = Solution() + ll = Node(1, Node(2, Node(3, Node(4)))) + head = s.reverseList(ll) + assert s.to_list(head) == [4, 3, 2, 1] + + +if __name__ == '__main__': + test() diff --git "a/\345\211\221\346\214\207offer/17_MergeSortedLists(\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250).py" "b/\345\211\221\346\214\207offer/17_MergeSortedLists(\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250).py" new file mode 100644 index 0000000..7acc42e --- /dev/null +++ "b/\345\211\221\346\214\207offer/17_MergeSortedLists(\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250).py" @@ -0,0 +1,98 @@ +""" +面试题17:合并两个排序的链表 +题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的 + +https://leetcode.com/problems/merge-two-sorted-lists/ + +Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists. + +Example: + +Input: 1->2->4, 1->3->4 +Output: 1->1->2->3->4->4 +""" + + +# Definition for singly-linked list. +class ListNode: + def __init__(self, x, next=None): + self.val = x + self.next = next + + def __str__(self): + return '{}'.format(self.val) + __repr__ = __str__ + + +Node = ListNode + + +class Solution: + def mergeTwoLists(self, l1, l2): + """ + :type l1: ListNode + :type l2: ListNode + :rtype: ListNode + """ + if not l1: + return l2 + if not l2: + return l1 + + root = cur = ListNode(None) + while l1 and l2: + if l1.val < l2.val: + node = ListNode(l1.val) + l1 = l1.next + else: + node = ListNode(l2.val) + l2 = l2.next + cur.next = node + cur = node + cur.next = l1 or l2 # 链接剩余元素 + return root.next + + +class Solution2: + + def mergeTwoLists(self, l1, l2): + """ + 思路:使用递归简化问题,一开始想用循环来写的,比较麻烦 + + :type l1: ListNode + :type l2: ListNode + :rtype: ListNode + """ + if not l1: + return l2 + if not l2: + return l1 + node1, node2 = l1, l2 + head = None + if node1.val < node2.val: + head = node1 + head.next = self.mergeTwoLists(node1.next, node2) + else: + head = node2 + head.next = self.mergeTwoLists(node1, node2.next) + return head + + def to_list(self, head): + res = [] + curnode = head + while curnode: + res.append(curnode.val) + curnode = curnode.next + return res + + +def test(): + ll1 = Node(1, Node(2, Node(4))) + ll2 = Node(1, Node(3, Node(4))) + s = Solution() + head = s.mergeTwoLists(ll1, ll2) + assert s.to_list(head) == [1, 1, 2, 3, 4, 4] + + +if __name__ == '__main__': + test() diff --git "a/\345\211\221\346\214\207offer/18_SubstructureInTree(\346\240\221\347\232\204\345\255\220\347\273\223\346\236\204).py" "b/\345\211\221\346\214\207offer/18_SubstructureInTree(\346\240\221\347\232\204\345\255\220\347\273\223\346\236\204).py" new file mode 100644 index 0000000..896d0ce --- /dev/null +++ "b/\345\211\221\346\214\207offer/18_SubstructureInTree(\346\240\221\347\232\204\345\255\220\347\273\223\346\236\204).py" @@ -0,0 +1,55 @@ +""" +面试题18:树的子结构 +题目:输入两棵二叉树A和B,判断B是不是A的子结构。 + +https://leetcode.com/problems/subtree-of-another-tree/ 这一题和 leetcode 还不太一样。剑指offer 上要求是子树, +leetcode 这一题要求是严格的子树 +""" + + +class Node: + def __init__(self, val, left=None, right=None): + self.val, self.left, self.right = val, left, right + + +class Solution: + def isSubtree(self, s, t): + """ TODO 思路 + :type s: TreeNode + :type t: TreeNode + :rtype: bool + """ + res = False + if s and t: + if s.val == t.val: + res = self.is_sametree(s, t) + if not res: + res = self.isSubtree(s.left, t) + if not res: + res = self.isSubtree(s.right, t) + return res + + def is_sametree(self, t1, t2): + """递归判断两个树是否相同""" + if t1 is None and t2 is None: + return True + if t1 is None or t2 is None: + return False + if t1.val != t2.val: + return False + return self.is_sametree(t1.left, t2.left) and self.is_sametree(t1.right, t2.right) + + +def test(): + s = Node(3, Node(4, Node(1), Node(2)), Node(5)) + t = Node(4, Node(1), Node(2)) + so = Solution() + assert so.isSubtree(s, t) is True + + s = Node(3, Node(4, Node(1), Node(2, Node(0))), Node(5)) + t = Node(4, Node(1), Node(2)) + so = Solution() + assert so.isSubtree(s, t) is False + + +test() diff --git "a/\345\211\221\346\214\207offer/19_MirrorOfBinaryTree(\344\272\214\345\217\211\346\240\221\351\225\234\345\203\217).py" "b/\345\211\221\346\214\207offer/19_MirrorOfBinaryTree(\344\272\214\345\217\211\346\240\221\351\225\234\345\203\217).py" new file mode 100644 index 0000000..1fb3dad --- /dev/null +++ "b/\345\211\221\346\214\207offer/19_MirrorOfBinaryTree(\344\272\214\345\217\211\346\240\221\351\225\234\345\203\217).py" @@ -0,0 +1,132 @@ +""" +请完成一个函数,输入一个二叉树,该函数输出它的镜像。 +https://leetcode.com/problems/invert-binary-tree/ +""" + +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + + +class _Solution: + def invertTree(self, root): + """ + :type root: TreeNode + :rtype: TreeNode + """ + if root: + root.left, root.right = root.right, root.left + self.invertTree(root.left) + self.invertTree(root.right) + return root + + +# Definition for a binary tree node. +class Node: + def __init__(self, x, left=None, right=None): + self.val = x + self.left = left + self.right = right + + def __str__(self): + return '{}'.format(self.val) + + __repr__ = __str__ + + +from collections import deque + + +class Stack: + def __init__(self): + self.items = deque() + + def push(self, val): + return self.items.append(val) + + def pop(self): + return self.items.pop() + + def empty(self): + return len(self.items) == 0 + + +class Solution: # https://leetcode.com/problems/symmetric-tree/ + + def isSymmetric(self, root): + """ use stack """ + if not root: + return True + s = Stack() + s.push((root.left, root.right)) # push a tuple + while not s.empty(): + top_vals = s.pop() + left_node, right_node = top_vals[0], top_vals[1] + if left_node and right_node: + if left_node.val == right_node.val: + s.push((left_node.left, right_node.right)) + s.push((left_node.right, right_node.left)) + else: + return False + else: + if left_node != right_node: + return False + return True + + def isSymmetric_recursive(self, root): + """ 判断是否是镜像,使用递归的方式 + :type root: TreeNode + :rtype: bool + """ + def _check(left, right): + if left and right: + if left.val == right.val: + flag1 = _check(left.left, right.right) + flag2 = _check(left.right, right.left) + return flag1 and flag2 + else: + return False + else: + return left == right # 这种情况下 left 和 right 要么一个为 None,或者都是 None + + if root: + return _check(root.left, root.right) + return True + + def isSymmetric_layer(self, root): + """ 判断是否是镜像,使用层序遍历 + :type root: TreeNode + :rtype: bool + """ + if not root: + return True + curnodes = [root] + next_nodes = [] + while curnodes or next_nodes: + lefts = [] + rights = [] + for node in curnodes: + lefts.append(node.left.val if node.left else None) # NOTE: append val not node + rights.append(node.right.val if node.right else None) + if node.left: + next_nodes.append(node.left) + if node.right: + next_nodes.append(node.right) + if lefts != rights[::-1]: + return False + + curnodes = next_nodes + next_nodes = [] + return True + + +def test(): + t = Node(1, Node(2, Node(3), Node(4)), Node(2, Node(4), Node(3))) + s = Solution() + assert s.isSymmetric(t) is True + + +test() diff --git "a/\345\211\221\346\214\207offer/20_PrintMatrix(\350\236\272\346\227\213\347\237\251\351\230\265).py" "b/\345\211\221\346\214\207offer/20_PrintMatrix(\350\236\272\346\227\213\347\237\251\351\230\265).py" new file mode 100644 index 0000000..60b30b8 --- /dev/null +++ "b/\345\211\221\346\214\207offer/20_PrintMatrix(\350\236\272\346\227\213\347\237\251\351\230\265).py" @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- + +""" +https://leetcode.com/problems/spiral-matrix/ + +输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。 + +Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order. + +Example 1: + +Input: +[ + [ 1, 2, 3 ], + [ 4, 5, 6 ], + [ 7, 8, 9 ] +] +Output: [1,2,3,6,9,8,7,4,5] +Example 2: + +Input: +[ + [1, 2, 3, 4], + [5, 6, 7, 8], + [9,10,11,12] +] +Output: [1,2,3,4,8,12,11,10,9,5,6,7] + + +# https://leetcode.com/problems/spiral-matrix/discuss/20571/1-liner-in-Python-%2B-Ruby +看到了这个天才的解法,只需要一行 + +spiral_order([[1, 2, 3], + [4, 5, 6], + [7, 8, 9]]) + += [1, 2, 3] + spiral_order([[6, 9], + [5, 8], + [4, 7]]) + += [1, 2, 3] + [6, 9] + spiral_order([[8, 7], + [5, 4]]) + += [1, 2, 3] + [6, 9] + [8, 7] + spiral_order([[4], + [5]]) + += [1, 2, 3] + [6, 9] + [8, 7] + [4] + spiral_order([[5]]) + += [1, 2, 3] + [6, 9] + [8, 7] + [4] + [5] + spiral_order([]) + += [1, 2, 3] + [6, 9] + [8, 7] + [4] + [5] + [] + += [1, 2, 3, 6, 9, 8, 7, 4, 5] +""" + + +class Solution: + def spiralOrder(self, matrix): + """ + :type matrix: List[List[int]] + :rtype: List[int] + """ + if not matrix: # 注意递归出口,凡是涉及递归的都要注意 + return [] + first_row = matrix.pop(0) # 弹出第一行元素 + rotate_matrix = list(zip(*matrix))[::-1] + return list(first_row) + self.spiralOrder(rotate_matrix) # 注意 list(first_row)强转 + + +def test(): + matrix = [ + [1, 2, 3], + [4, 5, 6], + [7, 8, 9] + ] + s = Solution() + assert s.spiralOrder(matrix) == [1, 2, 3, 6, 9, 8, 7, 4, 5] + + +if __name__ == '__main__': + test() diff --git "a/\345\211\221\346\214\207offer/21_MinInStack(\345\214\205\345\220\253min \345\207\275\346\225\260\347\232\204\346\240\210).py" "b/\345\211\221\346\214\207offer/21_MinInStack(\345\214\205\345\220\253min \345\207\275\346\225\260\347\232\204\346\240\210).py" new file mode 100644 index 0000000..67a25a9 --- /dev/null +++ "b/\345\211\221\346\214\207offer/21_MinInStack(\345\214\205\345\220\253min \345\207\275\346\225\260\347\232\204\346\240\210).py" @@ -0,0 +1,101 @@ +""" +面试题21:包含min函数的栈 +题目:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调用min、push及pop的时间复杂度都是O(1)。 + +https://leetcode.com/problems/min-stack/ + +Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. + +push(x) -- Push element x onto stack. +pop() -- Removes the element on top of the stack. +top() -- Get the top element. +getMin() -- Retrieve the minimum element in the stack. + +Example: +MinStack minStack = new MinStack(); +minStack.push(-2); +minStack.push(0); +minStack.push(-3); +minStack.getMin(); --> Returns -3. +minStack.pop(); +minStack.top(); --> Returns 0. +minStack.getMin(); --> Returns -2. +""" + +from collections import deque + + +class Stack: + def __init__(self): + self.items = deque() + + def push(self, val): + return self.items.append(val) + + def pop(self): + return self.items.pop() + + def empty(self): + return len(self.items) == 0 + + def top(self): + return self.items[-1] + + +class MinStack: + + def __init__(self): + """ + initialize your data structure here. + """ + self.s = Stack() + self.mins = Stack() + + def push(self, x): + """ + :type x: int + :rtype: void + """ + self.s.push(x) + if self.mins.empty(): + self.mins.push(x) + else: + min_val = self.mins.top() + if x < min_val: + self.mins.push(x) + else: + self.mins.push(min_val) + + def pop(self): + """ + :rtype: void + """ + self.mins.pop() + return self.s.pop() + + def top(self): + """ + :rtype: int + """ + return self.s.top() + + def getMin(self): + """Retrieve the minimum element in the stack. + :rtype: int + """ + return self.mins.top() + + +def test(): + minStack = MinStack() + minStack.push(-2) + minStack.push(0) + minStack.push(-3) + assert minStack.getMin() == -3 # --> Returns -3. + minStack.pop() + assert minStack.top() == 0 # --> Returns 0. + assert minStack.getMin() == -2 # --> Returns -2. + + +if __name__ == '__main__': + test() diff --git "a/\345\211\221\346\214\207offer/22_StackPushPopOrder(\346\240\210\347\232\204\345\216\213\345\205\245\345\274\271\345\207\272\345\272\217\345\210\227).py" "b/\345\211\221\346\214\207offer/22_StackPushPopOrder(\346\240\210\347\232\204\345\216\213\345\205\245\345\274\271\345\207\272\345\272\217\345\210\227).py" new file mode 100644 index 0000000..e1b4555 --- /dev/null +++ "b/\345\211\221\346\214\207offer/22_StackPushPopOrder(\346\240\210\347\232\204\345\216\213\345\205\245\345\274\271\345\207\272\345\272\217\345\210\227).py" @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- + +""" +面试题22:栈的压入、弹出序列 +题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。 +假设压入栈的所有数字均不相等。 +例如序列1、2、3、4、5是某栈的压栈序列,序列4、5、3、2、1是该压栈序列对应的一个弹出序列, +但4、3、5、1、2就不可能是该压栈序列的弹出序列。 + +比如: +push 1 +push 2 +push 3 +push 4 +pop 4 # 4 +push 5 +pop 5 # 4,5 +pop 3 # 4,5,3 +pop 2 # 4,5,3,2 +pop 1 # 4,5,3,2,1 +""" + + +from collections import deque + + +class Stack: + def __init__(self): + self.items = deque() + + def push(self, val): + return self.items.append(val) + + def pop(self): + return self.items.pop() + + def empty(self): + return len(self.items) == 0 + + def top(self): + return self.items[-1] + + def __str__(self): + return str(self.items) + + __repr__ = __str__ + + +class Solution: + def solve(self, nums1, nums2): + """ + 思路:借助一个辅助stack + 如果下一个弹出数字刚好是栈顶数字,直接弹出。 + 如果下一个弹出数字不在栈顶,把压栈序列中还没有入栈的数字push 进辅助栈, + 直到把下一个需要弹出的数字压入栈顶为止。 + 如果所有数字压入栈了仍然没找到下一个弹出的数字,说明不可能是一个弹出序列。 + """ + idx1, idx2 = 0, 0 + s = Stack() + + while True: + if s.empty() or s.top() != nums2[idx2]: + s.push(nums1[idx1]) + idx1 += 1 + if s.top() == nums2[idx2]: + s.pop() + idx2 += 1 + print(s, idx1, idx2) + if idx1 == len(nums1) and s.empty(): + return True + # 注意最后一个判断条件,这个时候如果已经push 完了,结果栈顶还是找不到 nums2中元素,返回False + if idx1 == len(nums1) and not s.empty() and s.top() != nums2[idx2]: + return False + + +def test(): + s = Solution() + assert s.solve([1, 2, 3, 4, 5], [4, 5, 3, 2, 1]) is True + assert s.solve([1, 2, 3, 4, 5], [4, 3, 5, 1, 2]) is False + assert s.solve([1], [1]) is True + assert s.solve([1], [2]) is False + + +if __name__ == '__main__': + test() diff --git "a/\345\211\221\346\214\207offer/23_BfsTree(\345\261\202\345\272\217\344\273\216\344\270\212\345\276\200\344\270\213\346\211\223\345\215\260\344\272\214\345\217\211\346\240\221).py" "b/\345\211\221\346\214\207offer/23_BfsTree(\345\261\202\345\272\217\344\273\216\344\270\212\345\276\200\344\270\213\346\211\223\345\215\260\344\272\214\345\217\211\346\240\221).py" new file mode 100644 index 0000000..c897408 --- /dev/null +++ "b/\345\211\221\346\214\207offer/23_BfsTree(\345\261\202\345\272\217\344\273\216\344\270\212\345\276\200\344\270\213\346\211\223\345\215\260\344\272\214\345\217\211\346\240\221).py" @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +""" +层序遍历二叉树 +""" + +from collections import deque + + +class Queue: + def __init__(self): + self.items = deque() + + def append(self, val): + return self.items.append(val) + + def pop(self): + return self.items.popleft() + + def empty(self): + return len(self.items) == 0 + + +class Node: + def __init__(self, val, left=None, right=None): + self.val, self.left, self.right = val, left, right + + +class Solution: + def solve(self, root): + if not root: + return [] + curnodes = [root] + nextnodes = [] + res = [root.val] # 别忘记第一个元素的值放进去 + while curnodes: + for node in curnodes: + if node.left: + nextnodes.append(node.left) + if node.right: + nextnodes.append(node.right) + curnodes = nextnodes + res.extend([node.val for node in nextnodes]) + nextnodes = [] # 更新nextnodes + return res + + def solve_use_queue(self, root): + """use queue bfs""" + if not root: + return [] + q = Queue() + res = [root.val] + q.append(root) + while not q.empty(): + curnode = q.pop() + if curnode.left: + q.append(curnode.left) + res.append(curnode.left.val) + if curnode.right: + q.append(curnode.right) + res.append(curnode.right.val) + return res + + +def test(): + tree = Node(1, Node(2), Node(3)) + s = Solution() + assert s.solve(tree) == [1, 2, 3] + assert s.solve_use_queue(tree) == [1, 2, 3] + + +if __name__ == '__main__': + test() diff --git "a/\345\211\221\346\214\207offer/24_SquenceOfBST(\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227).py" "b/\345\211\221\346\214\207offer/24_SquenceOfBST(\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227).py" new file mode 100644 index 0000000..798f785 --- /dev/null +++ "b/\345\211\221\346\214\207offer/24_SquenceOfBST(\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227).py" @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +""" +面试题24:二叉搜索树的后序遍历序列 +题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。 +例如输入数组{5,7,6,9,11,10,8},则返回true,因为这个整数序列是图4.6二叉搜索树的后序遍历结果。如果输入的数组是{7,4,6,5},由于没有哪棵二叉搜索树的后序遍历的结果是这个序列,因此返回false。 + +类似练习:https://leetcode.com/problems/validate-binary-search-tree/ +""" + + +class Solution: + def solve(self, nums): + """考点:二叉搜索树,性质:左子树都小于根节点值,右子树都大于根节点值 + + 思路:递归求解 + - 注意递归出口 + - 找到左右子树 + - 判断是否右子树值都是大于根节点的,如果不是,直接 return False + - 递归判断左子树和右子树 + """ + if len(nums) == 1: # 递归出口,只有一个元素怎么遍历都是自己 + return True + + root_val = nums[-1] # 后根序,根节点的值 + left_end = 0 + while nums[left_end] < root_val: + left_end += 1 + left_part = nums[0:left_end] + right_part = nums[left_end: -1] + + for val in right_part: + if val < root_val: # 右子树必须都要大于根节点的值 + return False + + return self.solve(left_part) and self.solve(right_part) + + +def test(): + s = Solution() + nums = [5, 7, 6, 9, 11, 10, 8] + assert s.solve(nums) is True + + nums = [5] + assert s.solve(nums) is True + + nums = [7, 4, 6, 5] + assert s.solve(nums) is False + + +if __name__ == '__main__': + test() diff --git "a/\345\211\221\346\214\207offer/25_PathInTree(\344\272\214\345\217\211\346\240\221\345\222\214\344\270\272\346\237\220\344\270\200\344\270\252\345\200\274).py" "b/\345\211\221\346\214\207offer/25_PathInTree(\344\272\214\345\217\211\346\240\221\345\222\214\344\270\272\346\237\220\344\270\200\344\270\252\345\200\274).py" new file mode 100644 index 0000000..830a791 --- /dev/null +++ "b/\345\211\221\346\214\207offer/25_PathInTree(\344\272\214\345\217\211\346\240\221\345\222\214\344\270\272\346\237\220\344\270\200\344\270\252\345\200\274).py" @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- +""" +面试题25:二叉树中和为某一值的路径 +题目:输入一棵二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。 +从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。 + +https://leetcode.com/problems/path-sum/ +""" + + +# Definition for a binary tree node. +class Node: + def __init__(self, x, left=None, right=None): + self.val = x + self.left = left + self.right = right + + +from collections import deque + + +class Stack: + def __init__(self): + self.items = deque() + + def push(self, val): + return self.items.append(val) + + def pop(self): + return self.items.pop() + + def empty(self): + return len(self.items) == 0 + + +class Solution: + """ + https://leetcode.com/problems/path-sum/ + """ + + def hasPathSum(self, root, sum): + if not root: + return False + s = Stack() + s.push((root, root.val)) + while not s.empty(): + topnode, val = s.pop() + if topnode.left is None and topnode.right is None: + if val == sum: + return True + if topnode.left: + s.push((topnode.left, val+topnode.left.val)) + if topnode.right: + s.push((topnode.right, val+topnode.right.val)) + return False + + def _hasPathSum(self, root, sum, cursum=0): + """思路:递归判断,如果到了叶节点(left=right=None)当前 cursum 等于sum,返回 True + :type root: TreeNode + :type sum: int + :rtype: bool + """ + if not root: + return False + cursum += root.val + if root.left is None and root.right is None: + if cursum == sum: + return True + else: + cursum -= root.val + return self._hasPathSum(root.left, sum, cursum) or self._hasPathSum(root.right, sum, cursum) + + +def test(): + tree = Node(1, Node(2), Node(3)) + s = Solution() + # assert s.hasPathSum(tree, 4) + + N = Node + tree = N(5, N(4, N(11, N(7), N(2))), N(8, N(13), N(4, None, N(1)))) + assert s.hasPathSum(tree, 22) + + +test() diff --git "a/\345\211\221\346\214\207offer/27_ConvertBinarySearchTree(\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\275\254\346\210\220\345\217\214\345\220\221\351\223\276\350\241\250).py" "b/\345\211\221\346\214\207offer/27_ConvertBinarySearchTree(\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\275\254\346\210\220\345\217\214\345\220\221\351\223\276\350\241\250).py" new file mode 100644 index 0000000..9e32701 --- /dev/null +++ "b/\345\211\221\346\214\207offer/27_ConvertBinarySearchTree(\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\275\254\346\210\220\345\217\214\345\220\221\351\223\276\350\241\250).py" @@ -0,0 +1,65 @@ +""" +面试题27:二叉搜索树与双向链表 +题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。 +比如输入图4.12中左边的二叉搜索树,则输出转换之后的排序双向链表。 + +https://www.lintcode.com/problem/convert-binary-search-tree-to-doubly-linked-list/description + +Description +Convert a binary search tree to doubly linked list with in-order traversal. + +Have you met this question in a real interview? +Example +Given a binary search tree: + + 4 + / \ + 2 5 + / \ +1 3 +return 1<->2<->3<->4<->5 + +""" + + +# Definition of Doubly-ListNode +class DoublyListNode(object): + def __init__(self, val, next=None): + self.val = val + self.next = self.prev = None # nextDefinition of TreeNode: + + +class TreeNode: + def __init__(self, val): + self.val = val + self.left, self.right = None, None + + +class Solution: + """ 用了一种有点 tricky 的方式,中序遍历输出所有节点以后拼成链表 + @param root: The root of tree + @return: the head of doubly list node + """ + + def bstToDoublyList(self, root): + if not root: + return None + vals = [] + self.inorder(root, vals) + prevnode = head = DoublyListNode(vals[0]) + for idx in range(1, len(vals)): + node = DoublyListNode(vals[idx]) + node.prev = prevnode + prevnode.next = node + prevnode = node + return head + + def inorder(self, subtree, vals): + if subtree: + self.inorder(subtree.left, vals) + vals.append(subtree.val) + self.inorder(subtree.right, vals) + + +def test(): + pass diff --git "a/\345\211\221\346\214\207offer/28_StringPermutation(\345\255\227\347\254\246\344\270\262\345\205\250\346\216\222\345\210\227).py" "b/\345\211\221\346\214\207offer/28_StringPermutation(\345\255\227\347\254\246\344\270\262\345\205\250\346\216\222\345\210\227).py" new file mode 100644 index 0000000..d3d27c1 --- /dev/null +++ "b/\345\211\221\346\214\207offer/28_StringPermutation(\345\255\227\347\254\246\344\270\262\345\205\250\346\216\222\345\210\227).py" @@ -0,0 +1,125 @@ +""" +面试题28:字符串的排列 +题目:输入一个字符串,打印出该字符串中字符的所有排列。 +例如输入字符串abc,则打印出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。 + +https://leetcode.com/problems/permutations/ + +Given a collection of distinct integers, return all possible permutations. + +Example: + +Input: [1,2,3] +Output: +[ + [1,2,3], + [1,3,2], + [2,1,3], + [2,3,1], + [3,1,2], + [3,2,1] + ] + + +https://leetcode.com/problems/permutations-ii/ + +Given a collection of numbers that might contain duplicates, return all possible unique permutations. + +Example: + +Input: [1,1,2] +Output: +[ + [1,1,2], + [1,2,1], + [2,1,1] +] +""" + + +class Solution1: + def permute(self, nums): + """ + 思路:使用递归。 + 可以把问题拆解为更小的问题,分成两步走:(固定第一个字符并求解其后边数组的全排列) + 1. 首先求解可能出现在第一个位置的所有字符(即把第一个字符和后边的所有字符交换) + 2. 求该字符后的所有字符的全排列 + + :type nums: List[int] + :rtype: List[List[int]] + """ + def _per(nums, beg, end, res): + print(nums) + if beg == end - 1: + res.append(nums[:]) + else: + for i in range(beg, end): + nums[i], nums[beg] = nums[beg], nums[i] + _per(nums, beg + 1, end, res) + nums[i], nums[beg] = nums[beg], nums[i] + res = [] + _per(nums, 0, len(nums), res) + return res + + +class Solution2: + def permuteUnique(self, nums): + """ + :type nums: List[int] + :rtype: List[List[int]] + """ + if not nums: + return [] + + nums.sort() + + def _per(nums, beg, end, res): + if beg == end - 1: + res.append(nums[:]) # appen copy + + for i in range(beg, end): + if nums[i] not in nums[beg:i]: + nums[i], nums[beg] = nums[beg], nums[i] + _per(nums, beg + 1, end, res) + nums[i], nums[beg] = nums[beg], nums[i] + + res = [] + _per(nums, 0, len(nums), res) + return res + + +def test_per1(): + s = Solution1() + nums = [1, 2, 3] + for i in s.permute(nums): + print(i, '=') + + +def test_per2(): + s = Solution2() + nums = [1, 1, 2] + for i in s.permuteUnique(nums): + print(i, '=') + print('\n') + nums = [1, 2, 3] + for i in s.permuteUnique(nums): + print(i, '=') + + +def test(): + # test_per1() + test_per2() + + +def perms(nums, beg, end): + if beg == end - 1: + print(nums) + for i in range(beg, end): + nums[i], nums[beg] = nums[beg], nums[i] + perms(nums, beg + 1, end) + nums[i], nums[beg] = nums[beg], nums[i] + + +if __name__ == '__main__': + nums = [1, 2, 3] + perms(nums, 0, len(nums)) diff --git "a/\345\211\221\346\214\207offer/29_MoreThanHalfNumber(\346\225\260\347\273\204\344\270\255\345\207\272\347\216\260\346\254\241\346\225\260\350\266\205\350\277\207\344\270\200\345\215\212\347\232\204\346\225\260\345\255\227).py" "b/\345\211\221\346\214\207offer/29_MoreThanHalfNumber(\346\225\260\347\273\204\344\270\255\345\207\272\347\216\260\346\254\241\346\225\260\350\266\205\350\277\207\344\270\200\345\215\212\347\232\204\346\225\260\345\255\227).py" new file mode 100644 index 0000000..20a4187 --- /dev/null +++ "b/\345\211\221\346\214\207offer/29_MoreThanHalfNumber(\346\225\260\347\273\204\344\270\255\345\207\272\347\216\260\346\254\241\346\225\260\350\266\205\350\277\207\344\270\200\345\215\212\347\232\204\346\225\260\345\255\227).py" @@ -0,0 +1,121 @@ +""" +面试题29:数组中出现次数超过一半的数字 +题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2} 。 +由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。 + +https://leetcode.com/problems/majority-element/ + +Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times. + +You may assume that the array is non-empty and the majority element always exist in the array. + +Example 1: + +Input: [3,2,3] +Output: 3 +Example 2: + +Input: [2,2,1,1,1,2,2] +Output: 2 + + + +思路: +1. nlogn 直接排序输出中位数 +2. 使用快排的 partion 求中位数 +3. 遍历数组, +因此我们可以考虑在遍历数组的时候保存两个值:一个是数组中的一个数字,一个是次数。当我们遍历到下一个数字的时候, +如果下一个数字和我们之前保存的数字相同,则次数加1;如果下一个数字和我们之前保存的数字不同,则次数减1。如果次数为零, +我们需要保存下 一个数字,并把次数设为1。 +由于我们要找的数字出现的次数比其他所有数字出现的次数之和还要多,那么要找的数字肯定是最后一次把次数设为1时对应的数字。 +""" + + +class Solution3: + def majorityElement(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + mid = len(nums)//2 + return sorted(nums)[mid] + + +def partition(array, beg, end): + """对给定数组执行 partition 操作,返回新的 pivot 位置""" + pivot_index = beg + pivot = array[pivot_index] + left = pivot_index + 1 + right = end - 1 # 开区间,最后一个元素位置是 end-1 [0, end-1] or [0: end),括号表示开区间 + + while True: + # 从左边找到比 pivot 大的 + while left <= right and array[left] < pivot: + left += 1 + + while right >= left and array[right] >= pivot: + right -= 1 + + if left > right: + break + else: + array[left], array[right] = array[right], array[left] + left += 1 + right -= 1 + + array[pivot_index], array[right] = array[right], array[pivot_index] + return right # 新的 pivot 位置 + + +def nth_element(array, beg, end, nth): + """查找一个数组第 n 大元素""" + if beg < end: + pivot_idx = partition(array, beg, end) + if pivot_idx == nth - 1: # 数组小标从 0 开始 + return array[pivot_idx] + elif pivot_idx > nth - 1: + return nth_element(array, beg, pivot_idx, nth) + else: + return nth_element(array, pivot_idx + 1, end, nth) + + +class Solution2: + def majorityElement(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + mid = len(nums)//2+1 + return nth_element(nums, 0, len(nums), mid) # 自己写的 partition 超时了 + + +class Solution: + def majorityElement(self, nums): + """有一个次数过半,说明他出现的次数比其他所有次数和还多。 + 思路: + 设置两个变量一个记录次数times,一个记录当前数字cur。 + 如果下一个数字等于当前数字,times+1,否则times-1。 + 如果times为0,把times重新置位1,然后赋值为当前 cur。最后返回cur 就是需要找的值 + :type nums: List[int] + :rtype: int + """ + cur = nums[0] + times = 1 + for i in range(1, len(nums)): + if nums[i] == cur: + times += 1 + else: + times -= 1 + if times == 0: + times = 1 + cur = nums[i] + return cur + + +def test(): + s = Solution() + assert s.majorityElement([3, 2, 3]) == 3 + assert s.majorityElement([2, 2, 1, 1, 1, 2, 2]) == 2 + + +test() diff --git "a/\345\211\221\346\214\207offer/30_KLeastNumbers(\346\234\200\345\260\217\347\232\204 k \344\270\252\346\225\260).py" "b/\345\211\221\346\214\207offer/30_KLeastNumbers(\346\234\200\345\260\217\347\232\204 k \344\270\252\346\225\260).py" new file mode 100644 index 0000000..fc7e0c9 --- /dev/null +++ "b/\345\211\221\346\214\207offer/30_KLeastNumbers(\346\234\200\345\260\217\347\232\204 k \344\270\252\346\225\260).py" @@ -0,0 +1,86 @@ +""" +面试题30:最小的k个数 +题目:输入n个整数,找出其中最小的k个数。例如输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。 +这道题最简单的思路莫过于把输入的n个整数排序,排序之后位于最前面的k个数就是最小的k个数。这种思路的时间复杂度是O(nlogn),面试官会提示我们还有更快的算法。 + + +思路1:O(n) +如果能修改数组,我们可以用 parittion 函数求前 k 个(前k 个最小的,不一定是排序的) + +思路2:nlogk +适合大数据处理,用一个最大堆 +""" + +import heapq + + +class MaxHeap: + """ + https://stackoverflow.com/questions/2501457/what-do-i-use-for-a-max-heap-implementation-in-python + py 的 heapq 模块提供了方便的最小堆,但是最大堆需要我们自己实现。 + 有两种方式实现: + 1. 对放入的数字取反。比如 10 放入 -10 ,然后取出来的时候再取反。个人喜欢这种方式 + 2. 新建一个对象重写 __lt__ 方法。这种方式也可以,但是重写魔术方法修改了语义不太好 + + import heapq + + class MaxHeapObj(object): + def __init__(self,val): self.val = val + def __lt__(self,other): return self.val > other.val + def __eq__(self,other): return self.val == other.val + def __str__(self): return str(self.val) + """ + + def __init__(self, capacity): + self.capacity = capacity + self.minheap = [] + + def push(self, val): + heapq.heappush(self.minheap, -val) # 取反后的数字 + + def pop(self): + val = heapq.heappop(self.minheap) + return -val + + def max(self): + return -self.minheap[0] + + def __iter__(self): + for val in self.minheap: + yield -val + + +def test_maxheap(): + mh = MaxHeap(3) + mh.push(2) + mh.push(1) + mh.push(3) + assert mh.max() == 3 + assert mh.pop() == 3 + assert mh.pop() == 2 + assert mh.pop() == 1 + + +class Solution: + + def min_k(self, nums, k): + """最小的 k 个数字 + 分析时间复杂度 + """ + maxheap = MaxHeap(k) + for idx, val in enumerate(nums): + if idx < k: + maxheap.push(val) + else: + maxval = maxheap.max() + if val < maxval: + maxheap.pop() + maxheap.push(val) + return [i for i in maxheap] + + +def test(): + s = Solution() + nums = [4, 5, 1, 6, 2, 7, 3, 8] + res = s.min_k(nums, 4) + assert sorted(res) == [1, 2, 3, 4] diff --git "a/\345\211\221\346\214\207offer/31_GreatestSumOfSubarrays(\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204\346\234\200\345\244\247\345\222\214).py" "b/\345\211\221\346\214\207offer/31_GreatestSumOfSubarrays(\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204\346\234\200\345\244\247\345\222\214).py" new file mode 100644 index 0000000..b90c57e --- /dev/null +++ "b/\345\211\221\346\214\207offer/31_GreatestSumOfSubarrays(\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204\346\234\200\345\244\247\345\222\214).py" @@ -0,0 +1,46 @@ +""" +面试题31:连续子数组的最大和 +题目:输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。 +求所有子数组的和的最大值。 要求时间复杂度为O(n)。 + +Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum. + +Example: + +Input: [-2,1,-3,4,-1,2,1,-5,4], +Output: 6 +Explanation: [4,-1,2,1] has the largest sum = 6. +Follow up: + +If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle. + +https://leetcode.com/problems/maximum-subarray/ +""" + + +class Solution: + def maxSubArray(self, nums): + """ 动态规划问题。写出来状态转移方程。 + dp[i] = max(dp[i-1]+nums[i], dp[i]) + :type nums: List[int] + :rtype: int + """ + if not nums: + return 0 + size = len(nums) + max_list = [0] * size + for i in range(size): + if i == 0: + max_list[i] = nums[i] + else: + max_list[i] = max(nums[i] + max_list[i-1], nums[i]) + return max(max_list) + + +def test(): + s = Solution() + nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4] + assert s.maxSubArray(nums) == 6 + + +test() diff --git "a/\345\211\221\346\214\207offer/32_NumberOf1(\344\273\2161\345\210\260n\346\225\264\346\225\260\344\270\2551\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260).py" "b/\345\211\221\346\214\207offer/32_NumberOf1(\344\273\2161\345\210\260n\346\225\264\346\225\260\344\270\2551\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260).py" new file mode 100644 index 0000000..26889f4 --- /dev/null +++ "b/\345\211\221\346\214\207offer/32_NumberOf1(\344\273\2161\345\210\260n\346\225\264\346\225\260\344\270\2551\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260).py" @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +""" +面试题32:从1到n整数中1出现的次数 +题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。 +例如输入12,从1到12这些整数中包含1 的数字有1,10,11和12,1一共出现了5次。 + +思路:比较容易想出来的一种方法是从1到 n 统计每个数字包含的1。时间复杂度n*logn +""" + + +def numberof1(n): + strn = str(n) + length = len(strn) + first = int(strn[0]) + if len(strn) == 1 and first == 0: + return 0 + if len(strn) == 1 and first > 0: + return 1 + # 假设 strn = "21345" + # num_first_digit是数字 10000-19999 第一个位中的数目 + num_first_digit = 0 + if first > 1: # 第一位不是1 + num_first_digit = power_base10(length - 1) + elif first == 1: # 如果第一位置是1,是后边数字+1, 12345有 2346个 + num_first_digit = int(strn[1:]) + 1 + + # num_other_digits 是 1346-21345 除了第一位之外的数位中的数目 + num_other_digits = first * (length - 1) * power_base10(length - 2) + + # num_recursive 是 1-1345中的数目 + num_recursive = numberof1(strn[1:]) + return num_first_digit + num_other_digits + num_recursive + + +def power_base10(n): + res = 1 + i = 0 + while i < n: + res *= 10 + i += 1 + return res + + +def test(): + assert numberof1(10) == 1 + print(numberof1(21345)) + + +test() 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" new file mode 100644 index 0000000..90e3c4c --- /dev/null +++ "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" @@ -0,0 +1,74 @@ +""" +面试题33:把数组排成最小的数 +题目:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。 +例如输入数组{3,32,321},则打印出这3个数字能排成的最小数字321323。 + + +https://leetcode.com/problems/largest-number/ + +Given a list of non negative integers, arrange them such that they form the largest number. + +Example 1: + +Input: [10,2] +Output: "210" +Example 2: + +Input: [3,30,34,5,9] +Output: "9534330" +Note: The result may be very large, so you need to return a string instead of an integer. +""" + +from functools import cmp_to_key + + +class Solution: + def largestNumber(self, nums): + """思路:直接定义比较规则就好""" + def str_cmp(a, b): + return int(a+b) - int(b+a) + strs = [str(i) for i in nums] + strs.sort(key=cmp_to_key(str_cmp), reverse=True) + return str(int(''.join(strs))) + + def largestNumber_2(self, nums): + """ 思路:一开始的解法,比较 ugly,把所有的数字扩充成一样长度,之后再比较 + :type nums: List[int] + :rtype: str + """ + if len(nums) == 1: + return str(nums[0]) + num_strs = [str(i) for i in nums] + maxlen = len(max(num_strs, key=lambda _s: len(_s))) + pairs = [] + for num_str in num_strs: + if len(num_str) < maxlen: + difflen = maxlen - len(num_str) + max_char = max(num_str[0], num_str[-1]) + append_num_str = num_str + ''.join([max_char] * difflen) + pairs.append((append_num_str, num_str)) + else: + pairs.append((num_str, num_str)) + res = [] + for pair in sorted(pairs, reverse=True): + res.append(pair[1]) + idx, size = 0, len(res) + while res[idx] == '0' and idx != size-1: + idx += 1 + return ''.join(res[idx:]) + + +def test(): + s = Solution() + assert s.largestNumber([824, 938, 1399, 5607, 6973, 5703, 9609, 4398, 8247]) == '9609938824824769735703560743981399' + assert s.largestNumber([824, 8247]) == '8248247' + assert s.largestNumber([0, 0]) == '0' + assert s.largestNumber([1, 1, 1]) == '111' + assert s.largestNumber([3, 30, 34, 5, 9]) == "9534330" + assert s.largestNumber([10, 2]) == '210' + assert s.largestNumber([0, 2]) == '20' + assert s.largestNumber([1]) == '1' + assert s.largestNumber([0]) == '0' + + +test() diff --git "a/\345\211\221\346\214\207offer/34_UglyNumber(\344\270\221\346\225\260).py" "b/\345\211\221\346\214\207offer/34_UglyNumber(\344\270\221\346\225\260).py" new file mode 100644 index 0000000..b7c26d6 --- /dev/null +++ "b/\345\211\221\346\214\207offer/34_UglyNumber(\344\270\221\346\225\260).py" @@ -0,0 +1,113 @@ +""" +面试题34:丑数 +题目:我们把只包含因子2、3和5的数称作丑数(Ugly Number)。求按从小到大的顺序的第1500个丑数。例如6、8都是丑数,但14不是, +因为它包含因子7。习惯上我们把1当做第一个丑数。 + + +https://leetcode.com/problems/ugly-number/ +Write a program to check whether a given number is an ugly number. + +Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. + +Example 1: + +Input: 6 +Output: true +Explanation: 6 = 2 × 3 +Example 2: + +Input: 8 +Output: true +Explanation: 8 = 2 × 2 × 2 +Example 3: + +Input: 14 +Output: false +Explanation: 14 is not ugly since it includes another prime factor 7. +Note: + +1 is typically treated as an ugly number. +Input is within the 32-bit signed integer range: [−231, 231 − 1]. + + + +https://leetcode.com/problems/ugly-number-ii/ + +Write a program to find the n-th ugly number. + +Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. + +Example: + +Input: n = 10 +Output: 12 +Explanation: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10 ugly numbers. +Note: + +1 is typically treated as an ugly number. +n does not exceed 1690. +""" + + +class Solution1: + def isUgly(self, num): + """ + :type num: int + :rtype: bool + """ + if num == 0: + return False + for p in (2, 3, 5): + while num % p == 0: + num /= p + return num == 1 + + +class Solution: + def nthUglyNumber(self, n): + """ + 思路1:自增数字并且判断是否是丑数,直到找到第 n 个。效率低 + + 思路2:创建一个数组保存排好序的丑数。 + 根据其定义,丑数应该是另一个丑数乘以2,3,5的结果(1除外)。 + 可以创建一个数组,里边的数字是*排好序*的丑数,每一个丑数都是前边的丑数乘以2,3或5得到的。 + 关键在于如何保证数组里的丑数是排好序的。 + + :type n: int + :rtype: int + """ + idx2, idx3, idx5 = 0, 0, 0 + uglys = [1] + beg = 1 + while beg < n: + u2, u3, u5 = uglys[idx2] * 2, uglys[idx3]*3, uglys[idx5]*5 + minu = min(u2, u3, u5) + uglys.append(minu) + if u2 == minu: + idx2 += 1 + if u3 == minu: + idx3 += 1 + if u5 == minu: + idx5 += 1 + beg += 1 + return uglys[-1] + + +def test_isugly(): + s = Solution1() + assert s.isUgly(6) + assert s.isUgly(8) + assert s.isUgly(14) is False + assert s.isUgly(0) is False + assert s.isUgly(1) + + +def test_nth_ugly(): + s = Solution() + assert s.nthUglyNumber(11) == 15 + assert s.nthUglyNumber(1) == 1 + assert s.nthUglyNumber(10) == 12 + + +if __name__ == '__main__': + test_nth_ugly() diff --git "a/\345\211\221\346\214\207offer/35_FirstNotRepeatingChar(\347\254\254\344\270\200\344\270\252\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\345\255\227\347\254\246).py" "b/\345\211\221\346\214\207offer/35_FirstNotRepeatingChar(\347\254\254\344\270\200\344\270\252\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\345\255\227\347\254\246).py" new file mode 100644 index 0000000..5e2f979 --- /dev/null +++ "b/\345\211\221\346\214\207offer/35_FirstNotRepeatingChar(\347\254\254\344\270\200\344\270\252\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\345\255\227\347\254\246).py" @@ -0,0 +1,52 @@ +""" +面试题35:第一个只出现一次的字符 +题目:在字符串中找出第一个只出现一次的字符。如输入"abaccdeff",则输出'b'。 + + +https://leetcode.com/problems/first-unique-character-in-a-string/ + +Given a string, find the first non-repeating character in it and return it's index. If it doesn't exist, return -1. + +Examples: + +s = "leetcode" +return 0. + +s = "loveleetcode", +return 2. +Note: You may assume the string contain only lowercase letters. +""" + + +class Solution: + def firstUniqChar(self, s): + """ + 思路:哈希表。 + 对于范围大小确定的有限集合,字母可以看成是数字0-25。可以直接用数组来保存也可以 + + 变形题目: + 1. 定义一个函数,输入俩字符串,从第一个字符串中删除第二个字符串中出现过的所有字符 + 2. 写一个函数删除字符串中所有重复出现的字符。 + 3. 判断是否是变位词。两个单词字母和每个字母出现次数均相同 + :type s: str + :rtype: int + """ + chars = [0] * 26 + for char in s: + chars[ord(char) - ord('a')] += 1 + for idx, char in enumerate(s): + _idx = ord(char) - ord('a') + if chars[_idx] == 1: + return idx + return -1 + + +def test(): + s = Solution() + assert s.firstUniqChar('ll') == -1 + assert s.firstUniqChar('l') == 0 + assert s.firstUniqChar('leetcode') == 0 + assert s.firstUniqChar('loveleetcode') == 2 + + +test() diff --git "a/\345\211\221\346\214\207offer/36_InversePairs(\346\225\260\347\273\204\344\270\255\347\232\204\351\200\206\345\272\217\345\257\271).py" "b/\345\211\221\346\214\207offer/36_InversePairs(\346\225\260\347\273\204\344\270\255\347\232\204\351\200\206\345\272\217\345\257\271).py" new file mode 100644 index 0000000..c24455e --- /dev/null +++ "b/\345\211\221\346\214\207offer/36_InversePairs(\346\225\260\347\273\204\344\270\255\347\232\204\351\200\206\345\272\217\345\257\271).py" @@ -0,0 +1,65 @@ +""" +面试题36:数组中的逆序对 +题目:在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。 +输入一个数组,求出这个数组中的逆序对的总数。 +“例如在数组{7,5,6,4}中,一共存在5个逆序对,分别是(7,6)、(7,5)、(7,4)、(6,4)和(5,4)。” + +https://www.lintcode.com/problem/reverse-pairs/ + +思路1:扫描整个数组,寻找每个数字后边小于它的。O(n^2) +思路2:类似归并排序的思路。 +""" + + +class Solution: + """ + @param A: an array + @return: total of reverse pairs + """ + + def reversePairs(self, A): + """做归并排序的同时计数 + """ + count = 0 + + def merge(A, beg, end): + nonlocal count + if beg == end - 1: + return [A[beg]] + mid = (beg + end) // 2 + left = merge(A, beg, mid) + right = merge(A, mid, end) + copy = [None] * (len(left) + len(right)) + i = len(left) - 1 + j = len(right) - 1 + k = len(left) + len(right) - 1 + while i >= 0 and j >= 0: + if left[i] > right[j]: + count += j + 1 + copy[k] = left[i] + i -= 1 + k -= 1 + else: + copy[k] = right[j] + k -= 1 + j -= 1 + if i >= 0: + copy[0:i + 1] = left[0:i + 1] + if j >= 0: + copy[0:j + 1] = right[0:j + 1] + return copy + + res = merge(A, 0, len(A)) + print(res, '|||||') + return count + + +def test(): + s = Solution() + assert s.reversePairs([2]) == 0 + assert s.reversePairs([2, 4, 1, 3, 5]) == 3 + assert s.reversePairs([2, 1]) == 1 + assert s.reversePairs([2]) == 0 + + +test() diff --git "a/\345\211\221\346\214\207offer/37_FirstCommonNodesInLists(\344\270\244\344\270\252\351\223\276\350\241\250\347\232\204\347\254\254\344\270\200\344\270\252\345\205\254\345\205\261\347\273\223\347\202\271).py" "b/\345\211\221\346\214\207offer/37_FirstCommonNodesInLists(\344\270\244\344\270\252\351\223\276\350\241\250\347\232\204\347\254\254\344\270\200\344\270\252\345\205\254\345\205\261\347\273\223\347\202\271).py" new file mode 100644 index 0000000..dfb2e7c --- /dev/null +++ "b/\345\211\221\346\214\207offer/37_FirstCommonNodesInLists(\344\270\244\344\270\252\351\223\276\350\241\250\347\232\204\347\254\254\344\270\200\344\270\252\345\205\254\345\205\261\347\273\223\347\202\271).py" @@ -0,0 +1,98 @@ +""" +面试题37:两个链表的第一个公共结点 +题目:输入两个链表,找出它们的第一个公共结点。链表结点定义如下: + + +https://leetcode.com/problems/intersection-of-two-linked-lists/ + +思路: +两个链表连接以后,之后的节点都是一样的了。 + +1. 使用两个栈push 所有节点,然后比较栈顶元素,如果一样就 都 pop继续比较。如果栈顶不一样,结果就是上一次 pop 的值。 + +2. 先分别遍历两个链表,找到各自长度,然后让一个链表先走 diff(len1-len2)步骤,之后一起往前走,找到的第一个就是。 + +""" + +# Definition for singly-linked list. + + +class Node(object): + def __init__(self, x, next=None): + self.val = x + self.next = next + + +class _Solution(object): + def getIntersectionNode(self, headA, headB): + """ + :type head1, head1: ListNode + :rtype: ListNode + """ + if headA is None or headB is None or (headA is None and headB is None): + return None + len1 = 0 + cura = headA + while cura: + len1 += 1 + cura = cura.next + + len2 = 0 + curb = headB + while curb: + len2 += 1 + curb = curb.next + + difflen = abs(len1 - len2) + if len1 > len2: + for i in range(difflen): + headA = headA.next + else: + for i in range(difflen): + headB = headB.next + + while headA and headB: + if headA == headB: # headA.val == headB.val and headA.next == headB.next + return headA + headA = headA.next + headB = headB.next + + return None + + +class Solution(object): + def getIntersectionNode(self, headA, headB): + """ + :type head1, head1: ListNode + :rtype: ListNode + """ + if headA is None or headB is None: + return None + + len1 = 0 + cura = headA + while cura: + len1 += 1 + cura = cura.next + + len2 = 0 + curb = headB + while curb: + len2 += 1 + curb = curb.next + + difflen = abs(len1 - len2) + if len1 > len2: + for i in range(difflen): + headA = headA.next + else: + for i in range(difflen): + headB = headB.next + + while headA and headB: + if headA == headB: # headA.val == headB.val and headA.next == headB.next + return headA + headA = headA.next + headB = headB.next + + return None diff --git "a/\345\211\221\346\214\207offer/38_NumberOfK(\346\225\260\345\255\227\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260).py" "b/\345\211\221\346\214\207offer/38_NumberOfK(\346\225\260\345\255\227\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260).py" new file mode 100644 index 0000000..2cb5002 --- /dev/null +++ "b/\345\211\221\346\214\207offer/38_NumberOfK(\346\225\260\345\255\227\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260).py" @@ -0,0 +1,88 @@ +""" +面试题38:数字在排序数组中出现的次数 +题目:统计一个数字在排序数组中出现的次数。例如输入排序数组{1,2,3,3,3,3,4,5}和数字3,由于3在这个数组中出现了4次,因此输出4 + + +https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/ + +Given an array of integers nums sorted in ascending order, find the starting and ending position of a given target value. + +Your algorithm's runtime complexity must be in the order of O(log n). + +If the target is not found in the array, return [-1, -1]. + +Example 1: + +Input: nums = [5,7,7,8,8,10], target = 8 +Output: [3,4] +Example 2: + +Input: nums = [5,7,7,8,8,10], target = 6 +Output: [-1,-1] +""" + + +def find_left(array, beg, end, target): + while beg < end: + mid = (beg + end) // 2 + if target > array[mid]: + beg = mid + 1 + else: + end = mid + if beg != len(array) and array[beg] == target: + return beg + return -1 + + +def find_right(nums, beg, end, target): + while beg < end: + mid = (beg + end) >> 1 + if target >= nums[mid]: # 条件是>=,找到之后beg会在 target 后一个位置 + beg = mid + 1 + else: + end = mid + before = beg - 1 + if before != len(nums) and nums[before] == target: + return before + return -1 + + +class Solution(object): + def searchRange(self, nums, target): + """ + :type nums: List[int] + :type target: int + :rtype: List[int] + """ + if not nums: + return [-1, -1] + l = find_left(nums, 0, len(nums), target) + r = find_right(nums, 0, len(nums), target) + return [l, r] + + +def test_left(): + nums = [5, 7, 7, 8, 8, 10] + assert find_left(nums, 0, len(nums), 5) == 0 + assert find_left(nums, 0, len(nums), 10) == 5 + assert find_left(nums, 0, len(nums), 8) == 3 + assert find_left(nums, 0, len(nums), 9) == -1 + assert find_left(nums, 0, len(nums), 4) == -1 + + +def test_right(): + nums = [5, 7, 7, 8, 8, 10] + assert find_right(nums, 0, len(nums), 5) == 0 + assert find_right(nums, 0, len(nums), 10) == 5 + assert find_right(nums, 0, len(nums), 11) == -1 + assert find_right(nums, 0, len(nums), 8) == 4 + + +def test(): + s = Solution() + assert s.searchRange([5, 7, 7, 8, 8, 10], 8) == [3, 4] + assert s.searchRange([5, 7, 7, 8, 8, 10], 6) == [-1, -1] + + +test_left() +test_right() diff --git "a/\345\211\221\346\214\207offer/39_1_TreeDepth(\344\272\214\345\217\211\346\240\221\346\267\261\345\272\246).py" "b/\345\211\221\346\214\207offer/39_1_TreeDepth(\344\272\214\345\217\211\346\240\221\346\267\261\345\272\246).py" new file mode 100644 index 0000000..6c548e9 --- /dev/null +++ "b/\345\211\221\346\214\207offer/39_1_TreeDepth(\344\272\214\345\217\211\346\240\221\346\267\261\345\272\246).py" @@ -0,0 +1,101 @@ +""" +面试题39:二叉树的深度 +题目一:输入一棵二叉树的根结点,求该树的深度。从根结点到叶结点依次经过的 +结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。 + + + +https://leetcode.com/problems/maximum-depth-of-binary-tree/ + + + +Given a binary tree, determine if it is height-balanced. + +For this problem, a height-balanced binary tree is defined as: + +a binary tree in which the depth of the two subtrees of every node never differ by more than 1. + +Example 1: + +Given the following tree [3,9,20,null,null,15,7]: + + 3 + / \ + 9 20 + / \ + 15 7 +Return true. + +Example 2: + +Given the following tree [1,2,2,3,3,null,null,4,4]: + + 1 + / \ + 2 2 + / \ + 3 3 + / \ + 4 4 +Return false. +""" + + +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution1: + def maxDepth(self, root): + """ + :type root: TreeNode + :rtype: int + """ + if not root: + return 0 + left = self.maxDepth(root.left) + right = self.maxDepth(root.right) + if left > right: + return left + 1 + else: + return right + 1 + + +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +def maxDepth(root): + """ + :type root: TreeNode + :rtype: int + """ + if not root: + return 0 + left = maxDepth(root.left) + right = maxDepth(root.right) + if left > right: + return left + 1 + else: + return right + 1 + + +class Solution: + def isBalanced(self, root): + """ + :type root: TreeNode + :rtype: bool + """ + if not root: + return True + leftd = maxDepth(root.left) + rightd = maxDepth(root.right) + if abs(leftd-rightd) > 1: + return False + return self.isBalanced(root.left) and self.isBalanced(root.right) 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" new file mode 100644 index 0000000..30ada80 --- /dev/null +++ "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" @@ -0,0 +1,72 @@ +""" + +题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n), +空间复杂度是O(1)。 + +我们还是从头到尾依次异或数组中的每一个数字,那么最终得到的结果就是两个只出现一次的数字的异或结果。因为其他数字都出现了两次, +在异或中全部抵消了。由于这两个数字肯定不一样,那么异或的结果肯定不为0,也就是说在这个结果数字的二进制表示中至少就有一位为1。 +我们在结果数字中找到第一个为1的位的位置,记为第n位。现在我们以第n位是不是1为标准把原数组中的数字分成两个子数组 +,第一个子数组中每个数字的第n位都是1,而第二个子数组中每个数字的第n位都是0。由于我们分组的标准是数字中的某一位是1还是0, +那么出现了两次的数字肯定被分配到同一个子数组。因为两个相同的数字的任意一位都是相同的,我们不可能把两个相同的数字分配到两个子数组中去, +于是我们已经把原数组分成了两个子数组,每个子数组都包含一个只出现一次的数字,而其他数字都出现了两次。 +我们已经知道如何在数组中找出唯一一个只出现一次数字,因此到此为止所有的问题都已经解决了。 + + + +https://leetcode.com/problems/single-number-iii/ + +Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once. + +Example: + +Input: [1,2,1,3,2,5] +Output: [3,5] +Note: + +The order of the result is not important. So in the above example, [5, 3] is also correct. +Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity? +""" + + +class Solution1: + def singleNumber(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + first = 0 + for num in nums: + first ^= num + return first + + +class Solution: + def singleNumber(self, nums): + """ + :type nums: List[int] + :rtype: List[int] + """ + def get_single_num(nums): + first = 0 + for num in nums: + first ^= num + return first + + single = get_single_num(nums) + print(single) + mask = 1 + while single & mask == 0: + mask = mask << 1 + + 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)] + + +def test(): + s = Solution() + assert s.singleNumber([1, 2, 1, 3, 2, 5]) == [3, 5] + + +test() diff --git "a/\345\211\221\346\214\207offer/41_1_TwoNumbersWithSum(\345\222\214\344\270\272s\347\232\204\344\270\244\344\270\252\346\225\260\345\255\227VS\345\222\214\344\270\272s\347\232\204\350\277\236\347\273\255\346\255\243\346\225\260\345\272\217\345\210\227).py" "b/\345\211\221\346\214\207offer/41_1_TwoNumbersWithSum(\345\222\214\344\270\272s\347\232\204\344\270\244\344\270\252\346\225\260\345\255\227VS\345\222\214\344\270\272s\347\232\204\350\277\236\347\273\255\346\255\243\346\225\260\345\272\217\345\210\227).py" new file mode 100644 index 0000000..5b2149f --- /dev/null +++ "b/\345\211\221\346\214\207offer/41_1_TwoNumbersWithSum(\345\222\214\344\270\272s\347\232\204\344\270\244\344\270\252\346\225\260\345\255\227VS\345\222\214\344\270\272s\347\232\204\350\277\236\347\273\255\346\255\243\346\225\260\345\272\217\345\210\227).py" @@ -0,0 +1,51 @@ +""" +2-sum问题 + +面试题41:和为s的两个数字VS和为s的连续正数序列 +题目一:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s, +输出任意一对即可。 +""" + + +class Solution: + def twoSum(self, nums, target): + """ 注意这题目 letcode 不是有序的,剑指offer 上的是有序的。一种方式是用 hash 来做 + :type nums: List[int] + :type target: int + :rtype: List[int] + """ + num_idx_map = {} + for idx, num in enumerate(nums): + diff = target - num + if diff in num_idx_map: + return [num_idx_map[diff], idx] + else: + num_idx_map[num] = idx + + def twoSum1(self, nums, target): + """ 注意这题目 letcode 不是有序的,剑指offer 上的是有序的。可以先排序来做。之后首位指针向中间归并 + :type nums: List[int] + :type target: int + :rtype: List[int] + """ + pairs = [(num, i) for i, num in enumerate(nums)] + nums = sorted(pairs) + print(nums) + beg, end = 0, len(nums) - 1 + while beg < end: + sum2 = nums[beg][0] + nums[end][0] + if sum2 == target: + break + elif sum2 > target: + end -= 1 + else: + beg += 1 + return [nums[beg][1], nums[end][1]] + + +def test(): + s = Solution() + assert s.twoSum([3, 2, 4], 6) == [1, 2] + assert s.twoSum([2, 7], 9) == [0, 1] + assert s.twoSum([2, 7, 11, 15], 9) == [0, 1] + assert s.twoSum([1, 2, 4, 7, 11, 15], 15) == [2, 4] From bf8b1770038b64daded1c5ecedae86fdb36bf28f Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Sun, 14 Jun 2020 09:36:22 +0800 Subject: [PATCH 16/69] =?UTF-8?q?update=20readme=20leetcode=20and=20?= =?UTF-8?q?=E5=89=91=E6=8C=87offer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 59cf292..06cba17 100644 --- a/README.md +++ b/README.md @@ -8,17 +8,21 @@ ## 链接 视频教程已经发布在网易云课堂和 csdn 学院,内容一致,推荐使用网易云课堂。 -[网易云课堂: Python数据结构与算法教程](http://study.163.com/course/introduction.htm?courseId=1005526003) 视频教程 +- [网易云课堂: Python数据结构与算法教程](http://study.163.com/course/introduction.htm?courseId=1005526003) +- [csdn 学院:Python数据结构与算法教程](https://edu.csdn.net/course/detail/8332) -[csdn 学院:Python数据结构与算法教程](https://edu.csdn.net/course/detail/8332) +电子书地址: -[网上阅读《Python 算法与数据结构教程 》](http://pegasuswang.github.io/python_data_structures_and_algorithms/) +- [网上阅读《Python 算法与数据结构教程 》](http://pegasuswang.github.io/python_data_structures_and_algorithms/) +- [github 链接](https://github.com/PegasusWang/python_data_structures_and_algorithms) +- [readthedoc 电子书下载](http://python-data-structures-and-algorithms.readthedocs.io/zh/latest/) +- [《开源一个 Python 算法和数据结构中文教程[视频]》](https://zhuanlan.zhihu.com/p/36038003) 视频讲解示例 -[github 链接](https://github.com/PegasusWang/python_data_structures_and_algorithms) +leetcode 实战教程: -[readthedoc 电子书下载](http://python-data-structures-and-algorithms.readthedocs.io/zh/latest/) +如果您有一定的基础,只是想快速针对面试刷题,也可以直接参考笔者针对《剑指offer》和 leetcode 经典题目的 Python 刷题图解实战。 -[《开源一个 Python 算法和数据结构中文教程[视频]》](https://zhuanlan.zhihu.com/p/36038003) 视频讲解示例 +- [图解Python数据结构与算法-实战篇- leetcode经典题目实战](https://edu.csdn.net/course/detail/29389?event_id=1256&event_type=fission&share_username=WangPegasus&sign=22bded1300551606e3882cf6e4a265a1) ## 痛点 - 讲 Python 数据结构和算法的资料很少,中文资料更少 @@ -27,7 +31,7 @@ - 网上很多视频教程不够循序渐进,不成系统 ## 作者简介 -曾就职于[知乎](https://www.zhihu.com/people/pegasus-wang/activities),现腾讯后端工程师,多年 Python 开发经验。 +曾就职于[知乎](https://www.zhihu.com/people/pegasus-wang/activities),现腾讯视频后端工程师,多年 Python/Go 开发经验。 知乎专栏: @@ -100,23 +104,21 @@ Python 抽象程度比较高, 我们能用更少的代码来实现功能,同 - 无需太多数学基础,仅在算法时间复杂度分析的时候会用到一些简单数学知识。对于学习基础算法,逻辑思维可能更重要一些 ## 参考教材和链接 -这里我参考过三本书,均可以网购纸质版或者网络上搜索电子版,建议大家先大致阅读一本教材掌握基本原理: +这里我参考过三本书,均可以网购纸质版或者网络上搜索电子版,建议大家先大致阅读一本教材掌握基本原理,本教程重点在于 Pythonic 代码实现: [《算法图解》](https://book.douban.com/subject/26979890/): 图解的形式很适合新手,示例使用的是 python。推荐基础较少的同学看这本书入门 [《Data Structures and Algorithms in Python》]( https://book.douban.com/subject/10607365/): 适合对 Python 和算法比较熟悉的同学,或者是有其他语言编程经验的同学。本书是英文版,缺点是书中错误真的很多,代码有些无法运行而且不够 Pythonic。该书 [勘误](http://bcs.wiley.com/he-bcs/Books?action=resource&bcsId=9003&itemId=0470618299&resourceId=35653) -[《算法导论》第三版]( https://book.douban.com/subject/20432061/): 喜欢数学证明和板砖书的同学可以参考,有很多高级主题。使用伪代码 +[《算法导论》第三版]( https://book.douban.com/subject/20432061/): 喜欢数学证明和板砖书的同学可以参考,有很多高级主题。使用伪代码可以很快翻译成 Python ## 算法可视化 学习算法的过程中有时候会比较抽象,这里给大家推荐一些可视化的网站,方便更直观地理解: -https://github.com/algorithm-visualizer/algorithm-visualizer - -https://www.cs.usfca.edu/~galles/visualization/Algorithms.html - +- https://github.com/algorithm-visualizer/algorithm-visualizer +- https://www.cs.usfca.edu/~galles/visualization/Algorithms.html ## 讲课形式 @@ -156,7 +158,9 @@ https://www.cs.usfca.edu/~galles/visualization/Algorithms.html ## 如何获取每章代码 注意每一章目录里都有 py 文件,在电子书里看不到。clone 下本代码仓库找到对应目录里的 python 文件即是每章涉及到的代码。 -由于代码实现千差万别,本书代码实现具有一定的个人风格,不代表最佳实现,仅供参考。 +由于代码实现千差万别,本书代码实现具有一定的个人风格,不代表最佳实现,仅供参考,笔者尽量使用 python2/3 兼容代码。 +目前已经新增《剑指offer》大部分经典题目的 Python 解法。本项目遵守 MIT 协议,本项目下的所有代码您可以任意学习修改和使用, +但是直接引用代码请加上本项目 github 地址。 ## 如何学习 From 98d39d55e26bd22e9516ab5eb135e9cfe16c548c Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Sun, 14 Jun 2020 09:49:03 +0800 Subject: [PATCH 17/69] update readme --- docs/163_course.png | 1 + 1 file changed, 1 insertion(+) create mode 120000 docs/163_course.png diff --git a/docs/163_course.png b/docs/163_course.png new file mode 120000 index 0000000..c4f4aa7 --- /dev/null +++ b/docs/163_course.png @@ -0,0 +1 @@ +../163_course.png \ No newline at end of file From 778de19a0280ea17d699fd56d4a682b43baec58a Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Sun, 14 Jun 2020 19:25:25 +0800 Subject: [PATCH 18/69] =?UTF-8?q?add=20=E5=89=91=E6=8C=87offer=20python=20?= =?UTF-8?q?code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 06cba17..9ded6a9 100644 --- a/README.md +++ b/README.md @@ -159,8 +159,8 @@ Python 抽象程度比较高, 我们能用更少的代码来实现功能,同 注意每一章目录里都有 py 文件,在电子书里看不到。clone 下本代码仓库找到对应目录里的 python 文件即是每章涉及到的代码。 由于代码实现千差万别,本书代码实现具有一定的个人风格,不代表最佳实现,仅供参考,笔者尽量使用 python2/3 兼容代码。 -目前已经新增《剑指offer》大部分经典题目的 Python 解法。本项目遵守 MIT 协议,本项目下的所有代码您可以任意学习修改和使用, -但是直接引用代码请加上本项目 github 地址。 +目前已经新增《剑指offer》大部分经典题目的 Python 解法,每道题目附带leetcode 地址,大家可以自己尝试解决提交。 +本项目遵守 MIT 协议,本项目下的所有代码您可以任意学习修改和使用, 但是直接引用代码请加上本项目 github 地址。 ## 如何学习 From 0319f8bcd356a08aac81da5abe5728bc5f246aee Mon Sep 17 00:00:00 2001 From: PegasusWang <291374108@qq.com> Date: Mon, 15 Jun 2020 20:14:23 +0800 Subject: [PATCH 19/69] =?UTF-8?q?add=20=E5=89=91=E6=8C=87offer=20readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- "\345\211\221\346\214\207offer/readme.md" | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 "\345\211\221\346\214\207offer/readme.md" diff --git a/README.md b/README.md index 9ded6a9..15b5991 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ - [readthedoc 电子书下载](http://python-data-structures-and-algorithms.readthedocs.io/zh/latest/) - [《开源一个 Python 算法和数据结构中文教程[视频]》](https://zhuanlan.zhihu.com/p/36038003) 视频讲解示例 -leetcode 实战教程: +leetcode 实战教程(推荐): 如果您有一定的基础,只是想快速针对面试刷题,也可以直接参考笔者针对《剑指offer》和 leetcode 经典题目的 Python 刷题图解实战。 diff --git "a/\345\211\221\346\214\207offer/readme.md" "b/\345\211\221\346\214\207offer/readme.md" new file mode 100644 index 0000000..667914f --- /dev/null +++ "b/\345\211\221\346\214\207offer/readme.md" @@ -0,0 +1,3 @@ +# 《剑指offer》题解 + +你可以根据关键词搜索到 《剑指offer》上对应的 leetcode 题目。 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 20/69] 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 21/69] 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 22/69] =?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 23/69] =?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 24/69] 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 25/69] 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 26/69] =?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 27/69] 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 28/69] 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 29/69] 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 30/69] 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 31/69] 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 32/69] 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 33/69] 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 34/69] 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 35/69] 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 36/69] =?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 37/69] =?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 38/69] =?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 39/69] =?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 40/69] 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 41/69] =?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 42/69] 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 43/69] 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 44/69] 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 45/69] 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 46/69] =?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 47/69] =?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 48/69] 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 49/69] 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 50/69] 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 51/69] 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 52/69] 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 53/69] 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 54/69] 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 55/69] 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 56/69] 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 57/69] 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 58/69] 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 59/69] =?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 60/69] 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 61/69] =?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 62/69] 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 63/69] 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 64/69] 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 65/69] =?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 66/69] 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 67/69] =?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 68/69] =?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 69/69] 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 技巧