From 42178d4ff8410191f23826c3df4bdc1510fb4cff Mon Sep 17 00:00:00 2001 From: zlinna <1537216090@qq.com> Date: Tue, 19 Jun 2018 23:01:17 +0800 Subject: [PATCH 01/54] update func: isLeapYear (not(year % 4 and year % 100)) --- ch01_basic/at001_math.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ch01_basic/at001_math.py b/ch01_basic/at001_math.py index 764516c..cb53a8f 100644 --- a/ch01_basic/at001_math.py +++ b/ch01_basic/at001_math.py @@ -10,7 +10,7 @@ # 闰年判断 def isLeapYear(year): - return (not year % 4 and year % 100) or (not year % 400) + return (not(year % 4 and year % 100)) or (not year % 400) # 找零钱 @@ -97,4 +97,4 @@ def main(): if __name__ == '__main__': - main() \ No newline at end of file + main() From 7b8fa07ad18dabe716adf5c3ae0b335358fec8fb Mon Sep 17 00:00:00 2001 From: pluieciel Date: Fri, 21 Sep 2018 15:32:45 +0000 Subject: [PATCH 02/54] Update at001_math.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # 最小公倍数 def minCommonMultiple(m, n): --- ch01_basic/at001_math.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ch01_basic/at001_math.py b/ch01_basic/at001_math.py index cb53a8f..70fe4b5 100644 --- a/ch01_basic/at001_math.py +++ b/ch01_basic/at001_math.py @@ -10,7 +10,7 @@ # 闰年判断 def isLeapYear(year): - return (not(year % 4 and year % 100)) or (not year % 400) + return (not year % 4 and year % 100) or (not year % 400) # 找零钱 @@ -33,7 +33,7 @@ def maxCommonDivisor(m, n): # 最小公倍数 -def maxCommonMultiple(m, n): +def minCommonMultiple(m, n): return m * n / maxCommonDivisor(m, n) From df82b589074f689fa80453a2cefdd8bdfd8f7ac9 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Wed, 29 Jan 2020 20:23:55 +0800 Subject: [PATCH 03/54] update README.md --- .gitignore | 3 ++- README.md | 16 +++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index ee40bb3..eef840f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .idea/ -*.pyc \ No newline at end of file +*.pyc +/venv/ diff --git a/README.md b/README.md index 8bd5df4..8065f2d 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,22 @@ -## 《算法导论》第3版算法集锦 - python实现 +## 算法集锦 - python实现 + +参考书籍列表,从易到难的顺序,建议按照顺序阅读: + +* 《大话数据结构》 +* 《算法图解》 +* 《算法》第4版 +* 《算法导论》第3版 ### 作者的话 -《算法导论》第3版,这本书的经典程度就无需我多言了。 书中所有的算法示例都用python语言实现,并且配有详细的算法原理说明,有些复杂算法还会专门写博客来讲解。 -希望这些对自己,还有其他人都有所帮助。 +自从2016年后好久没更新了,今年2020年开始会继续更新这个系列。希望这些对自己,还有其他人都有所帮助。 有任何问题都可以联系我: * Email: yidao620@gmail.com -* 博客: http://yidao620c.github.io/ +* Blog: https://www.xncoding.com/ * GitHub: https://github.com/yidao620c ## How to Contribute @@ -33,7 +39,7 @@ Meanwhile you'd better follow the rules below (The Apache License) -Copyright (c) 2011-2015 [Xiong Neng](http://yidao620c.github.io/) and other contributors +Copyright (c) 2013-2020 [Xiong Neng](https://www.xncoding.com/) and other contributors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at From f02c20e7fb3d75e06be85f5a8721efae65c8b9a9 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Wed, 29 Jan 2020 20:35:18 +0800 Subject: [PATCH 04/54] update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 8065f2d..4dbb1e9 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@ 参考书籍列表,从易到难的顺序,建议按照顺序阅读: -* 《大话数据结构》 * 《算法图解》 * 《算法》第4版 * 《算法导论》第3版 From 1e91c890d964a4a10991d09c8503265b453ac517 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Fri, 31 Jan 2020 22:17:21 +0800 Subject: [PATCH 05/54] =?UTF-8?q?=E9=87=8D=E6=96=B0=E7=BB=84=E7=BB=87?= =?UTF-8?q?=E7=9B=AE=E5=BD=95=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LeeCode/todo.txt | 1 + README.md | 3 ++- files/names.txt | 0 test.py | 17 ----------------- .../todo.txt" | 1 + "\347\256\227\346\263\225/todo.txt" | 1 + .../ch01_basic/__init__.py" | 0 .../ch01_basic/at001_math.py" | 2 +- .../ch01_basic/at002_triangle_str.py" | 1 + .../ch01_basic/at003_duplicate_words.py" | 2 -- .../ch01_basic/at004_binary_add.py" | 2 +- .../ch01_basic/at005_nine_number.py" | 1 + .../ch01_basic/at008_hornerpoly.py" | 1 + .../ch01_basic/at010_max_subarr.py" | 1 + .../ch01_basic/at011_max_subarr2.py" | 2 ++ .../ch01_basic/at011_max_subarr3.py" | 0 .../ch01_basic/at012_code_funny.py" | 1 + .../ch01_basic/at013_rand_permute.py" | 1 - .../ch01_basic/at014_right_shift.py" | 0 .../ch01_basic/at015_sin_cpu.py" | 7 +++++-- .../ch01_basic/at016_bestsinger.py" | 2 +- .../ch01_basic/at017_bracket_match.py" | 0 .../ch02_sort/__init__.py" | 0 .../ch02_sort/at103_insert_sort.py" | 0 .../ch02_sort/at105_select_sort.py" | 0 .../ch02_sort/at106_merge_sort.py" | 0 .../ch02_sort/at107_merge_sort2.py" | 0 .../ch02_sort/at109_bubble_sort.py" | 0 .../ch02_sort/at200_heap_sort.py" | 0 .../ch02_sort/at203_quick_sort.py" | 0 .../ch02_sort/at204_count_sort.py" | 0 .../ch02_sort/at205_radix_sort.py" | 0 .../ch02_sort/at206_bucket_sort.py" | 2 +- .../ch02_sort/at207_find_minmax.py" | 0 .../ch02_sort/at208_imin_select.py" | 0 .../ch02_sort/at209_imin_select2.py" | 2 +- .../ch02_sort/at210_imin_list.py" | 0 .../ch02_sort/at211_prior_queue.py" | 2 +- .../ch03_datastruct/__init__.py" | 0 .../ch03_datastruct/at300_basic.py" | 0 .../ch03_datastruct/at301_bisearch_tree.py" | 0 .../ch03_datastruct/at302_redblack_tree.py" | 0 .../ch03_datastruct/at303_circle_queue.py" | 0 .../ch03_datastruct/redblack.cpp" | 0 .../ch04_dynamic/__init__.py" | 0 .../ch04_dynamic/at400_cut_steel.py" | 0 .../ch04_dynamic/at401_fibonacci.py" | 0 .../ch04_dynamic/at402_matrix_chain.py" | 0 .../ch04_dynamic/at403_elevator.py" | 0 .../ch04_dynamic/at404_lcs.py" | 0 .../ch05_greedy/__init__.py" | 0 .../files/names.txt" | 1 + 52 files changed, 24 insertions(+), 29 deletions(-) create mode 100644 LeeCode/todo.txt delete mode 100644 files/names.txt delete mode 100644 test.py create mode 100644 "\345\233\276\350\247\243\347\256\227\346\263\225/todo.txt" create mode 100644 "\347\256\227\346\263\225/todo.txt" rename ch01_basic/__init__.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/__init__.py" (100%) rename ch01_basic/at001_math.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at001_math.py" (98%) rename ch01_basic/at002_triangle_str.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at002_triangle_str.py" (99%) rename ch01_basic/at003_duplicate_words.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at003_duplicate_words.py" (98%) rename ch01_basic/at004_binary_add.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at004_binary_add.py" (93%) rename ch01_basic/at005_nine_number.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at005_nine_number.py" (99%) rename ch01_basic/at008_hornerpoly.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at008_hornerpoly.py" (99%) rename ch01_basic/at010_max_subarr.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at010_max_subarr.py" (99%) rename ch01_basic/at011_max_subarr2.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at011_max_subarr2.py" (99%) rename ch01_basic/at011_max_subarr3.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at011_max_subarr3.py" (100%) rename ch01_basic/at012_code_funny.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at012_code_funny.py" (99%) rename ch01_basic/at013_rand_permute.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at013_rand_permute.py" (99%) rename ch01_basic/at014_right_shift.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at014_right_shift.py" (100%) rename ch01_basic/at015_sin_cpu.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at015_sin_cpu.py" (79%) rename ch01_basic/at016_bestsinger.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at016_bestsinger.py" (98%) rename ch01_basic/at017_bracket_match.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at017_bracket_match.py" (100%) rename ch02_sort/__init__.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/__init__.py" (100%) rename ch02_sort/at103_insert_sort.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at103_insert_sort.py" (100%) rename ch02_sort/at105_select_sort.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at105_select_sort.py" (100%) rename ch02_sort/at106_merge_sort.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at106_merge_sort.py" (100%) rename ch02_sort/at107_merge_sort2.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at107_merge_sort2.py" (100%) rename ch02_sort/at109_bubble_sort.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at109_bubble_sort.py" (100%) rename ch02_sort/at200_heap_sort.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at200_heap_sort.py" (100%) rename ch02_sort/at203_quick_sort.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at203_quick_sort.py" (100%) rename ch02_sort/at204_count_sort.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at204_count_sort.py" (100%) rename ch02_sort/at205_radix_sort.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at205_radix_sort.py" (100%) rename ch02_sort/at206_bucket_sort.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at206_bucket_sort.py" (95%) rename ch02_sort/at207_find_minmax.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at207_find_minmax.py" (100%) rename ch02_sort/at208_imin_select.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at208_imin_select.py" (100%) rename ch02_sort/at209_imin_select2.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at209_imin_select2.py" (97%) rename ch02_sort/at210_imin_list.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at210_imin_list.py" (100%) rename ch02_sort/at211_prior_queue.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at211_prior_queue.py" (98%) rename ch03_datastruct/__init__.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/__init__.py" (100%) rename ch03_datastruct/at300_basic.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/at300_basic.py" (100%) rename ch03_datastruct/at301_bisearch_tree.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/at301_bisearch_tree.py" (100%) rename ch03_datastruct/at302_redblack_tree.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/at302_redblack_tree.py" (100%) rename ch03_datastruct/at303_circle_queue.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/at303_circle_queue.py" (100%) rename ch03_datastruct/redblack.cpp => "\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/redblack.cpp" (100%) rename ch04_dynamic/__init__.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/__init__.py" (100%) rename ch04_dynamic/at400_cut_steel.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at400_cut_steel.py" (100%) rename ch04_dynamic/at401_fibonacci.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at401_fibonacci.py" (100%) rename ch04_dynamic/at402_matrix_chain.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at402_matrix_chain.py" (100%) rename ch04_dynamic/at403_elevator.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at403_elevator.py" (100%) rename ch04_dynamic/at404_lcs.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at404_lcs.py" (100%) rename ch05_greedy/__init__.py => "\347\256\227\346\263\225\345\257\274\350\256\272/ch05_greedy/__init__.py" (100%) create mode 100644 "\347\256\227\346\263\225\345\257\274\350\256\272/files/names.txt" diff --git a/LeeCode/todo.txt b/LeeCode/todo.txt new file mode 100644 index 0000000..a459bc2 --- /dev/null +++ b/LeeCode/todo.txt @@ -0,0 +1 @@ +something \ No newline at end of file diff --git a/README.md b/README.md index 4dbb1e9..3f56983 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ 参考书籍列表,从易到难的顺序,建议按照顺序阅读: +* 《LeeCode算法题库》 * 《算法图解》 * 《算法》第4版 * 《算法导论》第3版 @@ -10,7 +11,7 @@ 书中所有的算法示例都用python语言实现,并且配有详细的算法原理说明,有些复杂算法还会专门写博客来讲解。 -自从2016年后好久没更新了,今年2020年开始会继续更新这个系列。希望这些对自己,还有其他人都有所帮助。 +自从2016年后好久没更新了,今年2020年开始会继续更新这个系列。 有任何问题都可以联系我: diff --git a/files/names.txt b/files/names.txt deleted file mode 100644 index e69de29..0000000 diff --git a/test.py b/test.py deleted file mode 100644 index 76f3cfc..0000000 --- a/test.py +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env python -# -*- encoding: utf-8 -*- -""" - Topic: sample - Desc : -""" -from ch01_basic import at010_max_subarr -__author__ = 'Xiong Neng' - -def main(): - a = [0] * 10 - a[1] = 2 - print(a) - - -if __name__ == '__main__': - print([1] + [1]) \ No newline at end of file diff --git "a/\345\233\276\350\247\243\347\256\227\346\263\225/todo.txt" "b/\345\233\276\350\247\243\347\256\227\346\263\225/todo.txt" new file mode 100644 index 0000000..a459bc2 --- /dev/null +++ "b/\345\233\276\350\247\243\347\256\227\346\263\225/todo.txt" @@ -0,0 +1 @@ +something \ No newline at end of file diff --git "a/\347\256\227\346\263\225/todo.txt" "b/\347\256\227\346\263\225/todo.txt" new file mode 100644 index 0000000..a459bc2 --- /dev/null +++ "b/\347\256\227\346\263\225/todo.txt" @@ -0,0 +1 @@ +something \ No newline at end of file diff --git a/ch01_basic/__init__.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/__init__.py" similarity index 100% rename from ch01_basic/__init__.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/__init__.py" diff --git a/ch01_basic/at001_math.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at001_math.py" similarity index 98% rename from ch01_basic/at001_math.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at001_math.py" index 70fe4b5..a0eda53 100644 --- a/ch01_basic/at001_math.py +++ "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at001_math.py" @@ -93,7 +93,7 @@ def main(): print(fibonacci(8)) mod(0.78) print(maxCommonDivisor(24, 36)) - print(maxCommonMultiple(24, 36)) + print(minCommonMultiple(24, 36)) if __name__ == '__main__': diff --git a/ch01_basic/at002_triangle_str.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at002_triangle_str.py" similarity index 99% rename from ch01_basic/at002_triangle_str.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at002_triangle_str.py" index 4698996..ffbfd53 100644 --- a/ch01_basic/at002_triangle_str.py +++ "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at002_triangle_str.py" @@ -20,5 +20,6 @@ def triangleDisplay(mystr): result.append(mystr[i: -1]) return result + for each in triangleDisplay(u"我和我的小伙伴们都惊呆了"): print(each) diff --git a/ch01_basic/at003_duplicate_words.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at003_duplicate_words.py" similarity index 98% rename from ch01_basic/at003_duplicate_words.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at003_duplicate_words.py" index 73686ae..cf4bced 100644 --- a/ch01_basic/at003_duplicate_words.py +++ "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at003_duplicate_words.py" @@ -5,8 +5,6 @@ Desc : """ -import sys - def find_count(filename): count_map = {} diff --git a/ch01_basic/at004_binary_add.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at004_binary_add.py" similarity index 93% rename from ch01_basic/at004_binary_add.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at004_binary_add.py" index 77c7ad0..925f91f 100644 --- a/ch01_basic/at004_binary_add.py +++ "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at004_binary_add.py" @@ -11,7 +11,7 @@ def biAdd(a, b): res = [] m = 0 - r = range(0, len(a)) + r = list(range(0, len(a))) r.reverse() for i in r: m, n = divmod(a[i] + b[i] + m, 2) diff --git a/ch01_basic/at005_nine_number.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at005_nine_number.py" similarity index 99% rename from ch01_basic/at005_nine_number.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at005_nine_number.py" index 5ecceed..81b3e0d 100644 --- a/ch01_basic/at005_nine_number.py +++ "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at005_nine_number.py" @@ -36,5 +36,6 @@ def nine_number(): result.append((each1, each2, each3)) return result + if __name__ == '__main__': print(nine_number()) diff --git a/ch01_basic/at008_hornerpoly.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at008_hornerpoly.py" similarity index 99% rename from ch01_basic/at008_hornerpoly.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at008_hornerpoly.py" index 5c7f4d1..b3d423f 100644 --- a/ch01_basic/at008_hornerpoly.py +++ "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at008_hornerpoly.py" @@ -15,5 +15,6 @@ def hornerPoly(coefficientArr, x): res = coefficientArr[i] + x * res return res + if __name__ == '__main__': print(hornerPoly((1, 2, 3), 2)) diff --git a/ch01_basic/at010_max_subarr.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at010_max_subarr.py" similarity index 99% rename from ch01_basic/at010_max_subarr.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at010_max_subarr.py" index 584b5bb..565beee 100644 --- a/ch01_basic/at010_max_subarr.py +++ "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at010_max_subarr.py" @@ -50,5 +50,6 @@ def __maxCrossingSubArr(seq, low, mid, high): maxRight = j return maxLeft, maxRight, leftSum + rightSum + if __name__ == '__main__': print(maxSubArr([13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7])) diff --git a/ch01_basic/at011_max_subarr2.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at011_max_subarr2.py" similarity index 99% rename from ch01_basic/at011_max_subarr2.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at011_max_subarr2.py" index 68dbc14..6d54999 100644 --- a/ch01_basic/at011_max_subarr2.py +++ "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at011_max_subarr2.py" @@ -8,6 +8,7 @@ 最后结论: k < lg(n)的时候,使用暴力算法 """ from math import log + __author__ = 'Xiong Neng' @@ -61,5 +62,6 @@ def __maxCrossingSubArr(seq, low, mid, high): maxRight = j return maxLeft, maxRight, leftSum + rightSum + if __name__ == '__main__': print(maxSubArr([13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7])) diff --git a/ch01_basic/at011_max_subarr3.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at011_max_subarr3.py" similarity index 100% rename from ch01_basic/at011_max_subarr3.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at011_max_subarr3.py" diff --git a/ch01_basic/at012_code_funny.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at012_code_funny.py" similarity index 99% rename from ch01_basic/at012_code_funny.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at012_code_funny.py" index 2c0d0d9..dd7d005 100644 --- a/ch01_basic/at012_code_funny.py +++ "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at012_code_funny.py" @@ -16,5 +16,6 @@ def list_chess(): for i in range(1, 10): print([(i, k) for k in range(1, 10) if abs(k - i) % 3 != 0]) + if __name__ == '__main__': list_chess() diff --git a/ch01_basic/at013_rand_permute.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at013_rand_permute.py" similarity index 99% rename from ch01_basic/at013_rand_permute.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at013_rand_permute.py" index a46e515..cb8feca 100644 --- a/ch01_basic/at013_rand_permute.py +++ "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at013_rand_permute.py" @@ -49,4 +49,3 @@ def randPermuteBySwap(seq): se = [4, 5, 12, 44, 56, 6] shuffle(se) # python中的函数 print(se) - diff --git a/ch01_basic/at014_right_shift.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at014_right_shift.py" similarity index 100% rename from ch01_basic/at014_right_shift.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at014_right_shift.py" diff --git a/ch01_basic/at015_sin_cpu.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at015_sin_cpu.py" similarity index 79% rename from ch01_basic/at015_sin_cpu.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at015_sin_cpu.py" index 9ee7149..47eb9ff 100644 --- a/ch01_basic/at015_sin_cpu.py +++ "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at015_sin_cpu.py" @@ -5,11 +5,14 @@ Topic: sample Desc : CPU正弦曲线 """ -import itertools, math, time, sys +import itertools +import math +import sys +import time __author__ = 'Xiong Neng' -time_period = float(sys.argv[1]) if len(sys.argv) > 1 else 60 # seconds +time_period = float(sys.argv[1]) if len(sys.argv) > 1 else 60 # seconds time_slice = float(sys.argv[2]) if len(sys.argv) > 2 else 0.04 # seconds N = int(time_period / time_slice) diff --git a/ch01_basic/at016_bestsinger.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at016_bestsinger.py" similarity index 98% rename from ch01_basic/at016_bestsinger.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at016_bestsinger.py" index 505c78c..f7a1f7d 100644 --- a/ch01_basic/at016_bestsinger.py +++ "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at016_bestsinger.py" @@ -37,7 +37,7 @@ def lucky_seven(rows=166, cols=5, choices=13, lucky=7, start=1): if nextnum > choices: nextnum -= choices if nextnum > choices: - nextnum -= choices + nextnum -= choices votes[row][col] = nextnum nextnum += 1 return votes diff --git a/ch01_basic/at017_bracket_match.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at017_bracket_match.py" similarity index 100% rename from ch01_basic/at017_bracket_match.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at017_bracket_match.py" diff --git a/ch02_sort/__init__.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/__init__.py" similarity index 100% rename from ch02_sort/__init__.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/__init__.py" diff --git a/ch02_sort/at103_insert_sort.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at103_insert_sort.py" similarity index 100% rename from ch02_sort/at103_insert_sort.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at103_insert_sort.py" diff --git a/ch02_sort/at105_select_sort.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at105_select_sort.py" similarity index 100% rename from ch02_sort/at105_select_sort.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at105_select_sort.py" diff --git a/ch02_sort/at106_merge_sort.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at106_merge_sort.py" similarity index 100% rename from ch02_sort/at106_merge_sort.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at106_merge_sort.py" diff --git a/ch02_sort/at107_merge_sort2.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at107_merge_sort2.py" similarity index 100% rename from ch02_sort/at107_merge_sort2.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at107_merge_sort2.py" diff --git a/ch02_sort/at109_bubble_sort.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at109_bubble_sort.py" similarity index 100% rename from ch02_sort/at109_bubble_sort.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at109_bubble_sort.py" diff --git a/ch02_sort/at200_heap_sort.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at200_heap_sort.py" similarity index 100% rename from ch02_sort/at200_heap_sort.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at200_heap_sort.py" diff --git a/ch02_sort/at203_quick_sort.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at203_quick_sort.py" similarity index 100% rename from ch02_sort/at203_quick_sort.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at203_quick_sort.py" diff --git a/ch02_sort/at204_count_sort.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at204_count_sort.py" similarity index 100% rename from ch02_sort/at204_count_sort.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at204_count_sort.py" diff --git a/ch02_sort/at205_radix_sort.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at205_radix_sort.py" similarity index 100% rename from ch02_sort/at205_radix_sort.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at205_radix_sort.py" diff --git a/ch02_sort/at206_bucket_sort.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at206_bucket_sort.py" similarity index 95% rename from ch02_sort/at206_bucket_sort.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at206_bucket_sort.py" index 5b26206..4edd233 100644 --- a/ch02_sort/at206_bucket_sort.py +++ "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at206_bucket_sort.py" @@ -11,7 +11,7 @@ """ from math import floor -from ch02_sort.at103_insert_sort import insertSort +from 算法导论.ch02_sort import insertSort __author__ = 'Xiong Neng' diff --git a/ch02_sort/at207_find_minmax.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at207_find_minmax.py" similarity index 100% rename from ch02_sort/at207_find_minmax.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at207_find_minmax.py" diff --git a/ch02_sort/at208_imin_select.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at208_imin_select.py" similarity index 100% rename from ch02_sort/at208_imin_select.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at208_imin_select.py" diff --git a/ch02_sort/at209_imin_select2.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at209_imin_select2.py" similarity index 97% rename from ch02_sort/at209_imin_select2.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at209_imin_select2.py" index 209822e..12f8fa9 100644 --- a/ch02_sort/at209_imin_select2.py +++ "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at209_imin_select2.py" @@ -6,7 +6,7 @@ Desc : 顺序统计量的选择算法(最坏情况下O(n)) 利用中位数的中位数作为pivot划分数组 """ -from ch02_sort.at103_insert_sort import insertSort +from 算法导论.ch02_sort import insertSort __author__ = 'Xiong Neng' diff --git a/ch02_sort/at210_imin_list.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at210_imin_list.py" similarity index 100% rename from ch02_sort/at210_imin_list.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at210_imin_list.py" diff --git a/ch02_sort/at211_prior_queue.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at211_prior_queue.py" similarity index 98% rename from ch02_sort/at211_prior_queue.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at211_prior_queue.py" index 5dad60f..e280b7f 100644 --- a/ch02_sort/at211_prior_queue.py +++ "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at211_prior_queue.py" @@ -5,7 +5,7 @@ Topic: sample Desc : 最大堆实现最大优先级队列 """ -import ch02_sort.at200_heap_sort as hsort +from 算法导论 import ch02_sort as hsort __author__ = 'Xiong Neng' diff --git a/ch03_datastruct/__init__.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/__init__.py" similarity index 100% rename from ch03_datastruct/__init__.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/__init__.py" diff --git a/ch03_datastruct/at300_basic.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/at300_basic.py" similarity index 100% rename from ch03_datastruct/at300_basic.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/at300_basic.py" diff --git a/ch03_datastruct/at301_bisearch_tree.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/at301_bisearch_tree.py" similarity index 100% rename from ch03_datastruct/at301_bisearch_tree.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/at301_bisearch_tree.py" diff --git a/ch03_datastruct/at302_redblack_tree.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/at302_redblack_tree.py" similarity index 100% rename from ch03_datastruct/at302_redblack_tree.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/at302_redblack_tree.py" diff --git a/ch03_datastruct/at303_circle_queue.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/at303_circle_queue.py" similarity index 100% rename from ch03_datastruct/at303_circle_queue.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/at303_circle_queue.py" diff --git a/ch03_datastruct/redblack.cpp "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/redblack.cpp" similarity index 100% rename from ch03_datastruct/redblack.cpp rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/redblack.cpp" diff --git a/ch04_dynamic/__init__.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/__init__.py" similarity index 100% rename from ch04_dynamic/__init__.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/__init__.py" diff --git a/ch04_dynamic/at400_cut_steel.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at400_cut_steel.py" similarity index 100% rename from ch04_dynamic/at400_cut_steel.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at400_cut_steel.py" diff --git a/ch04_dynamic/at401_fibonacci.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at401_fibonacci.py" similarity index 100% rename from ch04_dynamic/at401_fibonacci.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at401_fibonacci.py" diff --git a/ch04_dynamic/at402_matrix_chain.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at402_matrix_chain.py" similarity index 100% rename from ch04_dynamic/at402_matrix_chain.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at402_matrix_chain.py" diff --git a/ch04_dynamic/at403_elevator.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at403_elevator.py" similarity index 100% rename from ch04_dynamic/at403_elevator.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at403_elevator.py" diff --git a/ch04_dynamic/at404_lcs.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at404_lcs.py" similarity index 100% rename from ch04_dynamic/at404_lcs.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at404_lcs.py" diff --git a/ch05_greedy/__init__.py "b/\347\256\227\346\263\225\345\257\274\350\256\272/ch05_greedy/__init__.py" similarity index 100% rename from ch05_greedy/__init__.py rename to "\347\256\227\346\263\225\345\257\274\350\256\272/ch05_greedy/__init__.py" diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/files/names.txt" "b/\347\256\227\346\263\225\345\257\274\350\256\272/files/names.txt" new file mode 100644 index 0000000..41624af --- /dev/null +++ "b/\347\256\227\346\263\225\345\257\274\350\256\272/files/names.txt" @@ -0,0 +1 @@ +Jone, Smith, Tom \ No newline at end of file From 778fae7e33a5c2babec10aece98a2e0b24dfcbed Mon Sep 17 00:00:00 2001 From: xiongneng Date: Wed, 4 Mar 2020 23:51:14 +0800 Subject: [PATCH 06/54] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=B8=80=E4=B8=AAmkdoc?= =?UTF-8?q?s=E7=9A=84=E6=BC=94=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + docs/docs/about.md | 23 +++++++++++++++++++++++ docs/docs/chapters/subpage.md | 3 +++ docs/docs/chapters/tutorial.md | 22 ++++++++++++++++++++++ docs/docs/chapters/usage.md | 5 +++++ docs/docs/index.md | 17 +++++++++++++++++ docs/mkdocs.yml | 18 ++++++++++++++++++ 7 files changed, 89 insertions(+) create mode 100644 docs/docs/about.md create mode 100644 docs/docs/chapters/subpage.md create mode 100644 docs/docs/chapters/tutorial.md create mode 100644 docs/docs/chapters/usage.md create mode 100644 docs/docs/index.md create mode 100644 docs/mkdocs.yml diff --git a/.gitignore b/.gitignore index eef840f..eb4b4af 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .idea/ *.pyc /venv/ +site/ diff --git a/docs/docs/about.md b/docs/docs/about.md new file mode 100644 index 0000000..a37a1e0 --- /dev/null +++ b/docs/docs/about.md @@ -0,0 +1,23 @@ +# 关于我 + +这一页是我的一个基本介绍 + +## 学习经历 + +xxx年在哪里学习。 + +## 工作经历 +毕业后去了xx公司实习 + +## 联系方式 + +### 邮件 + +xxxx@gmail.com + +### QQ和微信 + ++ QQ:7969979797 ++ 微信:yixx8989 + + diff --git a/docs/docs/chapters/subpage.md b/docs/docs/chapters/subpage.md new file mode 100644 index 0000000..14d441b --- /dev/null +++ b/docs/docs/chapters/subpage.md @@ -0,0 +1,3 @@ +# 内部子页面 + +内部子页面,哈哈哈。修改后 \ No newline at end of file diff --git a/docs/docs/chapters/tutorial.md b/docs/docs/chapters/tutorial.md new file mode 100644 index 0000000..06452b4 --- /dev/null +++ b/docs/docs/chapters/tutorial.md @@ -0,0 +1,22 @@ +# 简易教程 + +## 介绍 + +xxxx + +## 第一章节 + +11111111111 + + +## 第二章节 + +22222222222 + +### 小章节1 + +笑笑哈哈 + +### 小章节2 + +哈哈哈浪费大是大非 \ No newline at end of file diff --git a/docs/docs/chapters/usage.md b/docs/docs/chapters/usage.md new file mode 100644 index 0000000..255c9cb --- /dev/null +++ b/docs/docs/chapters/usage.md @@ -0,0 +1,5 @@ +# 使用方法 + +入门啦啦啦啊,[进入子页面](../subpage/) + + diff --git a/docs/docs/index.md b/docs/docs/index.md new file mode 100644 index 0000000..000ea34 --- /dev/null +++ b/docs/docs/index.md @@ -0,0 +1,17 @@ +# Welcome to MkDocs + +For full documentation visit [mkdocs.org](https://www.mkdocs.org). + +## Commands + +* `mkdocs new [dir-name]` - Create a new project. +* `mkdocs serve` - Start the live-reloading docs server. +* `mkdocs build` - Build the documentation site. +* `mkdocs -h` - Print help message and exit. + +## Project layout + + mkdocs.yml # The configuration file. + docs/ + index.md # The documentation homepage. + ... # Other markdown pages, images and other files. diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml new file mode 100644 index 0000000..fa0f7bb --- /dev/null +++ b/docs/mkdocs.yml @@ -0,0 +1,18 @@ +site_name: core-algorithm + +nav: +- Home: index.md +- About: about.md +- Documents: + - 小学部分: + - Usage: chapters/usage.md + - Tutorial: chapters/tutorial.md + +theme: + name: readthedocs + highlightjs: true + hljs_languages: + - yaml + navigation_depth: 2 + titles_only: true + From 357c0627928b7fa24e32c044b98108452e888056 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Mon, 16 Mar 2020 00:28:26 +0800 Subject: [PATCH 07/54] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=B8=BAmaterial?= =?UTF-8?q?=E7=9A=84=E4=B8=BB=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/about.md | 23 ++++++++ docs/chapters/chapter1/post01.md | 70 ++++++++++++++++++++++++ docs/chapters/chapter1/post02.md | 5 ++ docs/chapters/chapter2/post03.md | 3 ++ docs/chapters/chapter2/post04.md | 3 ++ docs/chapters/chapter2/post05.md | 3 ++ docs/chapters/chapter2/temp/temp01.md | 3 ++ docs/chapters/chapter2/temp/temp02.md | 3 ++ docs/chapters/subpage.md | 3 ++ docs/chapters/tutorial.md | 22 ++++++++ docs/chapters/usage.md | 3 ++ docs/index.md | 17 ++++++ docs/mkdocs.yml | 18 ------- docs/resources/css/extra.css | 14 +++++ docs/resources/img/favicon.ico | Bin 0 -> 67646 bytes mkdocs.yml | 74 ++++++++++++++++++++++++++ 16 files changed, 246 insertions(+), 18 deletions(-) create mode 100644 docs/about.md create mode 100644 docs/chapters/chapter1/post01.md create mode 100644 docs/chapters/chapter1/post02.md create mode 100644 docs/chapters/chapter2/post03.md create mode 100644 docs/chapters/chapter2/post04.md create mode 100644 docs/chapters/chapter2/post05.md create mode 100644 docs/chapters/chapter2/temp/temp01.md create mode 100644 docs/chapters/chapter2/temp/temp02.md create mode 100644 docs/chapters/subpage.md create mode 100644 docs/chapters/tutorial.md create mode 100644 docs/chapters/usage.md create mode 100644 docs/index.md delete mode 100644 docs/mkdocs.yml create mode 100644 docs/resources/css/extra.css create mode 100644 docs/resources/img/favicon.ico create mode 100644 mkdocs.yml diff --git a/docs/about.md b/docs/about.md new file mode 100644 index 0000000..a37a1e0 --- /dev/null +++ b/docs/about.md @@ -0,0 +1,23 @@ +# 关于我 + +这一页是我的一个基本介绍 + +## 学习经历 + +xxx年在哪里学习。 + +## 工作经历 +毕业后去了xx公司实习 + +## 联系方式 + +### 邮件 + +xxxx@gmail.com + +### QQ和微信 + ++ QQ:7969979797 ++ 微信:yixx8989 + + diff --git a/docs/chapters/chapter1/post01.md b/docs/chapters/chapter1/post01.md new file mode 100644 index 0000000..fa0cf4e --- /dev/null +++ b/docs/chapters/chapter1/post01.md @@ -0,0 +1,70 @@ + +# 设计背景 + +由于网络安全的不确定性,决定设计这个。 + +## 文本修饰 + +加粗 **bold** + +斜体字 _斜体字_ + +加粗斜体 ___粗斜体___ + +下划线 ^^Insert me^^ + +删除线 ~~Delete me~~ + +增加 {++ add ++} + +修改 {~~ is ~> are ~~} + +删除 {-- del --} + +高亮 {== highlight ==} + +注释 {>> comment <<} + +上标 H^2^O, text^a\ superscript^ + +下标 CH~3~CH~2~OH, text~a\ subscript~ + +行内代码高亮:`:::java System.out.println("hello");` or `#!python println('hello')` + +键盘快捷键标签:++ctrl+alt+f++ + +其他 {++sth++} + +## 提示文字 + +???+ danger highlight blink "custom title or blank" + text vtext text, text, v + text vtext text, text, v + ```python + text1 = "Hello, " + text2 = "world!" + print text1 + text2 + ``` + +!!! note + this is a tip + +## 复选框 + +看看复选框 + +- [x] item1 +- [x] item2 +- [x] item3 + +## 表格演示 + +今年的旅游目标地 + +编号 | 省份 | 日期 +------ | ------- | -------------- +01 | 湖北 | 2020-12-12 +02 | 陕西 | 2020-12-12 +03 | 四川 | 2020-12-12 +04 | ShanXi | 2020-12-12 + diff --git a/docs/chapters/chapter1/post02.md b/docs/chapters/chapter1/post02.md new file mode 100644 index 0000000..bb63a8e --- /dev/null +++ b/docs/chapters/chapter1/post02.md @@ -0,0 +1,5 @@ +# post02 + +第2篇。。。。。。。。。 + +这里讨论IO和多线程 diff --git a/docs/chapters/chapter2/post03.md b/docs/chapters/chapter2/post03.md new file mode 100644 index 0000000..2e14259 --- /dev/null +++ b/docs/chapters/chapter2/post03.md @@ -0,0 +1,3 @@ +# post03 + +第3篇。。。。。。。。。 \ No newline at end of file diff --git a/docs/chapters/chapter2/post04.md b/docs/chapters/chapter2/post04.md new file mode 100644 index 0000000..fcc27af --- /dev/null +++ b/docs/chapters/chapter2/post04.md @@ -0,0 +1,3 @@ +# post04 + +第4篇。。。。。。。。。 \ No newline at end of file diff --git a/docs/chapters/chapter2/post05.md b/docs/chapters/chapter2/post05.md new file mode 100644 index 0000000..3de089f --- /dev/null +++ b/docs/chapters/chapter2/post05.md @@ -0,0 +1,3 @@ +# post05 + +第5篇。。。。。。。。。 \ No newline at end of file diff --git a/docs/chapters/chapter2/temp/temp01.md b/docs/chapters/chapter2/temp/temp01.md new file mode 100644 index 0000000..605bfb7 --- /dev/null +++ b/docs/chapters/chapter2/temp/temp01.md @@ -0,0 +1,3 @@ +# 我爱你 + +我爱你我爱你我爱你我爱你我爱你 \ No newline at end of file diff --git a/docs/chapters/chapter2/temp/temp02.md b/docs/chapters/chapter2/temp/temp02.md new file mode 100644 index 0000000..c2bc5d7 --- /dev/null +++ b/docs/chapters/chapter2/temp/temp02.md @@ -0,0 +1,3 @@ +# 王大锤 + +买个锤子锤子锤子 diff --git a/docs/chapters/subpage.md b/docs/chapters/subpage.md new file mode 100644 index 0000000..14d441b --- /dev/null +++ b/docs/chapters/subpage.md @@ -0,0 +1,3 @@ +# 内部子页面 + +内部子页面,哈哈哈。修改后 \ No newline at end of file diff --git a/docs/chapters/tutorial.md b/docs/chapters/tutorial.md new file mode 100644 index 0000000..06452b4 --- /dev/null +++ b/docs/chapters/tutorial.md @@ -0,0 +1,22 @@ +# 简易教程 + +## 介绍 + +xxxx + +## 第一章节 + +11111111111 + + +## 第二章节 + +22222222222 + +### 小章节1 + +笑笑哈哈 + +### 小章节2 + +哈哈哈浪费大是大非 \ No newline at end of file diff --git a/docs/chapters/usage.md b/docs/chapters/usage.md new file mode 100644 index 0000000..abbb6f7 --- /dev/null +++ b/docs/chapters/usage.md @@ -0,0 +1,3 @@ +# 使用方法 + +入门啦啦啦啊,[进入子页面](subpage.md) diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..000ea34 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,17 @@ +# Welcome to MkDocs + +For full documentation visit [mkdocs.org](https://www.mkdocs.org). + +## Commands + +* `mkdocs new [dir-name]` - Create a new project. +* `mkdocs serve` - Start the live-reloading docs server. +* `mkdocs build` - Build the documentation site. +* `mkdocs -h` - Print help message and exit. + +## Project layout + + mkdocs.yml # The configuration file. + docs/ + index.md # The documentation homepage. + ... # Other markdown pages, images and other files. diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml deleted file mode 100644 index fa0f7bb..0000000 --- a/docs/mkdocs.yml +++ /dev/null @@ -1,18 +0,0 @@ -site_name: core-algorithm - -nav: -- Home: index.md -- About: about.md -- Documents: - - 小学部分: - - Usage: chapters/usage.md - - Tutorial: chapters/tutorial.md - -theme: - name: readthedocs - highlightjs: true - hljs_languages: - - yaml - navigation_depth: 2 - titles_only: true - diff --git a/docs/resources/css/extra.css b/docs/resources/css/extra.css new file mode 100644 index 0000000..c42c78f --- /dev/null +++ b/docs/resources/css/extra.css @@ -0,0 +1,14 @@ +.md-typeset table:not([class]) th { + min-width: 5rem; + padding: .6rem .8rem; + background-color: #9facf6; + color: #fff; + vertical-align: top; +} + +.md-footer-nav__link { + padding-top: 0; + padding-bottom: 0; + -webkit-transition: opacity .25s; + transition: opacity .25s; +} \ No newline at end of file diff --git a/docs/resources/img/favicon.ico b/docs/resources/img/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..a93c7684ab0ee7aa70b837ac5b498379ed4184c5 GIT binary patch literal 67646 zcmeHQ2Y3`!7mW=O`B702DIrEgM8t+zKnO)Zq^XFA3eu6@d+$B;&_nMXLWhJ<5(p$A z2@w)P=%Kd&(!%}EnVGjcyV(?wP-MsNvO8O5XWn_|o_p`R6J1=M!GAq_y5L_omwf4; zamni9;*t-Bm-wRgI-l}c=9gVG)AybKI!C}c0?rX|j(~FnoFm{I0p|!fN5DA(&Jl2q zfO7<#Bj6kX=Lk4Qz&QfW5pa%xa|9l%5qK77V{ebu2|7UYxU>r#w%dzcS8a&INwQIR`KZNo*V& za)smN>fJhP&HYn<3c~Y`VfkThFpeq5IjuRB6xNE{3Tx$~vf-RKN8Mm~V0jJWbH2{c zsdL6t=jLDp$Pe-;J1pOUDXzY!7B!Ns!>jsW|4Udw7{`;poZ)euTjCMm*pnX|WB2;sWh#GY zQcgLwppqP$-&rQKC^i7Ee+^UP$+0)<0l%M`jh|CStQFph*UFDO!rBd==lmm{3TvJZ zvF7|N3M&TlfR!{J`5Hgt4&yQTJN$j;W;+7JL2*C-)?qm&?HQO=;^tS7!*e>wp_whD zUfK5=;4>UwjyK1jV@fV2r3V~mWyxV})@<_B?8k{UxlP|g9La5B&ADjCx-|A_WnkqD zp^CAfNNV3hf`4J#I&j%yM#Gc{wzzjl|4sCHp4Tj?eF! z?m@w;js(8tnvOpdqWwDRG^;a+g&Z+XD@yN+-!kJrss0sAz*#yP-w z!uiAV)(oSQxZ#Gd29aUmx87j@0nCv| zADu0Jebe-^q1j8aq4`S^F)WMh^{NfbYe~r1KO}g}@3Lof4cR@ax@;f(eSGo!uhhZ! zI0w``P@FdN+Me5va7xS9`1_oPj5G4UIN#I5o@V^%|1!X+hk0Rz=5=~=Kw!5_vi7eR zWnE)flNTj?$QuUkzgch(8d*(tjrdu1dj2HqdX|iFf8*Ke_`bqV%>_QH*B5;*)P2^jW+>=;^EwhyT!vs)M0gzrCUjFbC);!l6X7= z$4d@_NBJJ{rv`Yy7?Zlgo>mR8=RW!H^|oO-7W)AA6}6s~m4Cu&!!Q^8+h&lxW4{IN zRlxPiz`UYt9rV3{dpYszUsinkeJh)Ldq~T2Z}r2m9wpAn{kDn$r~&z4*xd?(QHMnXJkw3mw>;A3HR^7cj8_KxR;jAeM`xvJ|$#B zFArJW^{e>GA7^Ne<0Xf~qk4}%fH45`zydJFyo`OHCj1rmdELBzjr+6OXC30(BE4w% za}FrOTv%B*gY2L9IrvW8%WAl9?pqp|my(UWiFrqtJcK=!yw)rH+EwhU` z9(+`I+yAbL0hk9W4akh=>0lg}r(v__KI=6lLq@!{*Mhmi-t-tbzL4(YHQY-AcMk*i zZ!Ea4?)s(pbooM7b^ctYHq0A<nMgu9v(`@B8{-xcoU`ZwTu5n0piYxsQPURc9@Wv9<%MaNHMd54c>M2+mrAHzA| zNCPtBJf8*);5G7ERm`t(-+yS1rHuC!){Y+k9$(Pp zeE%Gn7XsHm)wsT_J#qigz&*b#YMoCOwt7$IG|LlTvA~PX@jH)$@8>xXf3pU#?)5a} zfr|Ugd9+#|9zCYD%{t6s+-ElzLWj75@4B|@TvxakG;sd_eAjVb&@!*gZ}G0oYyOVR zZT7ZIYnbcw+nJwvXz^f$!Wrsx{q?nuQ(9&5T;1obxxRz5FAtmaY50(4U#Q$vX~35l zgZwa#Ne0+|RRa|F8SA>iw3r`{rT2}=9-}y(+++CgoF*Utu`Fv(+zWv3AAsxcgX{T3 z$32e)_c={-%j_nuGOKY;@v5069KZLkeL#NK7pfE6;SFBzM{H@KW8MxA8TC$h%;bFW zu~Q1jp~(d$%BzqZ@cL5rjVUgX$X#RR)skIv+o_n8_?v5i|HV9znA13?>Gz2}uaong z^SfqXmKQ+Ju#`Pd~ z7{`a>#4&r4H=aK+XHLuOVZ5iX&xhx{Ugp1Lc8<)sA*Hxa;UC=Z^+ejfpyj*p^W?j` z%xUTduIC2ViF*zc?pejVeioTp?{!(!GK-9@pLvq<%iD+M*c3E0dwAH$oH0?Ob4m0V zSBV(vDq(|jOK?9o3F_r8LA~FR-F@DbJ$>JkJ^k`Y@PPahGO&Pz3@WH&KjahO{~56V zT*5rR0QO%=#KaV6#N@!!hPm91sY;M(k2pdTXsrD5a($AvL5HQ-6a zpXaP_C+574Ofce3ZF7V18b5^8J(uk2kz024d>i-!``&qEci+4^_Wj=n{vQDU4}m?nuVHWE{s?e? zq&@e6y;o`35Bv{71EPJpoyPU6I8bRo0lfC4tp}PhC)drGb1u`@yTgb(^`5yNdCxgt z4)=9%S(27N%UO3=WZz|~!L56um(<10dG7Y+P@ee0KjKe5jw+u8wtV86XXW{vv+7Vf`g;y$o9b6@lOiu?H; za36l3y07_tTkbRFi=^MzxL*eK>vD2nQh8`VEAgM!Ld7BFFcu|Y)Wkfn$1xAI$DICM zVb1d<=A64c|NJn{Wn#`X4)UGXM?c4F<(x0yuzaSbJ33`dw%(&~Us03mfzM$*@OcUE z{ec`qOtk};`V#x5I`)3epEvMV*ju^3joc^p8ux*{J@+-gpP2ia-?!+#^804p2ltJb zFHDR1p!=hWAm%gczKQ#jzLO}#fCpz)m!q2o#A6&P7~?@saIEMjsg)et=V6a>GhBjg_gSzf?zNuRuwPaC1@r}^lkh$t%CRvX5&%w< z_kPV3_UXWT;19p=kG?@$?(2TvG53MJru#bggQ)wKn9t08U~i-Q_KJnN6z83RQ_boA>;yz`F8rRGO#2u$9tAJz}zdO>l=xDe{!7nsRP{Wrq{4vQ~xDdQ$K_3?DV!AA74&_ zySr+-uVOxb#(XxqZ;tuiFk(K&{M3D&`@3)q>V8nKWVo;8dn)F)=RWeiQS|#d_qBYF zy6=Gd(cV>XA5%4n^B*eTeU+yU#)fl%W2o}Lhou2#+{tx?Ie*_?&kNx-v!34*=J;-f z5(QtavuWTvo6gO7Uu1d_IWi!R_(0Q_rIPcj>*=_!ZID6MHhfvuHOwdh@B>H3m64Dh zZl;)@F<(Yg%m@69m`~+SlN?{$Mdl3p(|rE|$CrMU zewMj2`IuH4vFGs>?#jQrrH>>bQ#{f^afWyHW<%g$jRNzjN-(X(Gzg2#Rh-}sH(oL*FJP5n|Ly5&NzUt*ni#QAjw?i(6sk`0Yt zk&R7WMSP!Aj*S0K_75$TWWJ}kpLDGUb%msAJ*@NE*LoQ9CsXUu^F2N0kD99M{=sR) z{wK})_k%b>0!@iTeiNPV6@|eN8qs%Pf8^vr5cpXzsAWDc5?a`&yk(ao@hq zn_R8O9P>M_^Qu~p&V67%wX*2k2lg|5#(nI+$f4Q4%JDTFW#i`~!3Q&a6V;Ca0E zpf@xB>1U`n`C#-t{Cy7?&*h%*AJs6kXQWro)BDEe6#qWi#jkfR@$c&<+xq9h9C%Lx z2IrT+VFhKE=O?mz?ZA$MjKlWSAHkZmnrM|=mZr_RIQQ|EQg z>;7JGexrdqvESVMb@6TS2Kq#^Nz9mUW&iLmwfdgD?&~q1s`KhGpW{03gQ@jIO|Bq1 z_u=<7?pL*NKX!HvIkKRR9NRpYwE*H@21X5_4|anQ8}c+QHqHSan{kHn0h|N;ZE8Nx zqa=*yl%x-MJIgcG7k0`r_t2D_@q315m5p6rmrdQW$mSl|#IIKl+0w^Vw)T5lwhee! zb_~iV0Yg5351FAuVNB5p`;v`Qd+Lg@(`I@OrjARsu<7e@4_PeUat44e2+2T!Rc1+$AbH@ zbAFS;T+WaGOg1-rO^fkta5s2Q&Tnr1hQ@n8V&5vO zY-#nT<^%lOWRtn4KC56O9bjVE!P_kq`X#wV`zFyB)#AM-xye(anY!2WkRJg=r4 zU)5UnEb69e0UT?NJ24<0#D+Mf)u!eF=b7>a)Pp=Qo&)EiMH4E2^>WQ^L*LpEF$(^+ z8??G@I$6^$y{zq!LDqGIf9?#9cF8OoH6QRM=70ko7?QLOgik6h`=*wYLo>?Dt$8Kn z)|_u-cjug%&L_ut4g1z_3UT*u^A>yntX+1j`4z_;C@(?C5B2rE#JX?8eM_y!ah+GM z^*E^WCR6Lt@;$}F+HdaGw;RcqXz)du(JwS7_6w0{Y609uW| z)v&%Z;QAx<`627P54+Z*xPQoo`@kM+!ABPS3H<9y+@{_#Z&-r~7<;n@kb^1)AU+Rc zGy8*#n+IjD6g4q>K0~v0z?$}m*EAiV4@jL3 z>|#EUgbqY{e=qxIRF=58739vsQgUVbSE%=77p3z_abCwhC$P^2?WduiV_+dU>isi% zI`SFod!{gp7Tgx|BNQg754h$s#cf-79ZeP2lQA_*MTkO zd|(jrfmGI$dry5m=30*f-8a>GtlZaQKKlJ53uPqqbw4=q&Dbs7(R#QHJSg@bF zDIZ`>z;QmH>40~6*+0FK9GLZ^M9--v7Zz3$Sz1a?AvWC6A%{iht(*t%4bBtyfX+Jh zfnDB~on74}xbKH@bb57(Kz^8ft;a!6U!qzMxv%&2IIi{RbzV!%hnQc*d}i(+Thc&| zFKr~JHujXw-fdV5P#VA(+zrOMJheGZd;lQ#dQz(O zSh&xakGj9Op6J~FOHM3rA}3cglQUa~%kXwTu@+Do#=MI;7-N73rUAgc*slnxT#h>3xtqw32RCOV@M0FuY z`9Qc)7gG6v(t$$@5JxYrEpf|g$<37&scORZBUwy0x6$ zI!wF=)EfrOsR7Ib^T8gd2H<$w2K+O@y2BoTPk6XGaBwcx&(_u12z`o12= zwI1gC)>;qqy<^DtjxV$4erw?0R!(o|CNUd^uoj^5zyf$~)&L#62mCMQKqc5x82tJD zS}Js)8`lR?s{>!c2NV&m4_I_ynqC*O*MXzU>dT3hf5|DICi2f(<)+^yJ$4J;_(13!|ev8Cn6?3&vBJNi9b_gL#;oi~|U&r#HRRK91+{Z<0*A@IfC-1n%RD82pJu zdzF!+bN-abF(nM{>-TS_)YIpf`>M`s%J&j+za?}Z++PFkuWc`9)_0V1TL+8(%#KR| z3}XP52XZ}-wZMn59)O>5alt&e51()^I)GSETPME%e85%*>S;P~(x;i6TH8u4tZyc_ z*Z(NjmzBmnLLWKgypH`RvJd?|`-Xgq&wVD*<4Vi1dG*l0Th?;_ro%d~rLRZTdQ5d* zV|~w2tw+oEk?%3)XUunMbsJIKKeN8GoZZ}0j&Ji~Z>&Sas3o^omy_6WxK9gOZ_jz+z7O~C68lKp)A2X%<%~if_wfY{w0pMH{hNAUkGa-U z$>{50Ul;p&9MpQubzV!phkT#dGv>45ekVD*p^Kc|)J-nz94DhYSMLQ7m0{m;jd{deSwmN{?u(nR@C?B{V9rzaO#L$81CLNfMo(fAoVAX*$>)Oh>O`YV* z=2nuhzLH#+i~F*GHGRFA^BV33_WL~xW9_)GM2{_jInYp|r&QK^`L+8v*wbg<*JJJJ zV_%Qsd{3|Qs#;InNlt*gK44cDio*IpayoEkeS0~-xrngW5)_@+Ak%OZPC*nMLPuvfT z_(HR&kzY#m=%R9bem(H}7tI%#d-`nhJ)@^j_4U}+c@x)qlH>ll%{}D2Z*RG{XNr83 zH+v-j%{-8`z=zQja?kS$^T4rBFzEn$MUvM6Yp+PEbYM~`*@u3iNG%_zB3eF>tPXU< zn0A#*{=MWM-==bV&G!=Ljr%q1IIm$3+=+eEsIP$k*K%-dF*&iY0oHJTHMkGI|8HtN zX6`fQTh~#}n7QxUOV0cCkxRSA$?TzxhX4?BPl#F%x@Vly`U{u`1!3MWOPp}eI)I+R zl=6X4OI^s34%Be01M77ixZu}aE^qB4*S5kJY^oub7k&$@zmWX~=MNaTE9|4k6p@2t zib{+Z;(>X8!nfDd?%}fMzI|WM5moD1Z1{Z#wH|BC2i@P;Mf3X__x*ayg)M#M;`X6( z)PF2%0Uj`FKpxlwtp(zE4}1gutSiwcgs9qZ;`IUa^_tg-we^7{@&S_$>>2ficK?9Z zH)_^_8I{DM0}J%^ful=p^MNxPbRD?3rH5SJ)>p3X=r6anG?p8yzL(hXMQk`9J({?~ z#sd4X-$)GR+@W#BC^gpv^AcjYCVkkt@++r#eL21_mT_X{ssSj za&g;0xg6{*RlohD20${`0v~!$$o)p8RD%Kh`m`_3!wZyg|)i2ts!61cF>VvN6810G2pc)xRi-vj?M z`LuqnCVB>AwVuIb^8vkgJZ*HKot6(M9f;pCP_FG9DmQ|L%N@VE62A=puQ@MZZsNR- zyN>-~tVbN4h`eBCRrKvN(fYXce%{p7dKmK?bzY;^qvd-WyNMq2Dem{zxPNK;V7VMH zTu$wr5{Du5fSGH7|9U+T$9p6jd_Xb8g5G-HsL}!U4C4L)iw@+({R8H@(EAebfOO!j zy$%EnlIy#M%Z)vwjP)jJJNw+a%1->xfS9iclLToLO?sYw(1AqTuK~aPyCNh zEh8sqR+dw%+MuVWfvK;jk)^Naq&eR+)_835J?g#@^O5`82g&6fLv`-&93k<$M#-g+ z8S#Zaa4U~7W-UqbO85~rd|hr((6K6K7hU} zn|uIk?G_#AiF}}+Tn!j((Sh5c6C@#GirftzBDXgEA*W}RH8`*Hp19Lac$bwE)5=NQ ztRLje>h@UIZIY<3CpEPm-R~>z8-9PMC$JwW@j;{IYS;`}G^X_cj2kt8dEi4?4@?TD zhw(c4#VX+*qNVCyQfpnvssp>V`v+7$fc|jaLo}rv)(9)${sB{6Xd&XWd)0xkiE?+J zx7-aMFA3Y4%jKn2fVYnOapG=Ze{%YFLW`SO5p$p|dODh0xNl$QO65Y!{rLO zA2dp??j9@GLMF=5?UO<P!D&cPmEal%6&~<=+Q{Xf0ZwdtCZwffB3z>9a@%`w)R1q}?!p6#NzlL&Q zQ579~;2t*vxD)$X=r^FvsUl}rVf}G!C+qsIQRhvv)}!e@@;&Ij&VBlQgZsf=avl7? z9x+pPEE?#Iab_Oq2K&!z0It#DwqtNUSKLG789402i~8Rb;Qhq+qXR9Bbz8U1MVFI`M)`_@{|IlEd9Ykih{ zPt$#15AI*veWTQY zF!qfm$_J`R%zUg5XgYxU+;ZwbQV7c%KDhtS-pLyNH})@* zF+J-x#*i}xU>^9y)dJIMy5Rm1SNH%==)lFqI#3zw1NWl?o?2b#_Fm=#Rvoa+f$)iv zu%nG!US3Vdp19A2{|ENx=KUb&=Kmn)SJapDTLxIxcoNrnO|>2)-@Ce7aesnb*SJ4L zZiG*h8PG4p{XtP3?j z-zfWq>~)~GPzSDIeZW!|3Y(|<@!3@lcI3fu>VocFQEM-7gjbvZEt|J z&TC)m(YTLVkA?e)`N;iHo%=V!z2!#4bh){2rd->$AV=7FpQW`H^I#~|2m z_`4znaSxF<`h_l9`-L8?4ybu>ckdXvwY8;OTvAQW&o^)<_6w_Oc5!(vxwxf2YCV1R z^*y7`YhUZJSz%mD*5qEZWmust0KVGO~e{oS&xwzU%@A z8ow6vX=^-so!3(9VZLYKKK;JI{m7Ye>+d;oJ8FR(-#Kdwuwfp^TA)({?qQm2t4EvW?{D~eE#QVfv#eC*kj~4S&_l=lO z<36#UEw}d11^)Bp&Y_j^*YD*j;If~Ho{)Qh=b?QR_-8t_;J4hW&GB)JpNS>jjzj(Gt5i9Ky;b-A*vhFn3-=Q7uKj5@DPt%ot+UY+|lBMiU4 zAKX7MPwqr51pX@|VA%-XC&u-_r=}K|R+9tw5f;NeMBc|&m~{a6;-GKz;uiDz0CixD zB$W>+?9Gn}!Gqt0{pdxK z5VKUSN3A@8@i5;X_Egsa9>mn%&)8P`Ib7bnfof{)3^`65AG)%Tp|gFmdV{CYh_TU zKda-q-C>V?U*Lnl=V2b>^xD?N&^zvZZc}Hu=!c#`^o`org;JvfYA)Q}huAO(Ipx~= zc5~oYiTCY-I^QI{&g+Q#n%`d_cMR^|J+xfz9`=!=yJoM%m?#Z!=7DK2L2&-o)H zyF&+JuUOWJp##D9rURCF5IRb3__dNN%WZwZRlhEBJ#3nx`=)%4G2a1jKU(MhU2;Em zg~;KRaw~Q<|7MKR0B0VU2Kbu~dC9*|l`Go^EWH+Ze>z~91L2e8R$xzw_o;2;3*tAl zlz&vdhgy%8?-|@rIJj8T{kyTtHSCH1-6Lyc>!KlDagJ^?Wb6aQV!S9xN5Wlvu++?jM8SWE*m=fmp@3YV7&Yq!ib&WMPj9*<}ZXy5E zV?LexV(7lYUiSe$60&B@AY7WcFE9nAG_8bdRO^9G4R{2AC-IY9n|=0r@T5A>hrKEJ0KQK> zNC+Jx*EhB>d_fIioN0r(q5tZ&V>@R~$L~0MLXrUCF?gBt;Q14NBMRNxJ7s2S;)J^q zljUXrYL6=z8)6Owk4|z9U`^;Uj_+I#d<=k2;S{uauwrb>tQP~l>fH%X-Y2mC_)hRh zxw^WZ<_m6xj7ee+tdi}Ehcv)%JM+L40C-H^)^q{qk}hh^;KKiePNq+|oRmH=F1WD; zf6E5z2LEjB?r;uV3}3*%8S|gJKkPBVE3HmL^9P&QytE5Kd;;aWdYk_HnR@xocG7s<*86sB=C?CIj!d&}#Ks`tZn;_RV zG{+q1B6m?2R52hQqx~lK!uOpTkajqw^^w&);62_MJ2$N8hM2J{^2lT6xj%mXbp93|KNI@rvCB@;Tc z9?W|Kc#p7id$LEsejdCrvh#0+k8bw#yt#LZ;S;9Gt(}7;A!@GX2hIl1=KovV83R1o zxZ9t-{XAf;H`}iHJ?dTB>9v7A;SO@cgadO>FJ8`CfU_2CKZ5^_eTVa4aGPJgKC)@J z=dEz>V}h74cH5L1xZEfH@5KB!AWM_0a5N8C|Id12UC++vH+AcW=hT0G&bj?}N5Fm_ zun&xV0OY=N9q7M{yZOpE2h=ZO@m$S?r{ij!SLqx9=Lk4Qz&QfW5pa%x za|E0t;2Z(x2slT;IRefRaE^d;1e_z_90BJDI7h%a0?rX|j(~Fnp2883Cvm$`-1e+5 z<>vmS9{iWv;TQ4G9hcmE&h7AX_{Y!X6>Ud*Dssccyx&8Bz2*I$F2xUHpGVQQo-SNB zx9)QXn|lAQzU#tY;by;o$L@W#|BU`|o{F|5wSUQY-^KX6{r+LQ_wD!n)cZa31K98P zw0qyOUtIsZdfUbEzPel&<9*BN836cMzMq@NvwmEE-}-SK0L!oIfT+RZK?u-cJ~1`| zpq}#)`{s{x-*j~C{ln(Z12DgP+_(8Y0JGm$SZasG`=+bKOE}-2+B?QScGtuA&2PK( zu)QAa+guO!{cJv8-1hJQwc14`2YIf8ns*J`P~>J`SJ&(7({rZvU{| k{tdf*96h`e@BFmVE_OC literal 0 HcmV?d00001 diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..33e703a --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,74 @@ +site_name: 'core-algorithm' +site_author: '熊能' +site_description: '看我七十二变' +site_url: 'https://www.xncoding.com/' +copyright: Copyright © 2020 XiongNeng + +# 源码地址 +#repo_name: 'yidao620c/core-algorithm' +#repo_url: 'https://github.com/yidao620c/core-algorithm' +#edit_uri: 'blob/master/docs/' + +nav: +- Index: index.md +- Documents: + - 第一部分: + - 数据结构: chapters/chapter1/post01.md + - IO操作: chapters/chapter1/post02.md + - 第二部分: + - 多线程: chapters/chapter2/post03.md + - 面向对象编程: chapters/chapter2/post04.md + - 网络编程: chapters/chapter2/post05.md + - 备忘录: + - 我爱你: chapters/chapter2/temp/temp01.md + - 买个锤子: chapters/chapter2/temp/temp02.md +- 关于我们: + - About: about.md + +#主题 +theme: + name: 'material' + language: 'zh' # 配置语言 + palette: # 颜色 + primary: 'light blue' + accent: 'indigo' + feature: + tabs: true # 横向导航 + custom_dir: 'docs/resources/' + +markdown_extensions: + - admonition # 提示块 + - footnotes # 脚注 + - meta # 定义元数据,通过文章上下文控制,如disqus + - pymdownx.caret # 下划线上标 + - pymdownx.tilde # 删除线下标 + - pymdownx.critic # 增加删除修改高亮注释,可修饰行内或段落 + - pymdownx.details # 提示块可折叠 + - pymdownx.inlinehilite # 行内代码高亮 + - pymdownx.keys # 键盘快捷键 + - pymdownx.mark # 文本高亮 + - pymdownx.smartsymbols # 符号转换 + - pymdownx.superfences # 代码嵌套在列表里 + - codehilite: # 代码高亮,显示行号 + guess_lang: false + linenums: true + - toc: # 锚点 + permalink: true +# - pymdownx.arithmatex # 数学公式 + - pymdownx.betterem: # 对加粗和斜体更好的检测 + smart_enable: all +# - pymdownx.emoji: # 表情 +# emoji_generator: !!python/name:pymdownx.emoji.to_svg +# - pymdownx.magiclink # 自动识别超链接 + - pymdownx.tasklist: # 复选框checklist + custom_checkbox: true + +# PDF导出插件 +plugins: + - search +# - pdf-export #这个插件还有点问题,没有更新 + +#扩展样式 +extra_css: + - resources/css/extra.css + From 26f0b5937af59760efbb1d80468254392df8aa00 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Sun, 29 Mar 2020 21:54:36 +0800 Subject: [PATCH 08/54] =?UTF-8?q?=E9=87=8D=E5=91=BD=E5=90=8D=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LeeCode/todo.txt | 1 - README.md | 6 +++--- algorithms/__init__.py | 7 +++++++ algorithmsintro/__init__.py | 7 +++++++ .../__init__.py" => algorithmsintro/ch01_basic/__init__.py | 0 .../ch01_basic/at001_math.py | 0 .../ch01_basic/at002_triangle_str.py | 0 .../ch01_basic/at003_duplicate_words.py | 0 .../ch01_basic/at004_binary_add.py | 0 .../ch01_basic/at005_nine_number.py | 0 .../ch01_basic/at008_hornerpoly.py | 0 .../ch01_basic/at010_max_subarr.py | 0 .../ch01_basic/at011_max_subarr2.py | 0 .../ch01_basic/at011_max_subarr3.py | 0 .../ch01_basic/at012_code_funny.py | 0 .../ch01_basic/at013_rand_permute.py | 0 .../ch01_basic/at014_right_shift.py | 0 .../ch01_basic/at015_sin_cpu.py | 0 .../ch01_basic/at016_bestsinger.py | 0 .../ch01_basic/at017_bracket_match.py | 0 .../__init__.py" => algorithmsintro/ch02_sort/__init__.py | 0 .../ch02_sort/at103_insert_sort.py | 0 .../ch02_sort/at105_select_sort.py | 0 .../ch02_sort/at106_merge_sort.py | 0 .../ch02_sort/at107_merge_sort2.py | 0 .../ch02_sort/at109_bubble_sort.py | 0 .../ch02_sort/at200_heap_sort.py | 0 .../ch02_sort/at203_quick_sort.py | 0 .../ch02_sort/at204_count_sort.py | 0 .../ch02_sort/at205_radix_sort.py | 0 .../ch02_sort/at206_bucket_sort.py | 2 +- .../ch02_sort/at207_find_minmax.py | 0 .../ch02_sort/at208_imin_select.py | 0 .../ch02_sort/at209_imin_select2.py | 2 +- .../ch02_sort/at210_imin_list.py | 0 .../ch02_sort/at211_prior_queue.py | 2 +- .../ch03_datastruct/__init__.py | 0 .../ch03_datastruct/at300_basic.py | 0 .../ch03_datastruct/at301_bisearch_tree.py | 0 .../ch03_datastruct/at302_redblack_tree.py | 0 .../ch03_datastruct/at303_circle_queue.py | 0 .../ch03_datastruct/redblack.cpp | 0 .../ch04_dynamic/__init__.py | 0 .../ch04_dynamic/at400_cut_steel.py | 0 .../ch04_dynamic/at401_fibonacci.py | 0 .../ch04_dynamic/at402_matrix_chain.py | 0 .../ch04_dynamic/at403_elevator.py | 0 .../ch04_dynamic/at404_lcs.py | 0 .../ch05_greedy/__init__.py | 0 .../files/names.txt" => algorithmsintro/files/names.txt | 0 leecode/__init__.py | 6 ++++++ .../todo.txt" | 1 - "\347\256\227\346\263\225/todo.txt" | 1 - 53 files changed, 26 insertions(+), 9 deletions(-) delete mode 100644 LeeCode/todo.txt create mode 100644 algorithms/__init__.py create mode 100644 algorithmsintro/__init__.py rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/__init__.py" => algorithmsintro/ch01_basic/__init__.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at001_math.py" => algorithmsintro/ch01_basic/at001_math.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at002_triangle_str.py" => algorithmsintro/ch01_basic/at002_triangle_str.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at003_duplicate_words.py" => algorithmsintro/ch01_basic/at003_duplicate_words.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at004_binary_add.py" => algorithmsintro/ch01_basic/at004_binary_add.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at005_nine_number.py" => algorithmsintro/ch01_basic/at005_nine_number.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at008_hornerpoly.py" => algorithmsintro/ch01_basic/at008_hornerpoly.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at010_max_subarr.py" => algorithmsintro/ch01_basic/at010_max_subarr.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at011_max_subarr2.py" => algorithmsintro/ch01_basic/at011_max_subarr2.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at011_max_subarr3.py" => algorithmsintro/ch01_basic/at011_max_subarr3.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at012_code_funny.py" => algorithmsintro/ch01_basic/at012_code_funny.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at013_rand_permute.py" => algorithmsintro/ch01_basic/at013_rand_permute.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at014_right_shift.py" => algorithmsintro/ch01_basic/at014_right_shift.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at015_sin_cpu.py" => algorithmsintro/ch01_basic/at015_sin_cpu.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at016_bestsinger.py" => algorithmsintro/ch01_basic/at016_bestsinger.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at017_bracket_match.py" => algorithmsintro/ch01_basic/at017_bracket_match.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/__init__.py" => algorithmsintro/ch02_sort/__init__.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at103_insert_sort.py" => algorithmsintro/ch02_sort/at103_insert_sort.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at105_select_sort.py" => algorithmsintro/ch02_sort/at105_select_sort.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at106_merge_sort.py" => algorithmsintro/ch02_sort/at106_merge_sort.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at107_merge_sort2.py" => algorithmsintro/ch02_sort/at107_merge_sort2.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at109_bubble_sort.py" => algorithmsintro/ch02_sort/at109_bubble_sort.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at200_heap_sort.py" => algorithmsintro/ch02_sort/at200_heap_sort.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at203_quick_sort.py" => algorithmsintro/ch02_sort/at203_quick_sort.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at204_count_sort.py" => algorithmsintro/ch02_sort/at204_count_sort.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at205_radix_sort.py" => algorithmsintro/ch02_sort/at205_radix_sort.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at206_bucket_sort.py" => algorithmsintro/ch02_sort/at206_bucket_sort.py (95%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at207_find_minmax.py" => algorithmsintro/ch02_sort/at207_find_minmax.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at208_imin_select.py" => algorithmsintro/ch02_sort/at208_imin_select.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at209_imin_select2.py" => algorithmsintro/ch02_sort/at209_imin_select2.py (97%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at210_imin_list.py" => algorithmsintro/ch02_sort/at210_imin_list.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at211_prior_queue.py" => algorithmsintro/ch02_sort/at211_prior_queue.py (98%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/__init__.py" => algorithmsintro/ch03_datastruct/__init__.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/at300_basic.py" => algorithmsintro/ch03_datastruct/at300_basic.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/at301_bisearch_tree.py" => algorithmsintro/ch03_datastruct/at301_bisearch_tree.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/at302_redblack_tree.py" => algorithmsintro/ch03_datastruct/at302_redblack_tree.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/at303_circle_queue.py" => algorithmsintro/ch03_datastruct/at303_circle_queue.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/redblack.cpp" => algorithmsintro/ch03_datastruct/redblack.cpp (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/__init__.py" => algorithmsintro/ch04_dynamic/__init__.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at400_cut_steel.py" => algorithmsintro/ch04_dynamic/at400_cut_steel.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at401_fibonacci.py" => algorithmsintro/ch04_dynamic/at401_fibonacci.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at402_matrix_chain.py" => algorithmsintro/ch04_dynamic/at402_matrix_chain.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at403_elevator.py" => algorithmsintro/ch04_dynamic/at403_elevator.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at404_lcs.py" => algorithmsintro/ch04_dynamic/at404_lcs.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/ch05_greedy/__init__.py" => algorithmsintro/ch05_greedy/__init__.py (100%) rename "\347\256\227\346\263\225\345\257\274\350\256\272/files/names.txt" => algorithmsintro/files/names.txt (100%) create mode 100644 leecode/__init__.py delete mode 100644 "\345\233\276\350\247\243\347\256\227\346\263\225/todo.txt" delete mode 100644 "\347\256\227\346\263\225/todo.txt" diff --git a/LeeCode/todo.txt b/LeeCode/todo.txt deleted file mode 100644 index a459bc2..0000000 --- a/LeeCode/todo.txt +++ /dev/null @@ -1 +0,0 @@ -something \ No newline at end of file diff --git a/README.md b/README.md index 3f56983..a5e67ea 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ ## 算法集锦 - python实现 -参考书籍列表,从易到难的顺序,建议按照顺序阅读: +参考书籍列表,建议按照顺序阅读: -* 《LeeCode算法题库》 -* 《算法图解》 * 《算法》第4版 * 《算法导论》第3版 +* 《算法图解》 +* 《LeeCode算法题库》 ### 作者的话 diff --git a/algorithms/__init__.py b/algorithms/__init__.py new file mode 100644 index 0000000..1b36587 --- /dev/null +++ b/algorithms/__init__.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +""" +《算法》第4版 +使用Python语言重写所有算法逻辑 +""" + diff --git a/algorithmsintro/__init__.py b/algorithmsintro/__init__.py new file mode 100644 index 0000000..033682e --- /dev/null +++ b/algorithmsintro/__init__.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +""" +《算法导论》第3版 +使用Python语言重写所有算法逻辑 +""" + diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/__init__.py" b/algorithmsintro/ch01_basic/__init__.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/__init__.py" rename to algorithmsintro/ch01_basic/__init__.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at001_math.py" b/algorithmsintro/ch01_basic/at001_math.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at001_math.py" rename to algorithmsintro/ch01_basic/at001_math.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at002_triangle_str.py" b/algorithmsintro/ch01_basic/at002_triangle_str.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at002_triangle_str.py" rename to algorithmsintro/ch01_basic/at002_triangle_str.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at003_duplicate_words.py" b/algorithmsintro/ch01_basic/at003_duplicate_words.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at003_duplicate_words.py" rename to algorithmsintro/ch01_basic/at003_duplicate_words.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at004_binary_add.py" b/algorithmsintro/ch01_basic/at004_binary_add.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at004_binary_add.py" rename to algorithmsintro/ch01_basic/at004_binary_add.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at005_nine_number.py" b/algorithmsintro/ch01_basic/at005_nine_number.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at005_nine_number.py" rename to algorithmsintro/ch01_basic/at005_nine_number.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at008_hornerpoly.py" b/algorithmsintro/ch01_basic/at008_hornerpoly.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at008_hornerpoly.py" rename to algorithmsintro/ch01_basic/at008_hornerpoly.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at010_max_subarr.py" b/algorithmsintro/ch01_basic/at010_max_subarr.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at010_max_subarr.py" rename to algorithmsintro/ch01_basic/at010_max_subarr.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at011_max_subarr2.py" b/algorithmsintro/ch01_basic/at011_max_subarr2.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at011_max_subarr2.py" rename to algorithmsintro/ch01_basic/at011_max_subarr2.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at011_max_subarr3.py" b/algorithmsintro/ch01_basic/at011_max_subarr3.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at011_max_subarr3.py" rename to algorithmsintro/ch01_basic/at011_max_subarr3.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at012_code_funny.py" b/algorithmsintro/ch01_basic/at012_code_funny.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at012_code_funny.py" rename to algorithmsintro/ch01_basic/at012_code_funny.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at013_rand_permute.py" b/algorithmsintro/ch01_basic/at013_rand_permute.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at013_rand_permute.py" rename to algorithmsintro/ch01_basic/at013_rand_permute.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at014_right_shift.py" b/algorithmsintro/ch01_basic/at014_right_shift.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at014_right_shift.py" rename to algorithmsintro/ch01_basic/at014_right_shift.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at015_sin_cpu.py" b/algorithmsintro/ch01_basic/at015_sin_cpu.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at015_sin_cpu.py" rename to algorithmsintro/ch01_basic/at015_sin_cpu.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at016_bestsinger.py" b/algorithmsintro/ch01_basic/at016_bestsinger.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at016_bestsinger.py" rename to algorithmsintro/ch01_basic/at016_bestsinger.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at017_bracket_match.py" b/algorithmsintro/ch01_basic/at017_bracket_match.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch01_basic/at017_bracket_match.py" rename to algorithmsintro/ch01_basic/at017_bracket_match.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/__init__.py" b/algorithmsintro/ch02_sort/__init__.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/__init__.py" rename to algorithmsintro/ch02_sort/__init__.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at103_insert_sort.py" b/algorithmsintro/ch02_sort/at103_insert_sort.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at103_insert_sort.py" rename to algorithmsintro/ch02_sort/at103_insert_sort.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at105_select_sort.py" b/algorithmsintro/ch02_sort/at105_select_sort.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at105_select_sort.py" rename to algorithmsintro/ch02_sort/at105_select_sort.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at106_merge_sort.py" b/algorithmsintro/ch02_sort/at106_merge_sort.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at106_merge_sort.py" rename to algorithmsintro/ch02_sort/at106_merge_sort.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at107_merge_sort2.py" b/algorithmsintro/ch02_sort/at107_merge_sort2.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at107_merge_sort2.py" rename to algorithmsintro/ch02_sort/at107_merge_sort2.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at109_bubble_sort.py" b/algorithmsintro/ch02_sort/at109_bubble_sort.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at109_bubble_sort.py" rename to algorithmsintro/ch02_sort/at109_bubble_sort.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at200_heap_sort.py" b/algorithmsintro/ch02_sort/at200_heap_sort.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at200_heap_sort.py" rename to algorithmsintro/ch02_sort/at200_heap_sort.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at203_quick_sort.py" b/algorithmsintro/ch02_sort/at203_quick_sort.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at203_quick_sort.py" rename to algorithmsintro/ch02_sort/at203_quick_sort.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at204_count_sort.py" b/algorithmsintro/ch02_sort/at204_count_sort.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at204_count_sort.py" rename to algorithmsintro/ch02_sort/at204_count_sort.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at205_radix_sort.py" b/algorithmsintro/ch02_sort/at205_radix_sort.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at205_radix_sort.py" rename to algorithmsintro/ch02_sort/at205_radix_sort.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at206_bucket_sort.py" b/algorithmsintro/ch02_sort/at206_bucket_sort.py similarity index 95% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at206_bucket_sort.py" rename to algorithmsintro/ch02_sort/at206_bucket_sort.py index 4edd233..4b72f5f 100644 --- "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at206_bucket_sort.py" +++ b/algorithmsintro/ch02_sort/at206_bucket_sort.py @@ -11,7 +11,7 @@ """ from math import floor -from 算法导论.ch02_sort import insertSort +from algorithmsintro.ch02_sort import insertSort __author__ = 'Xiong Neng' diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at207_find_minmax.py" b/algorithmsintro/ch02_sort/at207_find_minmax.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at207_find_minmax.py" rename to algorithmsintro/ch02_sort/at207_find_minmax.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at208_imin_select.py" b/algorithmsintro/ch02_sort/at208_imin_select.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at208_imin_select.py" rename to algorithmsintro/ch02_sort/at208_imin_select.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at209_imin_select2.py" b/algorithmsintro/ch02_sort/at209_imin_select2.py similarity index 97% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at209_imin_select2.py" rename to algorithmsintro/ch02_sort/at209_imin_select2.py index 12f8fa9..45b9495 100644 --- "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at209_imin_select2.py" +++ b/algorithmsintro/ch02_sort/at209_imin_select2.py @@ -6,7 +6,7 @@ Desc : 顺序统计量的选择算法(最坏情况下O(n)) 利用中位数的中位数作为pivot划分数组 """ -from 算法导论.ch02_sort import insertSort +from algorithmsintro.ch02_sort import insertSort __author__ = 'Xiong Neng' diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at210_imin_list.py" b/algorithmsintro/ch02_sort/at210_imin_list.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at210_imin_list.py" rename to algorithmsintro/ch02_sort/at210_imin_list.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at211_prior_queue.py" b/algorithmsintro/ch02_sort/at211_prior_queue.py similarity index 98% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at211_prior_queue.py" rename to algorithmsintro/ch02_sort/at211_prior_queue.py index e280b7f..a36dfdb 100644 --- "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch02_sort/at211_prior_queue.py" +++ b/algorithmsintro/ch02_sort/at211_prior_queue.py @@ -5,7 +5,7 @@ Topic: sample Desc : 最大堆实现最大优先级队列 """ -from 算法导论 import ch02_sort as hsort +from algorithmsintro import ch02_sort as hsort __author__ = 'Xiong Neng' diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/__init__.py" b/algorithmsintro/ch03_datastruct/__init__.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/__init__.py" rename to algorithmsintro/ch03_datastruct/__init__.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/at300_basic.py" b/algorithmsintro/ch03_datastruct/at300_basic.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/at300_basic.py" rename to algorithmsintro/ch03_datastruct/at300_basic.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/at301_bisearch_tree.py" b/algorithmsintro/ch03_datastruct/at301_bisearch_tree.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/at301_bisearch_tree.py" rename to algorithmsintro/ch03_datastruct/at301_bisearch_tree.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/at302_redblack_tree.py" b/algorithmsintro/ch03_datastruct/at302_redblack_tree.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/at302_redblack_tree.py" rename to algorithmsintro/ch03_datastruct/at302_redblack_tree.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/at303_circle_queue.py" b/algorithmsintro/ch03_datastruct/at303_circle_queue.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/at303_circle_queue.py" rename to algorithmsintro/ch03_datastruct/at303_circle_queue.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/redblack.cpp" b/algorithmsintro/ch03_datastruct/redblack.cpp similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch03_datastruct/redblack.cpp" rename to algorithmsintro/ch03_datastruct/redblack.cpp diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/__init__.py" b/algorithmsintro/ch04_dynamic/__init__.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/__init__.py" rename to algorithmsintro/ch04_dynamic/__init__.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at400_cut_steel.py" b/algorithmsintro/ch04_dynamic/at400_cut_steel.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at400_cut_steel.py" rename to algorithmsintro/ch04_dynamic/at400_cut_steel.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at401_fibonacci.py" b/algorithmsintro/ch04_dynamic/at401_fibonacci.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at401_fibonacci.py" rename to algorithmsintro/ch04_dynamic/at401_fibonacci.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at402_matrix_chain.py" b/algorithmsintro/ch04_dynamic/at402_matrix_chain.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at402_matrix_chain.py" rename to algorithmsintro/ch04_dynamic/at402_matrix_chain.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at403_elevator.py" b/algorithmsintro/ch04_dynamic/at403_elevator.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at403_elevator.py" rename to algorithmsintro/ch04_dynamic/at403_elevator.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at404_lcs.py" b/algorithmsintro/ch04_dynamic/at404_lcs.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch04_dynamic/at404_lcs.py" rename to algorithmsintro/ch04_dynamic/at404_lcs.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/ch05_greedy/__init__.py" b/algorithmsintro/ch05_greedy/__init__.py similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/ch05_greedy/__init__.py" rename to algorithmsintro/ch05_greedy/__init__.py diff --git "a/\347\256\227\346\263\225\345\257\274\350\256\272/files/names.txt" b/algorithmsintro/files/names.txt similarity index 100% rename from "\347\256\227\346\263\225\345\257\274\350\256\272/files/names.txt" rename to algorithmsintro/files/names.txt diff --git a/leecode/__init__.py b/leecode/__init__.py new file mode 100644 index 0000000..12f0bb3 --- /dev/null +++ b/leecode/__init__.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +""" +LeeCode算法题库 +""" + diff --git "a/\345\233\276\350\247\243\347\256\227\346\263\225/todo.txt" "b/\345\233\276\350\247\243\347\256\227\346\263\225/todo.txt" deleted file mode 100644 index a459bc2..0000000 --- "a/\345\233\276\350\247\243\347\256\227\346\263\225/todo.txt" +++ /dev/null @@ -1 +0,0 @@ -something \ No newline at end of file diff --git "a/\347\256\227\346\263\225/todo.txt" "b/\347\256\227\346\263\225/todo.txt" deleted file mode 100644 index a459bc2..0000000 --- "a/\347\256\227\346\263\225/todo.txt" +++ /dev/null @@ -1 +0,0 @@ -something \ No newline at end of file From b2d420e839492eefdb36d4fff7ae7d77ea4ef4df Mon Sep 17 00:00:00 2001 From: xiongneng Date: Tue, 5 May 2020 22:02:30 +0800 Subject: [PATCH 09/54] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 19 +- algorithms/__init__.py | 10 +- algorithms/ch01structure/__init__.py | 4 + .../ch01structure/bisearch_tree.py | 9 +- .../ch01structure/circle_queue.py | 6 +- algorithms/ch01structure/prior_queue.py | 103 +++++ algorithms/ch01structure/queue.py | 42 ++ .../ch01structure/redblack_tree.py | 25 +- algorithms/ch01structure/stack.py | 48 +++ algorithms/ch02sort/__init__.py | 5 + .../ch02sort/base}/__init__.py | 2 - algorithms/ch02sort/base/sortutil.py | 16 + algorithms/ch02sort/base/template.py | 39 ++ algorithms/ch02sort/m01_select_sort.py | 28 ++ algorithms/ch02sort/m02_insert_sort.py | 24 ++ algorithms/ch02sort/m03_merge_sort.py | 57 +++ algorithms/ch02sort/m04_merge_insert_sort.py | 73 ++++ algorithms/ch02sort/m05_quick_sort.py | 62 +++ algorithms/ch02sort/m06_heap_sort.py | 57 +++ .../ch02sort/m07_count_sort.py | 4 +- .../ch02sort/m08_radix_sort.py | 7 +- .../ch02sort/m09_bucket_sort.py | 8 +- .../ch02sort/m10_find_minmax.py | 4 +- .../ch02sort/m11_imin_select.py | 1 + .../ch02sort/m12_imin_select2.py | 8 +- .../ch02sort/m13_imin_list.py | 6 +- algorithms/ch03search/__init__.py | 5 + algorithms/ch04graph/__init__.py | 5 + algorithms/ch05string/__init__.py | 5 + algorithms/ch07dynamic/__init__.py | 4 + .../ch07dynamic}/at400_cut_steel.py | 2 +- .../ch07dynamic}/at401_fibonacci.py | 1 - .../ch07dynamic}/at402_matrix_chain.py | 4 +- .../ch07dynamic}/at403_elevator.py | 2 +- .../ch07dynamic}/at404_lcs.py | 5 +- algorithms/ch08greedy/__init__.py | 5 + algorithms/ch09sample/__init__.py | 3 + .../ch09sample/m01_math.py | 0 .../ch09sample/m02_triangle_str.py | 0 .../ch09sample/m03_duplicate_words.py | 0 .../ch09sample/m04_binary_add.py | 0 .../ch09sample/m05_nine_number.py | 0 .../ch09sample/m06_hornerpoly.py | 0 .../ch09sample/m07_max_subarr.py | 2 +- .../ch09sample/m08_max_subarr2.py | 2 +- .../ch09sample/m09_max_subarr3.py | 0 .../ch09sample/m10_code_funny.py | 0 .../ch09sample/m11_rand_permute.py | 0 .../ch09sample/m12_right_shift.py | 0 .../ch09sample/m13_sin_cpu.py | 0 .../ch09sample/m14_bestsinger.py | 0 .../ch09sample/m15_bracket_match.py | 0 algorithmsintro/__init__.py | 7 - algorithmsintro/ch01_basic/__init__.py | 7 - algorithmsintro/ch02_sort/__init__.py | 7 - .../ch02_sort/at103_insert_sort.py | 28 -- .../ch02_sort/at105_select_sort.py | 24 -- algorithmsintro/ch02_sort/at106_merge_sort.py | 59 --- .../ch02_sort/at107_merge_sort2.py | 74 ---- .../ch02_sort/at109_bubble_sort.py | 21 - algorithmsintro/ch02_sort/at200_heap_sort.py | 87 ----- algorithmsintro/ch02_sort/at203_quick_sort.py | 75 ---- .../ch02_sort/at211_prior_queue.py | 120 ------ algorithmsintro/ch03_datastruct/__init__.py | 7 - .../ch03_datastruct/at300_basic.py | 10 - algorithmsintro/ch03_datastruct/redblack.cpp | 366 ------------------ algorithmsintro/ch04_dynamic/__init__.py | 9 - algorithmsintro/files/names.txt | 1 - 68 files changed, 649 insertions(+), 965 deletions(-) create mode 100644 algorithms/ch01structure/__init__.py rename algorithmsintro/ch03_datastruct/at301_bisearch_tree.py => algorithms/ch01structure/bisearch_tree.py (94%) rename algorithmsintro/ch03_datastruct/at303_circle_queue.py => algorithms/ch01structure/circle_queue.py (95%) create mode 100644 algorithms/ch01structure/prior_queue.py create mode 100644 algorithms/ch01structure/queue.py rename algorithmsintro/ch03_datastruct/at302_redblack_tree.py => algorithms/ch01structure/redblack_tree.py (89%) create mode 100644 algorithms/ch01structure/stack.py create mode 100644 algorithms/ch02sort/__init__.py rename {algorithmsintro/ch05_greedy => algorithms/ch02sort/base}/__init__.py (88%) create mode 100644 algorithms/ch02sort/base/sortutil.py create mode 100644 algorithms/ch02sort/base/template.py create mode 100644 algorithms/ch02sort/m01_select_sort.py create mode 100644 algorithms/ch02sort/m02_insert_sort.py create mode 100644 algorithms/ch02sort/m03_merge_sort.py create mode 100644 algorithms/ch02sort/m04_merge_insert_sort.py create mode 100644 algorithms/ch02sort/m05_quick_sort.py create mode 100644 algorithms/ch02sort/m06_heap_sort.py rename algorithmsintro/ch02_sort/at204_count_sort.py => algorithms/ch02sort/m07_count_sort.py (97%) rename algorithmsintro/ch02_sort/at205_radix_sort.py => algorithms/ch02sort/m08_radix_sort.py (86%) rename algorithmsintro/ch02_sort/at206_bucket_sort.py => algorithms/ch02sort/m09_bucket_sort.py (89%) rename algorithmsintro/ch02_sort/at207_find_minmax.py => algorithms/ch02sort/m10_find_minmax.py (92%) rename algorithmsintro/ch02_sort/at208_imin_select.py => algorithms/ch02sort/m11_imin_select.py (99%) rename algorithmsintro/ch02_sort/at209_imin_select2.py => algorithms/ch02sort/m12_imin_select2.py (93%) rename algorithmsintro/ch02_sort/at210_imin_list.py => algorithms/ch02sort/m13_imin_list.py (91%) create mode 100644 algorithms/ch03search/__init__.py create mode 100644 algorithms/ch04graph/__init__.py create mode 100644 algorithms/ch05string/__init__.py create mode 100644 algorithms/ch07dynamic/__init__.py rename {algorithmsintro/ch04_dynamic => algorithms/ch07dynamic}/at400_cut_steel.py (100%) rename {algorithmsintro/ch04_dynamic => algorithms/ch07dynamic}/at401_fibonacci.py (99%) rename {algorithmsintro/ch04_dynamic => algorithms/ch07dynamic}/at402_matrix_chain.py (99%) rename {algorithmsintro/ch04_dynamic => algorithms/ch07dynamic}/at403_elevator.py (98%) rename {algorithmsintro/ch04_dynamic => algorithms/ch07dynamic}/at404_lcs.py (99%) create mode 100644 algorithms/ch08greedy/__init__.py create mode 100644 algorithms/ch09sample/__init__.py rename algorithmsintro/ch01_basic/at001_math.py => algorithms/ch09sample/m01_math.py (100%) rename algorithmsintro/ch01_basic/at002_triangle_str.py => algorithms/ch09sample/m02_triangle_str.py (100%) rename algorithmsintro/ch01_basic/at003_duplicate_words.py => algorithms/ch09sample/m03_duplicate_words.py (100%) rename algorithmsintro/ch01_basic/at004_binary_add.py => algorithms/ch09sample/m04_binary_add.py (100%) rename algorithmsintro/ch01_basic/at005_nine_number.py => algorithms/ch09sample/m05_nine_number.py (100%) rename algorithmsintro/ch01_basic/at008_hornerpoly.py => algorithms/ch09sample/m06_hornerpoly.py (100%) rename algorithmsintro/ch01_basic/at010_max_subarr.py => algorithms/ch09sample/m07_max_subarr.py (98%) rename algorithmsintro/ch01_basic/at011_max_subarr2.py => algorithms/ch09sample/m08_max_subarr2.py (98%) rename algorithmsintro/ch01_basic/at011_max_subarr3.py => algorithms/ch09sample/m09_max_subarr3.py (100%) rename algorithmsintro/ch01_basic/at012_code_funny.py => algorithms/ch09sample/m10_code_funny.py (100%) rename algorithmsintro/ch01_basic/at013_rand_permute.py => algorithms/ch09sample/m11_rand_permute.py (100%) rename algorithmsintro/ch01_basic/at014_right_shift.py => algorithms/ch09sample/m12_right_shift.py (100%) rename algorithmsintro/ch01_basic/at015_sin_cpu.py => algorithms/ch09sample/m13_sin_cpu.py (100%) rename algorithmsintro/ch01_basic/at016_bestsinger.py => algorithms/ch09sample/m14_bestsinger.py (100%) rename algorithmsintro/ch01_basic/at017_bracket_match.py => algorithms/ch09sample/m15_bracket_match.py (100%) delete mode 100644 algorithmsintro/__init__.py delete mode 100644 algorithmsintro/ch01_basic/__init__.py delete mode 100644 algorithmsintro/ch02_sort/__init__.py delete mode 100644 algorithmsintro/ch02_sort/at103_insert_sort.py delete mode 100644 algorithmsintro/ch02_sort/at105_select_sort.py delete mode 100644 algorithmsintro/ch02_sort/at106_merge_sort.py delete mode 100644 algorithmsintro/ch02_sort/at107_merge_sort2.py delete mode 100644 algorithmsintro/ch02_sort/at109_bubble_sort.py delete mode 100644 algorithmsintro/ch02_sort/at200_heap_sort.py delete mode 100644 algorithmsintro/ch02_sort/at203_quick_sort.py delete mode 100644 algorithmsintro/ch02_sort/at211_prior_queue.py delete mode 100644 algorithmsintro/ch03_datastruct/__init__.py delete mode 100644 algorithmsintro/ch03_datastruct/at300_basic.py delete mode 100644 algorithmsintro/ch03_datastruct/redblack.cpp delete mode 100644 algorithmsintro/ch04_dynamic/__init__.py delete mode 100644 algorithmsintro/files/names.txt diff --git a/README.md b/README.md index a5e67ea..320b595 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,20 @@ -## 算法集锦 - python实现 +## 算法杂货铺 - python3实现 -参考书籍列表,建议按照顺序阅读: +算法参考书籍列表,建议按照顺序阅读: * 《算法》第4版 * 《算法导论》第3版 -* 《算法图解》 * 《LeeCode算法题库》 -### 作者的话 +## 作者的话 -书中所有的算法示例都用python语言实现,并且配有详细的算法原理说明,有些复杂算法还会专门写博客来讲解。 +书中经典的算法示例使用python3语言实现,并且配有详细的算法原理说明。 +整个部分分为两个部分,第一个部分是基于`《算法》第4版` + `《算法导论》第3版`这两本书中的所有例子写的。作为基础算法部分。 +第二部分是LeeCode算法题库,选取其中最具代表性的100个算法题来演示。 -自从2016年后好久没更新了,今年2020年开始会继续更新这个系列。 +从2013年就开始写这个系列,写到动态规划后就停了,期间工作太忙根本抽不出时间来写。 +今年2020年决定继续把之前的捡起来,重新更新这个系列,做事情得有始有终,希望能把这个系列坚持写完。 +希望对算法感兴趣的能在杂货铺里挑到自己想要的。 有任何问题都可以联系我: @@ -19,6 +22,10 @@ * Blog: https://www.xncoding.com/ * GitHub: https://github.com/yidao620c +**欢迎关注我的个人公众号“飞污熊”,我会定期分享一些自己的Python学习笔记和心得。** + +![公众号](https://github.com/yidao620c/python3-cookbook/raw/master/exts/wuxiong.jpg) + ## How to Contribute You are welcome to contribute to the project as follow diff --git a/algorithms/__init__.py b/algorithms/__init__.py index 1b36587..b54c107 100644 --- a/algorithms/__init__.py +++ b/algorithms/__init__.py @@ -1,7 +1,13 @@ #!/usr/bin/env python # -*- encoding: utf-8 -*- """ -《算法》第4版 -使用Python语言重写所有算法逻辑 +《算法》第4版 + 《算法导论》第3版 +使用python3语言实现书中经典的算法示例 """ +s = {} +s['1'] = None +s['2'] = None +print(s['1']) + + diff --git a/algorithms/ch01structure/__init__.py b/algorithms/ch01structure/__init__.py new file mode 100644 index 0000000..11beac5 --- /dev/null +++ b/algorithms/ch01structure/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +"""常见的数据结构 +Some of description... +""" diff --git a/algorithmsintro/ch03_datastruct/at301_bisearch_tree.py b/algorithms/ch01structure/bisearch_tree.py similarity index 94% rename from algorithmsintro/ch03_datastruct/at301_bisearch_tree.py rename to algorithms/ch01structure/bisearch_tree.py index 82ebd72..fc8fdce 100644 --- a/algorithmsintro/ch03_datastruct/at301_bisearch_tree.py +++ b/algorithms/ch01structure/bisearch_tree.py @@ -1,12 +1,9 @@ #!/usr/bin/env python # -*- encoding: utf-8 -*- -# 二叉搜索树 """ - Topic: sample - Desc : 二叉搜索树 - 二叉搜索树是指:对每个节点,其左子树元素不大于它,右子树元素不小于它 +Desc : 二叉搜索树 + 二叉搜索树是指:对每个节点,其左子树元素不大于它,右子树元素不小于它 """ -__author__ = 'Xiong Neng' class Tree(): @@ -160,5 +157,3 @@ def transplant(T, u, v): inOrderWalk(tree) treeDelete(tree, n) inOrderWalk(tree) - - diff --git a/algorithmsintro/ch03_datastruct/at303_circle_queue.py b/algorithms/ch01structure/circle_queue.py similarity index 95% rename from algorithmsintro/ch03_datastruct/at303_circle_queue.py rename to algorithms/ch01structure/circle_queue.py index 811c515..55f2d96 100644 --- a/algorithmsintro/ch03_datastruct/at303_circle_queue.py +++ b/algorithms/ch01structure/circle_queue.py @@ -1,13 +1,12 @@ #!/usr/bin/env python # -*- encoding: utf-8 -*- -# Josephus排列 """ +Josephus排列 Topic: n个人围成一圈,从某个指定人开始,沿着环将遇到的每第m个人移出去。 每个人移出去后,继续沿着环将剩下的人按同样规则移出去 默认队列第一个编号为1,以此类推。。。 -Desc : """ -__author__ = 'Xiong Neng' + def circle_out(n, m): # 初始化数组,1表示在队列中,0表示已经出了队列 @@ -31,5 +30,6 @@ def circle_out(n, m): print(result) return result + if __name__ == '__main__': circle_out(7, 3) diff --git a/algorithms/ch01structure/prior_queue.py b/algorithms/ch01structure/prior_queue.py new file mode 100644 index 0000000..ab02a76 --- /dev/null +++ b/algorithms/ch01structure/prior_queue.py @@ -0,0 +1,103 @@ +# -*- encoding: utf-8 -*- +"""基于二叉堆实现的优先队列 +Some of description... +""" +from functools import total_ordering + +from algorithms.ch00structure.stack import Stack + + +class MaxPriorQueue: + """ + 使用一个数组存储二叉堆,所有元素存储在seq[1..max_size]中,se[0]不存储任何东西。 + 优先队列支持插入和删除操作。 + 1. 插入元素放到最后一个,然后向上游到自己的位置。 + 2. 删除元素是移除第一个,然后将最后一个放到第一个,并向下沉到自己的位置。 + """ + + def __init__(self, max_size): + self._seq = [None] * (max_size + 1) # 初始化长度为max_size+1的数组 + self._size = 0 # 元素长度为0 + + def is_empty(self): + """判断队列是否为空""" + return self._size == 0 + + def size(self): + return self._size + + def insert(self, item): + self._size += 1 + self._seq[self._size] = item + self._swim(self._size) # 末端插入元素后向上游,游到自己合适的位置去 + + def del_max(self): + item = self._seq[1] # 根节点拿到最大元素,保留下来后面会作为结果返回 + self._exchange(1, self._size) # 跟最后一个元素做交换 + self._seq[self._size] = None # 清空最后一个元素 + self._size -= 1 # 长度-1 + self._sink(1) # 下沉操作,将第一个元素下沉至合适自己的位置 + return item + + def _less(self, i, j): + """比较两个元素大小,如果左边小于等于右边,返回True""" + if self._seq[i] is None or self._seq[j] is None: + raise IndexError('index error') + return self._seq[i] < self._seq[j] + + def _exchange(self, i, j): + """交换两个元素""" + self._seq[i], self._seq[j] = self._seq[j], self._seq[i] + + def _swim(self, index): + """向上游上去,游到合适的位置""" + while index > 1 and self._less(index // 2, index): + self._exchange(index // 2, index) + index = index // 2 + + def _sink(self, index): + """向下沉下去,把老大的位置叫出来,谁更牛逼谁做老大""" + while 2 * index <= self._size: + j = 2 * index + if j < self._size and self._less(j, j + 1): + j += 1 # 如果有两个下属,把最牛逼的下属拿出来做对比 + if not self._less(index, j): + break # 如果比最牛逼的那个下属还要厉害,说明这个老大位置没问题了 + self._exchange(index, j) # 如果没有下属厉害,就自己乖乖把位置让出来,跟他交换一下 + index = j # 现在index的值修改成新的位置,继续向下做对比,直到找到自己合适的位置 + + +@total_ordering +class Item: + def __init__(self, key, val, index=-1): + self.key = key + self.val = val + self.index = index + + def __eq__(self, other): + return self.key == other.key + + def __lt__(self, other): + return self.key < other.key + + def __str__(self): + return str((self.val, self.key, self.index)) + + +if __name__ == '__main__': + prior_queue = MaxPriorQueue(20) + items = [ + Item(2, "22222"), + Item(5, "55555"), + Item(5, "5===="), + Item(3, "33333"), + Item(9, "99999"), + ] + for item in items: + prior_queue.insert(item) + + stack = Stack() + while not prior_queue.is_empty(): + stack.push(prior_queue.del_max()) + for item in stack: + print(item) diff --git a/algorithms/ch01structure/queue.py b/algorithms/ch01structure/queue.py new file mode 100644 index 0000000..040480f --- /dev/null +++ b/algorithms/ch01structure/queue.py @@ -0,0 +1,42 @@ +# -*- encoding: utf-8 -*- +"""自己实现的一个简单队列 +队尾插入元素,队头取元素。就跟在菜市场排队买菜原理是一样的 +""" +from algorithms.ch00structure.stack import Node + + +class Queue: + def __init__(self): + self.first = None # beginning of queue + self.last = None # end of queue + self.n = 0 # number of elements on queue + + def is_empty(self): + return self.first is None + + def size(self): + return self.n + + def enqueue(self, item): + old_last = self.last + self.last = Node(item) # 将新插入的节点变成队尾元素 + if self.is_empty(): + self.first = self.last + else: + old_last.next = self.last # 同时将原来的队尾元素的next指向新的队尾元素 + + def dequeue(self): + if self.is_empty(): + raise LookupError('Queue underflow') + item = self.first.item + self.first = self.first.next + self.n -= 1 + if self.is_empty(): + # 如果队列现在为空了,说明之前队列中只有一个元素了。 + # 这时候需要把last赋空,防止一直引用着对象,导致无法内存回收 + self.last = None + return item + + def __iter__(self): + while self.n > 0: + yield self.dequeue() diff --git a/algorithmsintro/ch03_datastruct/at302_redblack_tree.py b/algorithms/ch01structure/redblack_tree.py similarity index 89% rename from algorithmsintro/ch03_datastruct/at302_redblack_tree.py rename to algorithms/ch01structure/redblack_tree.py index 993e8b4..056f617 100644 --- a/algorithmsintro/ch03_datastruct/at302_redblack_tree.py +++ b/algorithms/ch01structure/redblack_tree.py @@ -1,20 +1,16 @@ #!/usr/bin/env python # -*- encoding: utf-8 -*- -# 红黑树 """ - Topic: sample - Desc : 红黑树 - 红黑树是满足下面红黑性质的二叉搜索树: - 1,每个结点或者是红色的,或者是黑色的 - 2,根结点黑色 - 3,每个叶子结点(None)是黑色的 - 4,如果一个结点是红色的,则它的两个子结点都是黑色的 - 5,对每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点。 - 一个有n个内部结点的红黑树的高度最多为2lg(n+1) +Desc : 红黑树 + 红黑树是满足下面红黑性质的二叉搜索树: + 1,每个结点或者是红色的,或者是黑色的 + 2,根结点黑色 + 3,每个叶子结点(None)是黑色的 + 4,如果一个结点是红色的,则它的两个子结点都是黑色的 + 5,对每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点。 +一个有n个内部结点的红黑树的高度最多为2lg(n+1) """ -from .at301_bisearch_tree import treeMinimum, inOrderWalk - -__author__ = 'Xiong Neng' +from algorithms.ch01structure.bisearch_tree import treeMinimum class RBTree(): @@ -241,6 +237,7 @@ def inOrderRBWalkNode(node, ni): print(node.key), inOrderRBWalkNode(node.right, ni) + if __name__ == '__main__': ss = [4, 23, 65, 22, 12, 3, 7, 1, 256, 34, 27] tree = RBTree() @@ -251,4 +248,4 @@ def inOrderRBWalkNode(node, ni): rbTreeInsert(tree, n) inOrderRBWalk(tree) rbTreeDelete(tree, n) - inOrderRBWalk(tree) \ No newline at end of file + inOrderRBWalk(tree) diff --git a/algorithms/ch01structure/stack.py b/algorithms/ch01structure/stack.py new file mode 100644 index 0000000..1556a49 --- /dev/null +++ b/algorithms/ch01structure/stack.py @@ -0,0 +1,48 @@ +# -*- encoding: utf-8 -*- +"""自己实现的一个简单栈,内部使用链表方式,同时将这个栈设计成一个可迭代对象。 +可迭代的对象一定不能是自身的迭代器。也就是说,可迭代的对象必须实现`__iter__`方法,但不能实现 `__next__` 方法。 +另一方面,迭代器应该一直可以迭代。迭代器的 `__iter__` 方法应该返回自身。 +一般可使用生成器函数实现更符合python风格的可迭代对象。 +""" + + +class Stack: + def __init__(self): + self.first = None # top of stack + self.n = 0 # size of the stack + + def is_empty(self): + return self.first is None + + def size(self): + return self.n + + def push(self, item): + self.first = Node(item, self.first) + self.n += 1 + + def pop(self): + if self.is_empty(): + raise LookupError('Stack underflow') + result = self.first.item + self.first = self.first.next + self.n -= 1 + return result + + def peek(self): + if self.is_empty(): + raise LookupError('Stack underflow') + return self.first.item + + def __iter__(self): + while self.n > 0: + yield self.pop() + + +class Node: + def __init__(self, item_, next_=None): + self.item = item_ + self.next = next_ + + def __str__(self): + return str(self.item) diff --git a/algorithms/ch02sort/__init__.py b/algorithms/ch02sort/__init__.py new file mode 100644 index 0000000..2edcf76 --- /dev/null +++ b/algorithms/ch02sort/__init__.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +""" +Topic: 各类排序算法 +""" diff --git a/algorithmsintro/ch05_greedy/__init__.py b/algorithms/ch02sort/base/__init__.py similarity index 88% rename from algorithmsintro/ch05_greedy/__init__.py rename to algorithms/ch02sort/base/__init__.py index 0baca96..692a585 100644 --- a/algorithmsintro/ch05_greedy/__init__.py +++ b/algorithms/ch02sort/base/__init__.py @@ -2,6 +2,4 @@ # -*- encoding: utf-8 -*- """ Topic: sample -Desc : """ - diff --git a/algorithms/ch02sort/base/sortutil.py b/algorithms/ch02sort/base/sortutil.py new file mode 100644 index 0000000..86ea247 --- /dev/null +++ b/algorithms/ch02sort/base/sortutil.py @@ -0,0 +1,16 @@ +# -*- encoding: utf-8 -*- +"""将重复的方法抽取出来 +Some of description... +""" + + +def insert_sort(seq_): + """插入排序""" + for j in range(1, len(seq_)): + key = seq_[j] + # insert arrays[j] into the sorted seq[0...j-1] + i = j - 1 + while i >= 0 and key < seq_[i]: + seq_[i + 1] = seq_[i] # element move forward + i -= 1 + seq_[i + 1] = key # at last, put key to right place diff --git a/algorithms/ch02sort/base/template.py b/algorithms/ch02sort/base/template.py new file mode 100644 index 0000000..3e59d2b --- /dev/null +++ b/algorithms/ch02sort/base/template.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +""" +Topic: 排序模板 +""" + + +class SortTemplate: + + def __init__(self, seq): + self.seq = seq + + def sort(self): + """ + 排序方法 + """ + pass + + def less(self, val1, val2): + """ + 对比两个元素,如果从小到大则返回True + """ + return val1 <= val2 + + def show(self, vals): + for val in vals: + print("{}".format(val), end=' ') + print() + + def is_sorted(self, vals): + for i in range(1, len(vals)): + if self.less(vals[i], vals[i - 1]): + return False + return True + + def main(self): + self.sort() + assert self.is_sorted(self.seq) + self.show(self.seq) diff --git a/algorithms/ch02sort/m01_select_sort.py b/algorithms/ch02sort/m01_select_sort.py new file mode 100644 index 0000000..9ce2faf --- /dev/null +++ b/algorithms/ch02sort/m01_select_sort.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +"""选择排序 +1. 找到数组中最小的元素,将其与第一个元素交换位置(如果第一个元素最小,就啥也不做)。 +2. 在剩下的元素中找到最小元素,将其与数组第二个元素交换位置。 +3. 如此反复,直到剩下元素为1个,整个数组排序完。 + +复杂度:O(N^2),大约需要N^2/2次比较和N次交换。 +""" +from algorithms.ch02sort.base.template import SortTemplate + + +class SelectSort(SortTemplate): + + def sort(self): + le = len(self.seq) + for i in range(le - 1): + min_index = i + for j in range(i, le): + if self.seq[min_index] > self.seq[j]: + min_index = j + if i != min_index: + self.seq[i], self.seq[min_index] = self.seq[min_index], self.seq[i] + + +if __name__ == '__main__': + select_sort = SelectSort([4, 2, 5, 1, 6, 3]) + select_sort.main() diff --git a/algorithms/ch02sort/m02_insert_sort.py b/algorithms/ch02sort/m02_insert_sort.py new file mode 100644 index 0000000..011862e --- /dev/null +++ b/algorithms/ch02sort/m02_insert_sort.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +"""插入排序 +索引从1开始往右边遍历,将元素插入到左边已排序好的数组中,索引左边的所有元素都是有序的, +但是它们的最终位置并不确定,为了给更小元素腾出空间,它们可能会被移动。当索引到达最右端的时候,数组排序完成。 + +由于其内层循环非常紧凑,对于小规模的输入,插入排序是一种非常快的原址排序算法。 +注: 如果输入数组中仅有常数个元素需要在排序过程中存储在数组外,则称这种排序算法是原址的。 + +算法复杂度:N^2 +稳定排序:重复元素排序完后仍然保持原来的相对位置。 +""" +from algorithms.ch02sort.base.sortutil import insert_sort +from algorithms.ch02sort.base.template import SortTemplate + + +class InsertSort(SortTemplate): + + def sort(self): + insert_sort(self.seq) + + +if __name__ == '__main__': + select_sort = InsertSort([4, 2, 5, 1, 6, 3]) + select_sort.main() diff --git a/algorithms/ch02sort/m03_merge_sort.py b/algorithms/ch02sort/m03_merge_sort.py new file mode 100644 index 0000000..e872e4a --- /dev/null +++ b/algorithms/ch02sort/m03_merge_sort.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +"""归并排序(分治法) + 归并排序算法完全遵循分治模式,操作如下: + 分解: 分解待排序的n个元素序列成各具n/2个元素的两个子序列 + 解决: 使用归并排序递归的排序两个子序列 + 合并: 合并两个已排序的子序列以产生已排序的答案 + +复杂度:N*lg(N) +稳定排序:重复元素排序完后仍然保持原来的相对位置。 +""" +from algorithms.ch02sort.base.template import SortTemplate + + +class MergeSort(SortTemplate): + + def sort(self): + self.merge_sort_range(0, len(self.seq) - 1) + + def merge_sort_range(self, start, end): + """ + 归并排序一个序列的子序列 + start: 子序列的start下标 + end: 子序列的end下标 + """ + if start < end: # 如果start >= end就终止递归调用 + middle = (start + end) // 2 + self.merge_sort_range(start, middle) # 排好左边的一半 + self.merge_sort_range(middle + 1, end) # 再排好右边的一半 + self.merge_ordered_seq(start, middle, end) # 最后合并排序结果 + + def merge_ordered_seq(self, left, middle, right): + """ + seq: 待排序序列 + left <= middle <= right + 子数组seq[left..middle]和seq[middle+1..right]都是排好序的 + 该排序的时间复杂度为O(n) + """ + temp_seq = [] + i = left + j = middle + 1 + while i <= middle and j <= right: + if self.seq[i] <= self.seq[j]: + temp_seq.append(self.seq[i]) + i += 1 + else: + temp_seq.append(self.seq[j]) + j += 1 + if i <= middle: + temp_seq.extend(self.seq[i:middle + 1]) + else: + temp_seq.extend(self.seq[j:right + 1]) + self.seq[left:right + 1] = temp_seq[:] + + +if __name__ == '__main__': + merge_sort = MergeSort([4, 2, 5, 1, 6, 3]) + merge_sort.main() diff --git a/algorithms/ch02sort/m04_merge_insert_sort.py b/algorithms/ch02sort/m04_merge_insert_sort.py new file mode 100644 index 0000000..47639e3 --- /dev/null +++ b/algorithms/ch02sort/m04_merge_insert_sort.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python +"""归并排序中对小数组采用插入排序 + 纯归并排序的复杂度为: O(nlgn),而纯插入排序的时间复杂度为:O(n^2)。数据量很大的时候采用归并排序 + 但是在n较小的时候插入排序可能运行的会更快点。因此在归并排序中当子问题变得足够小时, + 采用插入排序来使得递归的叶子变粗可以加快排序速度。那么这个足够小到底怎么去衡量呢? 请看下面: + 这么几个我不证明了,比较简单: + A,插入排序最坏情况下可以在O(nk)时间内排序每个长度为k的n/k个子列表 + B,在最坏情况下可在O(nlg(n/k))的时间内合并这些子表 + C,修订后的算法的最坏情况运行时间复杂度是O(nk + nlg(n/k)) + 那么,O(nk+nlg(n/k))=O(nlgn).只能最大是k=O(lgn).等式左边中第一项是高阶项。 + k如果大于lgn,则比归并排序复杂度大了。左边可以写成nk+nlgn-nlgk,k等于lgn时, + 就是2nlgn-nlglgn.忽略恒定系数,则与归并排序是一样的。 + + 最后结论: k < lg(n)的时候,使用插入排序 + +复杂度为: O(nlgn) +稳定排序:重复元素排序完后仍然保持原来的相对位置。 +""" +from math import log + +from algorithms.ch02sort.base.sortutil import insert_sort +from algorithms.ch02sort.base.template import SortTemplate + + +class MergeAndInsertSort(SortTemplate): + + def sort(self): + self.merge_insert_sort_range(0, len(self.seq) - 1, log(len(self.seq), 2)) + + def merge_insert_sort_range(self, start, end, threshold): + """ + 归并排序一个序列的子序列 + start: 子序列的start下标 + end: 子序列的end下标 + threshold: 待排序长度低于这个值,就采用插入排序 + """ + if end - start + 1 < threshold: + temp_seq = self.seq[start: end + 1] + insert_sort(temp_seq) # 小数组使用插入排序 + self.seq[start: end + 1] = temp_seq[:] + elif start < end: # 如果start >= end就终止递归调用 + middle = (start + end) // 2 + self.merge_insert_sort_range(start, middle, threshold) # 排好左边的一半 + self.merge_insert_sort_range(middle + 1, end, threshold) # 再排好右边的一半 + self.merge_insert_sort_seq(start, middle, end) # 最后合并排序结果 + + def merge_insert_sort_seq(self, left, middle, right): + """ + seq: 待排序序列 + left <= middle <= right + 子数组seq[left..middle]和seq[middle+1..right]都是排好序的 + 该排序的时间复杂度为O(n) + """ + temp_seq = [] + i = left + j = middle + 1 + while i <= middle and j <= right: + if self.seq[i] <= self.seq[j]: + temp_seq.append(self.seq[i]) + i += 1 + else: + temp_seq.append(self.seq[j]) + j += 1 + if i <= middle: + temp_seq.extend(self.seq[i:middle + 1]) + else: + temp_seq.extend(self.seq[j:right + 1]) + self.seq[left:right + 1] = temp_seq[:] + + +if __name__ == '__main__': + merge_and_insert_sort = MergeAndInsertSort([4, 2, 5, 1, 6, 3, 7, 9, 8]) + merge_and_insert_sort.main() diff --git a/algorithms/ch02sort/m05_quick_sort.py b/algorithms/ch02sort/m05_quick_sort.py new file mode 100644 index 0000000..2397632 --- /dev/null +++ b/algorithms/ch02sort/m05_quick_sort.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python +"""快速排序 + 采用分治法思想: + 分解: 将数组A[p..r]划分成两个(也可能是空)的子数组A[p..q-1]和A[q+1..r], + 使得左边数组中的元素都小于A[p],而右边数组元素都大于A[p] + 解决: 通过递归调用快速排序,对子数组A[p..q-1]和A[q+1..r]进行排序 + 合并: 原址排序,不需要合并,数组已经排好序了 + + 快速排序的优点: + 最坏情况下时间复杂度为O(n^2),但是期望时间是O(nlg(n)), + 而且O(nlg(n))隐含常数因子非常的小,而且还是原址排序, + 所以实际中使用最多的排序算法就是快速排序 + + 性质T:快速排序是最快的通用排序算法。 +""" +from random import randint + +from algorithms.ch02sort.base.template import SortTemplate + + +class QuickSort(SortTemplate): + + def sort(self): + # self._quick_sub_sort_recursive(seq, 0, len(seq) - 1) + self._quick_sub_sort_tail(0, len(self.seq) - 1) + + def _quick_sub_sort_tail(self, start, end): + """循环版本,模拟尾递归,可以大大减少递归栈深度,而且时间复杂度不变""" + while start < end: + pivot = self._rand_partition(start, end) + if pivot - start < end - pivot: + self._quick_sub_sort_tail(start, pivot - 1) + start = pivot + 1 + else: + self._quick_sub_sort_tail(pivot + 1, end) + end = pivot - 1 + + def _rand_partition(self, start, end): + """分解子数组: 随机化版本""" + pivot = randint(start, end) # 随机的pivot + # 还是将这个pivot放到最后 + self.seq[pivot], self.seq[end] = self.seq[end], self.seq[pivot] + pivot_value = self.seq[end] + i = start - 1 # 以退为进,先初始化为start-1 + for j in range(start, end): + if self.seq[j] <= pivot_value: + i += 1 + self.seq[i], self.seq[j] = self.seq[j], self.seq[i] + self.seq[i + 1], self.seq[end] = self.seq[end], self.seq[i + 1] + return i + 1 + + def _quick_sub_sort_recursive(self, start, end): + """递归版本的""" + if start < end: + q = self._rand_partition(start, end) + self._quick_sub_sort_recursive(start, q - 1) + self._quick_sub_sort_recursive(q + 1, end) + + +if __name__ == '__main__': + quick_sort = QuickSort([9, 7, 8, 10, 16, 3, 14, 2, 1, 4]) + quick_sort.main() diff --git a/algorithms/ch02sort/m06_heap_sort.py b/algorithms/ch02sort/m06_heap_sort.py new file mode 100644 index 0000000..7efc658 --- /dev/null +++ b/algorithms/ch02sort/m06_heap_sort.py @@ -0,0 +1,57 @@ +# -*- encoding: utf-8 -*- +"""使用二叉堆实现堆排序最优雅代码 +原理:如果左右子树都已经是最大堆了,则通过下沉当前根节点操作即可重新构造为一个最大堆。 +""" +from algorithms.ch02sort.base.template import SortTemplate + + +class HeapSort(SortTemplate): + + def __init__(self, seq): + super().__init__(seq) + self._size = len(seq) + + def sort(self): + """最简的堆排序算法""" + # 第一步:首先通过下沉操作构造最大二叉堆 + k = self._size // 2 # 从中间开始往前循环 + while k >= 1: + self._sink(k, self._size) + k -= 1 + + # 第二步:通过每次将堆顶元素跟后面元素交换,堆大小减少1。 + # 然后再下沉堆顶元素重新构造堆,直到堆大小为1 + k = self._size + while k > 1: + self._exchange(1, k) + k -= 1 + self._sink(1, k) + + def _sink(self, index, n): + """向下沉下去,把老大的位置叫出来,谁更牛逼谁做老大""" + while 2 * index <= n: + j = 2 * index + if j < n and self._less(j, j + 1): + j += 1 # 如果有两个下属,把最牛逼的下属拿出来做对比 + if not self._less(index, j): + break # 如果比最牛逼的那个下属还要厉害,说明这个老大位置没问题了 + self._exchange(index, j) # 如果没有下属厉害,就自己乖乖把位置让出来,跟他交换一下 + index = j # 现在index的值修改成新的位置,继续向下做对比,直到找到自己合适的位置 + + def _less(self, i, j): + """ + 比较两个元素大小,如果左边小于等于右边,返回True + 注意,这里索引都减1,用来支持索引值从1开始的序列 + """ + if self.seq[i - 1] is None or self.seq[j - 1] is None: + raise IndexError('index error') + return self.seq[i - 1] < self.seq[j - 1] + + def _exchange(self, i, j): + """交换两个元素,这里索引也都减1""" + self.seq[i - 1], self.seq[j - 1] = self.seq[j - 1], self.seq[i - 1] + + +if __name__ == '__main__': + heap_sort = HeapSort([9, 7, 8, 10, 16, 3, 14, 2, 1, 4]) + heap_sort.main() diff --git a/algorithmsintro/ch02_sort/at204_count_sort.py b/algorithms/ch02sort/m07_count_sort.py similarity index 97% rename from algorithmsintro/ch02_sort/at204_count_sort.py rename to algorithms/ch02sort/m07_count_sort.py index c19b095..29ca3eb 100644 --- a/algorithmsintro/ch02_sort/at204_count_sort.py +++ b/algorithms/ch02sort/m07_count_sort.py @@ -9,7 +9,6 @@ 那么可以用这个计数排序 计数排序是稳定的:原数组中相同元素在输出数组中的次序是一样的 """ -__author__ = 'Xiong Neng' def countSort(A, k, offset=0): @@ -33,6 +32,7 @@ def countSort(A, k, offset=0): if offset > 0: A[:] = [p + offset for p in A] + if __name__ == '__main__': A = [9, 7, 8, 10, 16, 3, 14, 2, 1, 4] countSort(A, 20) @@ -40,4 +40,4 @@ def countSort(A, k, offset=0): A = [9, 7, 8, 10, 16, 3, 14, 2, 1, 4] B = [100 + p for p in A] countSort(B, 30, 96) - print(B) \ No newline at end of file + print(B) diff --git a/algorithmsintro/ch02_sort/at205_radix_sort.py b/algorithms/ch02sort/m08_radix_sort.py similarity index 86% rename from algorithmsintro/ch02_sort/at205_radix_sort.py rename to algorithms/ch02sort/m08_radix_sort.py index 9faf439..d173a26 100644 --- a/algorithmsintro/ch02_sort/at205_radix_sort.py +++ b/algorithms/ch02sort/m08_radix_sort.py @@ -8,7 +8,6 @@ 可以用基数排序,用一种稳定排序算法(比如计数排序)对这些信息进行三次排序: 优先级从低到高,权重从低到高。 """ -__author__ = 'Xiong Neng' def radixSort(A, digit, base): @@ -21,12 +20,12 @@ def radixSort(A, digit, base): C = [0] * base # 临时存储数组 for i in range(0, len(A)): # split the specified digit from the element - tmpSplitDigit = A[i] / pow(10, di - 1) - (A[i] / pow(10, di)) * 10 + tmpSplitDigit = A[i] // pow(10, di - 1) - (A[i] // pow(10, di)) * 10 C[tmpSplitDigit] += 1 # C[i]现在代表数组A中元素等于i的个数 for i in range(1, base): C[i] += C[i - 1] # C[i]现在代表数组A中元素小于等于i的个数 for j in range(len(A) - 1, -1, -1): - tmpSplitDigit = A[j] / pow(10, di - 1) - (A[j] / pow(10, di)) * 10 + tmpSplitDigit = A[j] // pow(10, di - 1) - (A[j] // pow(10, di)) * 10 B[C[tmpSplitDigit] - 1] = A[j] C[tmpSplitDigit] -= 1 # 防止数组A有重复的数,占据了相同的位置 A[:] = B[:] @@ -35,4 +34,4 @@ def radixSort(A, digit, base): if __name__ == '__main__': A = [9, 7, 8, 10, 16, 3, 14, 2, 1, 4] radixSort(A, 2, 10) - print(A) \ No newline at end of file + print(A) diff --git a/algorithmsintro/ch02_sort/at206_bucket_sort.py b/algorithms/ch02sort/m09_bucket_sort.py similarity index 89% rename from algorithmsintro/ch02_sort/at206_bucket_sort.py rename to algorithms/ch02sort/m09_bucket_sort.py index 4b72f5f..15dc8d1 100644 --- a/algorithmsintro/ch02_sort/at206_bucket_sort.py +++ b/algorithms/ch02sort/m09_bucket_sort.py @@ -11,9 +11,7 @@ """ from math import floor -from algorithmsintro.ch02_sort import insertSort - -__author__ = 'Xiong Neng' +from algorithms.ch02sort.base.sortutil import insert_sort def bucketSort(A): @@ -23,7 +21,7 @@ def bucketSort(A): ind = int(floor(n * A[i])) B[ind].append(A[i]) for i in range(0, n): - insertSort(B[i]) + insert_sort(B[i]) res = [] for i in range(0, n): res.extend(B[i]) @@ -35,4 +33,4 @@ def bucketSort(A): BB = [i / 20.0 for i in AA] print(BB) bucketSort(BB) - print(BB) \ No newline at end of file + print(BB) diff --git a/algorithmsintro/ch02_sort/at207_find_minmax.py b/algorithms/ch02sort/m10_find_minmax.py similarity index 92% rename from algorithmsintro/ch02_sort/at207_find_minmax.py rename to algorithms/ch02sort/m10_find_minmax.py index a876883..d5f499e 100644 --- a/algorithmsintro/ch02_sort/at207_find_minmax.py +++ b/algorithms/ch02sort/m10_find_minmax.py @@ -16,9 +16,9 @@ def minMax(A): lastMin, lastMax = (A[0], A[1]) if A[0] < A[1] else (A[1], A[0]) else: lastMin = lastMax = A[0] - for i in range(0, (n + 1)//2-1): + for i in range(0, (n + 1) // 2 - 1): tmp1 = A[2 * i + 1] - tmp2 = A[2*i + 2] + tmp2 = A[2 * i + 2] tmpMin, tmpMax = (tmp1, tmp2) if tmp1 < tmp2 else (tmp2, tmp1) lastMin = lastMin if lastMin < tmpMin else tmpMin lastMax = lastMax if lastMax > tmpMax else tmpMax diff --git a/algorithmsintro/ch02_sort/at208_imin_select.py b/algorithms/ch02sort/m11_imin_select.py similarity index 99% rename from algorithmsintro/ch02_sort/at208_imin_select.py rename to algorithms/ch02sort/m11_imin_select.py index 75a7a00..2685f51 100644 --- a/algorithmsintro/ch02_sort/at208_imin_select.py +++ b/algorithms/ch02sort/m11_imin_select.py @@ -7,6 +7,7 @@ pivot加入了随机特性,算法的期望运行时间是O(n) """ from random import randint + __author__ = 'Xiong Neng' diff --git a/algorithmsintro/ch02_sort/at209_imin_select2.py b/algorithms/ch02sort/m12_imin_select2.py similarity index 93% rename from algorithmsintro/ch02_sort/at209_imin_select2.py rename to algorithms/ch02sort/m12_imin_select2.py index 45b9495..4065d31 100644 --- a/algorithmsintro/ch02_sort/at209_imin_select2.py +++ b/algorithms/ch02sort/m12_imin_select2.py @@ -6,9 +6,7 @@ Desc : 顺序统计量的选择算法(最坏情况下O(n)) 利用中位数的中位数作为pivot划分数组 """ -from algorithmsintro.ch02_sort import insertSort - -__author__ = 'Xiong Neng' +from algorithms.ch02sort.base.sortutil import insert_sort def iminSelect2(A, i): @@ -48,11 +46,11 @@ def __selectMidOfMid(seq): midArr = [] # 每组的中位数列表 for i in range(0, grpNum): eachGroup = seq[i * 5: (i + 1) * 5] - insertSort(eachGroup) + insert_sort(eachGroup) midArr.append(eachGroup[2]) if lastNum > 0: lastGroup = seq[grpNum * 5: grpNum * 5 + lastNum] - insertSort(lastGroup) + insert_sort(lastGroup) midArr.append(lastGroup[(lastNum - 1) // 2]) seq = midArr return seq[0] diff --git a/algorithmsintro/ch02_sort/at210_imin_list.py b/algorithms/ch02sort/m13_imin_list.py similarity index 91% rename from algorithmsintro/ch02_sort/at210_imin_list.py rename to algorithms/ch02sort/m13_imin_list.py index fe219cb..ff17fac 100644 --- a/algorithmsintro/ch02_sort/at210_imin_list.py +++ b/algorithms/ch02sort/m13_imin_list.py @@ -7,9 +7,7 @@ 先通过找到第i小的数,然后将这个数作为pivot去划分这个数组, 左边 + 这个pivot即是解 """ -from .at209_imin_select2 import iminSelect2 - -__author__ = 'Xiong Neng' +from algorithms.ch02sort.m12_imin_select2 import iminSelect2 def iminList(A, i): @@ -39,4 +37,4 @@ def __midPartition(A, p, r, midNum): if __name__ == '__main__': - print(iminList([4, 23, 65, 3, 22, 3, 34, 3, 67, 3, 12, 3, 7, 1, 1, 256, 3, 34, 27], 10)) \ No newline at end of file + print(iminList([4, 23, 65, 3, 22, 3, 34, 3, 67, 3, 12, 3, 7, 1, 1, 256, 3, 34, 27], 10)) diff --git a/algorithms/ch03search/__init__.py b/algorithms/ch03search/__init__.py new file mode 100644 index 0000000..f5c7243 --- /dev/null +++ b/algorithms/ch03search/__init__.py @@ -0,0 +1,5 @@ +# -*- encoding: utf-8 -*- +"""各类查找算法 +Some of description... +""" + diff --git a/algorithms/ch04graph/__init__.py b/algorithms/ch04graph/__init__.py new file mode 100644 index 0000000..f7745a6 --- /dev/null +++ b/algorithms/ch04graph/__init__.py @@ -0,0 +1,5 @@ +# -*- encoding: utf-8 -*- +"""图算法 +Some of description... +""" + diff --git a/algorithms/ch05string/__init__.py b/algorithms/ch05string/__init__.py new file mode 100644 index 0000000..826a90e --- /dev/null +++ b/algorithms/ch05string/__init__.py @@ -0,0 +1,5 @@ +# -*- encoding: utf-8 -*- +"""字符串相关算法 +Some of description... +""" + diff --git a/algorithms/ch07dynamic/__init__.py b/algorithms/ch07dynamic/__init__.py new file mode 100644 index 0000000..1c690ea --- /dev/null +++ b/algorithms/ch07dynamic/__init__.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +"""动态规划 +""" diff --git a/algorithmsintro/ch04_dynamic/at400_cut_steel.py b/algorithms/ch07dynamic/at400_cut_steel.py similarity index 100% rename from algorithmsintro/ch04_dynamic/at400_cut_steel.py rename to algorithms/ch07dynamic/at400_cut_steel.py index 5471c7d..0c3ddd8 100644 --- a/algorithmsintro/ch04_dynamic/at400_cut_steel.py +++ b/algorithms/ch07dynamic/at400_cut_steel.py @@ -35,8 +35,8 @@ def bottom_up_cut_rod(p, n): ans.append([ii] + ans[j - ii]) return r[n], ans[len(ans) - 1] + if __name__ == '__main__': parry = [0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30] for k in range(1, 11): print(bottom_up_cut_rod(parry, k)) - diff --git a/algorithmsintro/ch04_dynamic/at401_fibonacci.py b/algorithms/ch07dynamic/at401_fibonacci.py similarity index 99% rename from algorithmsintro/ch04_dynamic/at401_fibonacci.py rename to algorithms/ch07dynamic/at401_fibonacci.py index 9ffcc27..3b400e9 100644 --- a/algorithmsintro/ch04_dynamic/at401_fibonacci.py +++ b/algorithms/ch07dynamic/at401_fibonacci.py @@ -15,4 +15,3 @@ def dynamic_fibo(n): if __name__ == '__main__': print(dynamic_fibo(10)) - diff --git a/algorithmsintro/ch04_dynamic/at402_matrix_chain.py b/algorithms/ch07dynamic/at402_matrix_chain.py similarity index 99% rename from algorithmsintro/ch04_dynamic/at402_matrix_chain.py rename to algorithms/ch07dynamic/at402_matrix_chain.py index 95ab339..4fd5deb 100644 --- a/algorithmsintro/ch04_dynamic/at402_matrix_chain.py +++ b/algorithms/ch07dynamic/at402_matrix_chain.py @@ -12,6 +12,7 @@ """ + def matrix_order(p): """:param p: 矩阵规模序列,Ai行列分别为p[i-1],p[i]""" INF = float('inf') @@ -38,6 +39,7 @@ def matrix_order(p): print_optimal(s, 0, n - 1) return m, s + def print_optimal(s, i, j): """根据保存的括号位置表打印出最后的括号最优解""" if i == j: @@ -48,7 +50,7 @@ def print_optimal(s, i, j): print_optimal(s, s[i][j] + 1, j) print(')', end='') + if __name__ == '__main__': p = [30, 35, 15, 5, 10, 20, 25] matrix_order(p) - diff --git a/algorithmsintro/ch04_dynamic/at403_elevator.py b/algorithms/ch07dynamic/at403_elevator.py similarity index 98% rename from algorithmsintro/ch04_dynamic/at403_elevator.py rename to algorithms/ch07dynamic/at403_elevator.py index 8945247..0b7eef3 100644 --- a/algorithmsintro/ch04_dynamic/at403_elevator.py +++ b/algorithms/ch07dynamic/at403_elevator.py @@ -44,4 +44,4 @@ def elevatorSchedule(seq): if __name__ == '__main__': s = [0, 0, 2, 4, 5, 7, 2, 1] - print(elevatorSchedule(s)) \ No newline at end of file + print(elevatorSchedule(s)) diff --git a/algorithmsintro/ch04_dynamic/at404_lcs.py b/algorithms/ch07dynamic/at404_lcs.py similarity index 99% rename from algorithmsintro/ch04_dynamic/at404_lcs.py rename to algorithms/ch07dynamic/at404_lcs.py index 61b5eb8..5bdc0ae 100644 --- a/algorithmsintro/ch04_dynamic/at404_lcs.py +++ b/algorithms/ch07dynamic/at404_lcs.py @@ -16,6 +16,7 @@ Desc : """ + def lcs(arr1, arr2): m = len(arr1) n = len(arr2) @@ -38,6 +39,7 @@ def lcs(arr1, arr2): print('一个最优解:%s' % str(rlcs)) return c[m][n], rlcs + def get_lcs_arr(b, X, i, j, arr): if i < 0 or j < 0: return @@ -49,7 +51,8 @@ def get_lcs_arr(b, X, i, j, arr): else: get_lcs_arr(b, X, i, j - 1, arr) + if __name__ == '__main__': x = ['A', 'B', 'D', 'A', 'C', 'K'] y = ['B', 'D', 'D', 'E', 'C', 'K', 'M'] - lcs(x, y) \ No newline at end of file + lcs(x, y) diff --git a/algorithms/ch08greedy/__init__.py b/algorithms/ch08greedy/__init__.py new file mode 100644 index 0000000..73d01c3 --- /dev/null +++ b/algorithms/ch08greedy/__init__.py @@ -0,0 +1,5 @@ +# -*- encoding: utf-8 -*- +"""贪心算法 +Some of description... +""" + diff --git a/algorithms/ch09sample/__init__.py b/algorithms/ch09sample/__init__.py new file mode 100644 index 0000000..1832bfc --- /dev/null +++ b/algorithms/ch09sample/__init__.py @@ -0,0 +1,3 @@ +# -*- encoding: utf-8 -*- +"""一些常见算法示例 +""" diff --git a/algorithmsintro/ch01_basic/at001_math.py b/algorithms/ch09sample/m01_math.py similarity index 100% rename from algorithmsintro/ch01_basic/at001_math.py rename to algorithms/ch09sample/m01_math.py diff --git a/algorithmsintro/ch01_basic/at002_triangle_str.py b/algorithms/ch09sample/m02_triangle_str.py similarity index 100% rename from algorithmsintro/ch01_basic/at002_triangle_str.py rename to algorithms/ch09sample/m02_triangle_str.py diff --git a/algorithmsintro/ch01_basic/at003_duplicate_words.py b/algorithms/ch09sample/m03_duplicate_words.py similarity index 100% rename from algorithmsintro/ch01_basic/at003_duplicate_words.py rename to algorithms/ch09sample/m03_duplicate_words.py diff --git a/algorithmsintro/ch01_basic/at004_binary_add.py b/algorithms/ch09sample/m04_binary_add.py similarity index 100% rename from algorithmsintro/ch01_basic/at004_binary_add.py rename to algorithms/ch09sample/m04_binary_add.py diff --git a/algorithmsintro/ch01_basic/at005_nine_number.py b/algorithms/ch09sample/m05_nine_number.py similarity index 100% rename from algorithmsintro/ch01_basic/at005_nine_number.py rename to algorithms/ch09sample/m05_nine_number.py diff --git a/algorithmsintro/ch01_basic/at008_hornerpoly.py b/algorithms/ch09sample/m06_hornerpoly.py similarity index 100% rename from algorithmsintro/ch01_basic/at008_hornerpoly.py rename to algorithms/ch09sample/m06_hornerpoly.py diff --git a/algorithmsintro/ch01_basic/at010_max_subarr.py b/algorithms/ch09sample/m07_max_subarr.py similarity index 98% rename from algorithmsintro/ch01_basic/at010_max_subarr.py rename to algorithms/ch09sample/m07_max_subarr.py index 565beee..eb6843e 100644 --- a/algorithmsintro/ch01_basic/at010_max_subarr.py +++ b/algorithms/ch09sample/m07_max_subarr.py @@ -22,7 +22,7 @@ def __findMaxSubArr(seq, low, high): if low == high: return low, high, seq[low] else: - mid = (low + high) / 2 + mid = (low + high) // 2 l = lefLow, leftHigh, leftSum = __findMaxSubArr(seq, low, mid) r = rightLow, rightHigh, right_sum = __findMaxSubArr(seq, mid + 1, high) c = crossLow, crossHigh, crossSum = __maxCrossingSubArr(seq, low, mid, high) diff --git a/algorithmsintro/ch01_basic/at011_max_subarr2.py b/algorithms/ch09sample/m08_max_subarr2.py similarity index 98% rename from algorithmsintro/ch01_basic/at011_max_subarr2.py rename to algorithms/ch09sample/m08_max_subarr2.py index 6d54999..d57f7fd 100644 --- a/algorithmsintro/ch01_basic/at011_max_subarr2.py +++ b/algorithms/ch09sample/m08_max_subarr2.py @@ -22,7 +22,7 @@ def __findMaxSubArr(seq, low, high, threshold): elif low == high: return low, high, seq[low] else: - mid = (low + high) / 2 + mid = (low + high) // 2 l = lefLow, leftHigh, leftSum = __findMaxSubArr(seq, low, mid, threshold) r = rightLow, rightHigh, right_sum = __findMaxSubArr(seq, mid + 1, high, threshold) c = crossLow, crossHigh, crossSum = __maxCrossingSubArr(seq, low, mid, high) diff --git a/algorithmsintro/ch01_basic/at011_max_subarr3.py b/algorithms/ch09sample/m09_max_subarr3.py similarity index 100% rename from algorithmsintro/ch01_basic/at011_max_subarr3.py rename to algorithms/ch09sample/m09_max_subarr3.py diff --git a/algorithmsintro/ch01_basic/at012_code_funny.py b/algorithms/ch09sample/m10_code_funny.py similarity index 100% rename from algorithmsintro/ch01_basic/at012_code_funny.py rename to algorithms/ch09sample/m10_code_funny.py diff --git a/algorithmsintro/ch01_basic/at013_rand_permute.py b/algorithms/ch09sample/m11_rand_permute.py similarity index 100% rename from algorithmsintro/ch01_basic/at013_rand_permute.py rename to algorithms/ch09sample/m11_rand_permute.py diff --git a/algorithmsintro/ch01_basic/at014_right_shift.py b/algorithms/ch09sample/m12_right_shift.py similarity index 100% rename from algorithmsintro/ch01_basic/at014_right_shift.py rename to algorithms/ch09sample/m12_right_shift.py diff --git a/algorithmsintro/ch01_basic/at015_sin_cpu.py b/algorithms/ch09sample/m13_sin_cpu.py similarity index 100% rename from algorithmsintro/ch01_basic/at015_sin_cpu.py rename to algorithms/ch09sample/m13_sin_cpu.py diff --git a/algorithmsintro/ch01_basic/at016_bestsinger.py b/algorithms/ch09sample/m14_bestsinger.py similarity index 100% rename from algorithmsintro/ch01_basic/at016_bestsinger.py rename to algorithms/ch09sample/m14_bestsinger.py diff --git a/algorithmsintro/ch01_basic/at017_bracket_match.py b/algorithms/ch09sample/m15_bracket_match.py similarity index 100% rename from algorithmsintro/ch01_basic/at017_bracket_match.py rename to algorithms/ch09sample/m15_bracket_match.py diff --git a/algorithmsintro/__init__.py b/algorithmsintro/__init__.py deleted file mode 100644 index 033682e..0000000 --- a/algorithmsintro/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env python -# -*- encoding: utf-8 -*- -""" -《算法导论》第3版 -使用Python语言重写所有算法逻辑 -""" - diff --git a/algorithmsintro/ch01_basic/__init__.py b/algorithmsintro/ch01_basic/__init__.py deleted file mode 100644 index 0593072..0000000 --- a/algorithmsintro/ch01_basic/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env python -# -*- encoding: utf-8 -*- -""" - Topic: sample - Desc : 算法基础 -""" -__author__ = 'Xiong Neng' diff --git a/algorithmsintro/ch02_sort/__init__.py b/algorithmsintro/ch02_sort/__init__.py deleted file mode 100644 index d5e3647..0000000 --- a/algorithmsintro/ch02_sort/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env python -# -*- encoding: utf-8 -*- -""" - Topic: sample - Desc : 排序和顺序统计量 -""" -__author__ = 'Xiong Neng' diff --git a/algorithmsintro/ch02_sort/at103_insert_sort.py b/algorithmsintro/ch02_sort/at103_insert_sort.py deleted file mode 100644 index 4f1c1e7..0000000 --- a/algorithmsintro/ch02_sort/at103_insert_sort.py +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env python -# -*- encoding: utf-8 -*- -# 插入排序 -""" - Topic: sample - Desc : 插入排序 - 由于其内层循环非常紧凑,对于小规模的输入, - 插入排序是一种非常快的原址排序算法 - 注: 如果输入数组中仅有常数个元素需要在排序过程中存储在数组外, - 则称这种排序算法是原址的。 -""" -__author__ = 'Xiong Neng' - - -def insertSort(seq): - for j in range(1, len(seq)): - key = seq[j] - # insert arrays[j] into the sorted seq[0...j-1] - i = j - 1 - while i >= 0 and seq[i] > key: - seq[i + 1] = seq[i] - i -= 1 - seq[i + 1] = key - -if __name__ == '__main__': - seq = [5, 2, 4, 6, 1, 3] - insertSort(seq) - print(seq) \ No newline at end of file diff --git a/algorithmsintro/ch02_sort/at105_select_sort.py b/algorithmsintro/ch02_sort/at105_select_sort.py deleted file mode 100644 index 188b4c5..0000000 --- a/algorithmsintro/ch02_sort/at105_select_sort.py +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env python -# -*- encoding: utf-8 -*- -# 选择排序 -""" - Topic: sample - Desc : 选择排序 -""" -__author__ = 'Xiong Neng' - - -def selectSort(seq): - le = len(seq) - for i in range(le - 1): - minIndx = i - for j in range(i, le): - if seq[minIndx] > seq[j]: - minIndx = j - if i != minIndx: - seq[i], seq[minIndx] = seq[minIndx], seq[i] - -if __name__ == '__main__': - se = [4, 2, 5, 1, 6, 3] - selectSort(se) - print(se) \ No newline at end of file diff --git a/algorithmsintro/ch02_sort/at106_merge_sort.py b/algorithmsintro/ch02_sort/at106_merge_sort.py deleted file mode 100644 index 3e458b3..0000000 --- a/algorithmsintro/ch02_sort/at106_merge_sort.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env python -# -*- encoding: utf-8 -*- -# 归并排序(分治法) -""" - Topic: sample - Desc : 归并排序 - 归并排序算法完全遵循分治模式,操作如下: - 分解: 分解待排序的n个元素序列成各具n/2个元素的两个子序列 - 解决: 使用归并排序递归的排序两个子序列 - 合并: 合并两个已排序的子序列以产生已排序的答案 -""" -__author__ = 'Xiong Neng' - - -def mergeSort(seq): - mergeSortRange(seq, 0, len(seq) - 1) - - -def mergeOrderedSeq(seq, left, middle, right): - """ - seq: 待排序序列 - left <= middle <= right - 子数组seq[left..middle]和seq[middle+1..right]都是排好序的 - 该排序的时间复杂度为O(n) - """ - tempSeq = [] - i = left - j = middle + 1 - while i <= middle and j <= right: - if seq[i] <= seq[j]: - tempSeq.append(seq[i]) - i += 1 - else: - tempSeq.append(seq[j]) - j += 1 - if i <= middle: - tempSeq.extend(seq[i:middle + 1]) - else: - tempSeq.extend(seq[j:right + 1]) - seq[left:right + 1] = tempSeq[:] - - -def mergeSortRange(seq, start, end): - """ - 归并排序一个序列的子序列 - start: 子序列的start下标 - end: 子序列的end下标 - """ - if start < end: # 如果start >= end就终止递归调用 - middle = (start + end) / 2 - mergeSortRange(seq, start, middle) # 排好左边的一半 - mergeSortRange(seq, middle + 1, end) # 再排好右边的一半 - mergeOrderedSeq(seq, start, middle, end) # 最后合并排序结果 - - -if __name__ == '__main__': - aa = [4, 2, 5, 1, 6, 3, 7, 9, 8] - mergeSort(aa) - print(aa) \ No newline at end of file diff --git a/algorithmsintro/ch02_sort/at107_merge_sort2.py b/algorithmsintro/ch02_sort/at107_merge_sort2.py deleted file mode 100644 index b229258..0000000 --- a/algorithmsintro/ch02_sort/at107_merge_sort2.py +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env python -# -*- encoding: utf-8 -*- -# 归并排序中对小数组采用插入排序 -""" - Topic: sample - Desc : 归并排序中对小数组采用插入排序 - 纯归并排序的复杂度为: O(nlgn),而纯插入排序的时间复杂度为:O(n^2)。数据量很大的时候采用归并排序 - 但是在n较小的时候插入排序可能运行的会更快点。因此在归并排序中当子问题变得足够小时, - 采用插入排序来使得递归的叶子变粗可以加快排序速度。那么这个足够小到底怎么去衡量呢? 请看下面: - 这么几个我不证明了,比较简单: - A,插入排序最坏情况下可以在O(nk)时间内排序每个长度为k的n/k个子列表 - B,在最坏情况下可在O(nlg(n/k))的时间内合并这些子表 - C,修订后的算法的最坏情况运行时间复杂度是O(nk + nlg(n/k)) - 那么,O(nk+nlg(n/k))=O(nlgn).只能最大是k=O(lgn).等式左边中第一项是高阶项。 - k如果大于lgn,则比归并排序复杂度大了。左边可以写成nk+nlgn-nlgk,k等于lgn时, - 就是2nlgn-nlglgn.忽略恒定系数,则与归并排序是一样的。 - 最后结论: k < lg(n)的时候,使用插入排序 -""" -from at003_insertsort import insertSort -from math import log - -__author__ = 'Xiong Neng' - - -def mergeSort(seq): - mergeSortRange(seq, 0, len(seq) - 1, log(len(seq), 2)) - - -def mergeOrderedSeq(seq, left, middle, right): - """ - seq: 待排序序列 - left <= middle <= right - 子数组seq[left..middle]和seq[middle+1..right]都是排好序的 - 该排序的时间复杂度为O(n) - """ - tempSeq = [] - i = left - j = middle + 1 - while i <= middle and j <= right: - if seq[i] <= seq[j]: - tempSeq.append(seq[i]) - i += 1 - else: - tempSeq.append(seq[j]) - j += 1 - if i <= middle: - tempSeq.extend(seq[i:middle + 1]) - else: - tempSeq.extend(seq[j:right + 1]) - seq[left:right + 1] = tempSeq[:] - - -def mergeSortRange(seq, start, end, threshold): - """ - 归并排序一个序列的子序列 - start: 子序列的start下标 - end: 子序列的end下标 - threshold: 待排序长度低于这个值,就采用插入排序 - """ - if end - start + 1 < threshold: - tempSeq = seq[start: end + 1] - insertSort(tempSeq) - seq[start: end + 1] = tempSeq[:] - elif start < end: # 如果start >= end就终止递归调用 - middle = (start + end) / 2 - mergeSortRange(seq, start, middle, threshold) # 排好左边的一半 - mergeSortRange(seq, middle + 1, end, threshold) # 再排好右边的一半 - mergeOrderedSeq(seq, start, middle, end) # 最后合并排序结果 - - -if __name__ == '__main__': - aa = [4, 2, 5, 1, 6, 3, 7, 9, 8] - mergeSort(aa) - print(aa) \ No newline at end of file diff --git a/algorithmsintro/ch02_sort/at109_bubble_sort.py b/algorithmsintro/ch02_sort/at109_bubble_sort.py deleted file mode 100644 index 1b113bc..0000000 --- a/algorithmsintro/ch02_sort/at109_bubble_sort.py +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env python -# -*- encoding: utf-8 -*- -# 冒泡排序 -""" - Topic: sample - Desc : 冒泡排序 -""" -__author__ = 'Xiong Neng' - - -def bubbleSort(seq): - for i in range(len(seq)): - for j in range(len(seq) - 1, i, -1): - if seq[j] < seq[j - 1]: - seq[j - 1], seq[j] = seq[j], seq[j - 1] - - -if __name__ == '__main__': - s = [4, 6, 2, 5, 7, 9, 8, 1] - bubbleSort(s) - print(s) diff --git a/algorithmsintro/ch02_sort/at200_heap_sort.py b/algorithmsintro/ch02_sort/at200_heap_sort.py deleted file mode 100644 index 572c237..0000000 --- a/algorithmsintro/ch02_sort/at200_heap_sort.py +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/env python -# -*- encoding: utf-8 -*- -# 堆排序 -""" - Topic: sample - Desc : 堆排序 - 堆排序的时间复杂度是O(nlg(n)),并且具有空间原址性 - 二叉堆heap是一种数据结构,可用来实现优先队列 - 给定一个节点的下标i(下标从0开始),则其父节点、坐孩子、右孩子坐标: - parent(i) = floor((i+1)/2 - 1) = ((i + 1) >> 1) - 1 - left(i) = 2*i + 1 = (i << 1) + 1 - right(i) = 2*i + 2 = (i + 1) << 1 - - 最小堆定义: 所有i必须满足A[parent(i)] <= A[i] - 最大堆定义: 所有i必须满足A[parent(i)] >= A[i] - - 在堆排序中,我们使用最大堆 - 在优先队列算法中,使用最小堆 -""" -__author__ = 'Xiong Neng' - - -class Heap(): - def __init__(self, seq, heapSize, length): - """ - seq: 存放待排序的序列 - heapSize: 堆的大小 - lenght: 整个序列大小 - """ - self.seq = seq - self.heapSize = heapSize - self.length = length - - -def heapSort(seq): - """ - 堆排序算法 - """ - heap = Heap(seq, len(seq), len(seq)) - __buildMaxHeap(heap) - s = heap.seq - for i in range(heap.length - 1, 0, -1): - s[0], s[i] = s[i], s[0] - heap.heapSize -= 1 - __maxHeapify(heap, 0) - - -def __maxHeapify(heap, i): - """ - 前提是i的两棵子树left(i)和right(i)的二叉树都是最大堆了 - 现在加入i节点后,要保持这个二叉树为最大堆的性质 - heap: Heap数据结构 - """ - seq = heap.seq - slen = heap.heapSize - while True: - left = (i << 1) + 1 - right = (i + 1) << 1 - if left < slen and seq[left] > seq[i]: - largest = left - else: - largest = i - if right < slen and seq[right] > seq[largest]: - largest = right - if largest != i: - seq[largest], seq[i] = seq[i], seq[largest] - i = largest - else: - break - - -def __buildMaxHeap(heap): - """ - 由完全二叉树的性质可知:对于 n/2..n-1为下标的元素,都是叶子节点, - 那么可从下标floor((i+1)/2 - 1)开始往前到0的元素调用maxHeapify - heap: Heap数据结构 - """ - slen = heap.heapSize - for i in range(((slen + 1) >> 1) - 1, -1, -1): - __maxHeapify(heap, i) - - -if __name__ == '__main__': - iSeq = [9, 7, 8, 10, 16, 3, 14, 2, 1, 4] - heapSort(iSeq) - print(iSeq) - diff --git a/algorithmsintro/ch02_sort/at203_quick_sort.py b/algorithmsintro/ch02_sort/at203_quick_sort.py deleted file mode 100644 index 44e8316..0000000 --- a/algorithmsintro/ch02_sort/at203_quick_sort.py +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/env python -# -*- encoding: utf-8 -*- -# 快速排序 -""" - Topic: sample - Desc : 快速排序 - 采用分治法思想: - 分解: 将数组A[p..r]划分成两个(也可能是空)的子数组A[p..q-1]和A[q+1..r], - 使得左边数组中的元素都小于A[p],而右边数组元素都大于A[p] - 解决: 通过递归调用快速排序,对子数组A[p..q-1]和A[q+1..r]进行排序 - 合并: 原址排序,不需要合并,数组已经排好序了 - - 快速排序的优点: - 最坏情况下时间复杂度为O(n^2),但是期望时间是O(nlg(n)), - 而且O(nlg(n))隐含常数因子非常的小,而且还是原址排序, - 所以实际中使用最多的排序算法就是快速排序 -""" -from random import randint -__author__ = 'Xiong Neng' - - -def quickSort(seq): - # __quickSubSort(seq, 0, len(seq) - 1) - __quickSubSortTail(seq, 0, len(seq) - 1) - - -def __partition(A, p, r): - """分解子数组""" - x = A[r] - i = p - 1 - for j in range(p, r): - if A[j] <= x: - i += 1 - A[i], A[j] = A[j], A[i] - A[i + 1], A[r] = A[r], A[i + 1] - return i + 1 - - -def __randPartition(A, p, r): - """分解子数组: 随机化版本""" - rinx = randint(p, r) # 随机的pivot - A[rinx], A[r] = A[r], A[rinx] # 还是将这个pivot放到最后 - x = A[r] - i = p - 1 - for j in range(p, r): - if A[j] <= x: - i += 1 - A[i], A[j] = A[j], A[i] - A[i + 1], A[r] = A[r], A[i + 1] - return i + 1 - - -def __quickSubSort(seq, p, r): - """递归版本的""" - if p < r: - q = __randPartition(seq, p, r) - __quickSubSort(seq, p, q - 1) - __quickSubSort(seq, q + 1, r) - - -def __quickSubSortTail(seq, p, r): - """循环版本,模拟尾递归,可以大大减少递归栈深度,而且时间复杂度不变""" - while p < r: - q = __randPartition(seq, p, r) - if q - p < r - q: - __quickSubSortTail(seq, p, q - 1) - p = q + 1 - else: - __quickSubSortTail(seq, q + 1, r) - r = q - 1 - -if __name__ == '__main__': - s = [9, 7, 8, 10, 16, 3, 14, 2, 1, 4] - quickSort(s) - print(s) diff --git a/algorithmsintro/ch02_sort/at211_prior_queue.py b/algorithmsintro/ch02_sort/at211_prior_queue.py deleted file mode 100644 index a36dfdb..0000000 --- a/algorithmsintro/ch02_sort/at211_prior_queue.py +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env python -# -*- encoding: utf-8 -*- -# 最大堆实现最大优先级队列 -""" - Topic: sample - Desc : 最大堆实现最大优先级队列 -""" -from algorithmsintro import ch02_sort as hsort - -__author__ = 'Xiong Neng' - - -class Item(): - def __init__(self, val, key, index=-1): - self.val = val - self.key = key - self.index = index - - def __cmp__(self, other): - if self.key > other.key: - return 1 - else: - return -1 if self.key < other.key else 0 - - def __str__(self): - return str((self.val, self.key, self.index)) - - -def heapGetMax(heap): - """返回最大优先队列中取最大值""" - return heap.seq[0] - - -def heapPopMax(heap): - """弹出最大优先队列中取最大值并返回这个值""" - if heap.heapSize < 1: - return None - re = heap.seq[0] - heap.seq[0] = heap.seq[heap.heapSize - 1] # 尾上的弄到头上去 - heap.heapSize -= 1 # heap的大小-1 - __maxHeapify(heap, 0) # 然后再次将其构建为最大堆 - return re - - -def heapIncreaseKey(heap, item, newKey): - """增加队列中元素item的key为新的newKey, key <= newKey""" - if newKey < item.key: - return - item.key = newKey - while True: - tmpItem = item - iindex = tmpItem.index - pindex = ((tmpItem.index + 1) >> 1) - 1 - if iindex > 0 and heap.seq[pindex] < tmpItem: - heap.seq[iindex], heap.seq[pindex] = heap.seq[pindex], heap.seq[iindex] - heap.seq[iindex].index, heap.seq[pindex].index = iindex, pindex - else: - break - - -def heapInsert(heap, item): - """最大优先队列中插入一条元素item,将其放入队列到最后一个位置, - 然后调用heapIncreaseKey""" - heap.heapSize += 1 - item.index = heap.heapSize - 1 - heap.seq[heap.heapSize - 1] = item - heapIncreaseKey(heap, item, item.key) - - -def __maxHeapify(heap, i): - """ - 前提是i的两棵子树left(i)和right(i)的二叉树都是最大堆了 - 现在加入i节点后,要保持这个二叉树为最大堆的性质 - heap: Heap数据结构 - """ - seq = heap.seq - slen = heap.heapSize - while True: - left = (i << 1) + 1 - right = (i + 1) << 1 - if left < slen and seq[left] > seq[i]: - largest = left - else: - largest = i - if right < slen and seq[right] > seq[largest]: - largest = right - if largest != i: - seq[largest], seq[i] = seq[i], seq[largest] - seq[largest].index, seq[i].index = seq[i].index, seq[largest].index - i = largest - else: - break - - -def __buildMaxHeap(heap): - """ - 由完全二叉树的性质可知:对于 n/2..n-1为下标的元素,都是叶子节点, - 那么可从下标floor((i+1)/2 - 1)开始往前到0的元素调用maxHeapify - heap: Heap数据结构 - """ - slen = heap.heapSize - for i in range(((slen + 1) >> 1) - 1, -1, -1): - __maxHeapify(heap, i) - for i in range(heap.heapSize): - heap.seq[i].index = i - - -if __name__ == '__main__': - iSeq = [9, 7, 8, 10, 16, 3, 14, 2, 1, 4] - iVal = ['9', '7', '8', '10', '16', '3', '14', '2', '1', '4'] - iVal = [2 * k for k in iVal] - pa = zip(iVal, iSeq) - lastParm = [Item(v, k) for (v, k) in pa] - lastParm.extend([None] * 100) - heap = hsort.Heap(lastParm, len(iSeq), len(lastParm)) - __buildMaxHeap(heap) - print([str(k) for k in heap.seq if k]) - - heapInsert(heap, Item('Love', 13)) - print([str(k) for k in heap.seq if k]) diff --git a/algorithmsintro/ch03_datastruct/__init__.py b/algorithmsintro/ch03_datastruct/__init__.py deleted file mode 100644 index 5de5a86..0000000 --- a/algorithmsintro/ch03_datastruct/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env python -# -*- encoding: utf-8 -*- -""" - Topic: sample - Desc : 数据结构 -""" -__author__ = 'Xiong Neng' diff --git a/algorithmsintro/ch03_datastruct/at300_basic.py b/algorithmsintro/ch03_datastruct/at300_basic.py deleted file mode 100644 index b6221b1..0000000 --- a/algorithmsintro/ch03_datastruct/at300_basic.py +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env python -# -*- encoding: utf-8 -*- -# 基本数据结构 -""" - Topic: sample - Desc : 基本数据结构 -""" -__author__ = 'Xiong Neng' - - diff --git a/algorithmsintro/ch03_datastruct/redblack.cpp b/algorithmsintro/ch03_datastruct/redblack.cpp deleted file mode 100644 index 2e568ab..0000000 --- a/algorithmsintro/ch03_datastruct/redblack.cpp +++ /dev/null @@ -1,366 +0,0 @@ -#include -using namespace std; - -#define BLACK 0 -#define RED 1 - -//红黑树结点结构 -struct node -{ - node *left; - node *right; - node *p; - int key; - bool color; - node(node *init, int k):left(init),right(init),p(init),key(k),color(BLACK){} -}; -//红黑树结构 -class Red_Black_Tree -{ -public: - node *root;//根结点 - node *nil;//哨兵 - Red_Black_Tree(){nil = new node(NULL, -1);root = nil;}; - //13.2旋转 - void Left_Rotate(node *x); - void Right_Rotate(node *x); - //13.3插入 - void RB_Insert_Fixup(node *z); - void RB_Insert(node *z); - //13.4删除 - void RB_Delete_Fixup(node *x); - node *RB_Delete(node *z); - //else - void Print(); - void Print(node *x); - node *RB_Search(node *x, int k); - node *Tree_Successor(node *x); - node *Tree_Minimum(node *x); -}; -//左旋,令y = x->right, 左旋是以x和y之间的链为支轴进行旋转 -//涉及到的结点包括:x,y,y->left,令node={p,l,r},具体变化如下: -//x={x->p,x->left,y}变为{y,x->left,y->left} -//y={x,y->left,y->right}变为{x->p,x,y->right} -//y->left={y,y->left->left,y->left->right}变为{x,y->left->left,y->left->right} -void Red_Black_Tree::Left_Rotate(node *x) -{ - //令y = x->right - node *y = x->right; - //按照上面的方式修改三个结点的指针,注意修改指针的顺序 - x->right = y->left; - if(y->left != nil) - y->left->p = x; - y->p = x->p; - if(x->p == nil)//特殊情况:x是根结点 - root = y; - else if(x == x->p->left) - x->p->left = y; - else - x->p->right = y; - y->left = x; - x->p = y; -} -//右旋,令y = x->left, 左旋是以x和y之间的链为支轴进行旋转 -//旋转过程与上文类似 -void Red_Black_Tree::Right_Rotate(node *x) -{ - node *y = x->left; - x->left = y->right; - if(y->right != nil) - y->right->p = x; - y->p = x->p; - if(x->p == nil) - root = y; - else if(x == x->p->right) - x->p->right = y; - else - x->p->left = y; - y->right = x; - x->p = y; -} -//红黑树调整 -void Red_Black_Tree::RB_Insert_Fixup(node *z) -{ - node *y; - //唯一需要调整的情况,就是违反性质2的时候,如果不违反性质2,调整结束 - while(z->p->color == RED) - { - //p[z]是左孩子时,有三种情况 - if(z->p == z->p->p->left) - { - //令y是z的叔结点 - y = z->p->p->right; - //第一种情况,z的叔叔y是红色的 - if(y->color == RED) - { - //将p[z]和y都着为黑色以解决z和p[z]都是红色的问题 - z->p->color = BLACK; - y->color = BLACK; - //将p[p[z]]着为红色以保持性质5 - z->p->p->color = RED; - //把p[p[z]]当作新增的结点z来重复while循环 - z = z->p->p; - } - else - { - //第二种情况:z的叔叔是黑色的,且z是右孩子 - if(z == z->p->right) - { - //对p[z]左旋,转为第三种情况 - z = z->p; - Left_Rotate(z); - } - //第三种情况:z的叔叔是黑色的,且z是左孩子 - //交换p[z]和p[p[z]]的颜色,并右旋 - z->p->color = BLACK; - z->p->p->color = RED; - Right_Rotate(z->p->p); - } - } - //p[z]是右孩子时,有三种情况,与上面类似 - else if(z->p == z->p->p->right) - { - y = z->p->p->left; - if(y->color == RED) - { - z->p->color = BLACK; - y->color = BLACK; - z->p->p->color = RED; - z = z->p->p; - } - else - { - if(z == z->p->left) - { - z = z->p; - Right_Rotate(z); - } - z->p->color = BLACK; - z->p->p->color = RED; - Left_Rotate(z->p->p); - } - } - } - //根结点置为黑色 - root->color = BLACK; -} -//插入一个结点 -void Red_Black_Tree::RB_Insert(node *z) -{ - node *y = nil, *x = root; - //找到应该插入的位置,与二叉查找树的插入相同 - while(x != nil) - { - y = x; - if(z->key < x->key) - x = x->left; - else - x = x->right; - } - z->p = y; - if(y == nil) - root = z; - else if(z->key < y->key) - y->left = z; - else - y->right = z; - z->left = nil; - z->right = nil; - //将新插入的结点转为红色 - z->color = RED; - //从新插入的结点开始,向上调整 - RB_Insert_Fixup(z); -} -//对树进行调整,x指向一个红黑结点,调整的过程是将额外的黑色沿树上移 -void Red_Black_Tree::RB_Delete_Fixup(node *x) -{ - node *w; - //如果这个额外的黑色在一个根结点或一个红结点上,结点会吸收额外的黑色,成为一个黑色的结点 - while(x != root && x->color == BLACK) - { - //若x是其父的左结点(右结点的情况相对应) - if(x == x->p->left) - { - //令w为x的兄弟,根据w的不同,分为三种情况来处理 - //执行删除操作前x肯定是没有兄弟的,执行删除操作后x肯定是有兄弟的 - w = x->p->right; - //第一种情况:w是红色的 - if(w->color == RED) - { - //改变w和p[x]的颜色 - w->color = BLACK; - x->p->color = RED; - //对p[x]进行一次左旋 - Left_Rotate(x->p); - //令w为x的新兄弟 - w = x->p->right; - //转为2.3.4三种情况之一 - } - //第二情况:w为黑色,w的两个孩子也都是黑色 - if(w->left->color == BLACK && w->right->color == BLACK) - { - //去掉w和x的黑色 - //w只有一层黑色,去掉变为红色,x有多余的一层黑色,去掉后恢复原来颜色 - w->color = RED; - //在p[x]上补一层黑色 - x = x->p; - //现在新x上有个额外的黑色,转入for循环继续处理 - } - //第三种情况,w是黑色的,w->left是红色的,w->right是黑色的 - else - { - if(w->right->color == BLACK) - { - //改变w和left[x]的颜色 - w->left->color = BLACK; - w->color = RED; - //对w进行一次右旋 - Right_Rotate(w); - //令w为x的新兄弟 - w = x->p->right; - //此时转变为第四种情况 - } - //第四种情况:w是黑色的,w->left是黑色的,w->right是红色的 - //修改w和p[x]的颜色 - w->color =x->p->color; - x->p->color = BLACK; - w->right->color = BLACK; - //对p[x]进行一次左旋 - Left_Rotate(x->p); - //此时调整已经结束,将x置为根结点是为了结束循环 - x = root; - } - } - //若x是其父的左结点(右结点的情况相对应) - else if(x == x->p->right) - { - //令w为x的兄弟,根据w的不同,分为三种情况来处理 - //执行删除操作前x肯定是没有兄弟的,执行删除操作后x肯定是有兄弟的 - w = x->p->left; - //第一种情况:w是红色的 - if(w->color == RED) - { - //改变w和p[x]的颜色 - w->color = BLACK; - x->p->color = RED; - //对p[x]进行一次左旋 - Right_Rotate(x->p); - //令w为x的新兄弟 - w = x->p->left; - //转为2.3.4三种情况之一 - } - //第二情况:w为黑色,w的两个孩子也都是黑色 - if(w->right->color == BLACK && w->left->color == BLACK) - { - //去掉w和x的黑色 - //w只有一层黑色,去掉变为红色,x有多余的一层黑色,去掉后恢复原来颜色 - w->color = RED; - //在p[x]上补一层黑色 - x = x->p; - //现在新x上有个额外的黑色,转入for循环继续处理 - } - //第三种情况,w是黑色的,w->right是红色的,w->left是黑色的 - else - { - if(w->left->color == BLACK) - { - //改变w和right[x]的颜色 - w->right->color = BLACK; - w->color = RED; - //对w进行一次右旋 - Left_Rotate(w); - //令w为x的新兄弟 - w = x->p->left; - //此时转变为第四种情况 - } - //第四种情况:w是黑色的,w->right是黑色的,w->left是红色的 - //修改w和p[x]的颜色 - w->color =x->p->color; - x->p->color = BLACK; - w->left->color = BLACK; - //对p[x]进行一次左旋 - Right_Rotate(x->p); - //此时调整已经结束,将x置为根结点是为了结束循环 - x = root; - } - } - } - //吸收了额外的黑色 - x->color = BLACK; -} -//找最小值 -node *Red_Black_Tree::Tree_Minimum(node *x) -{ - //只要有比当前结点小的结点 - while(x->left != nil) - x = x->left; - return x; -} -//查找中序遍历下x结点的后继,后继是大于key[x]的最小的结点 -node *Red_Black_Tree::Tree_Successor(node *x) -{ - //如果有右孩子 - if(x->right != nil) - //右子树中的最小值 - return Tree_Minimum(x->right); - //如果x的右子树为空且x有后继y,那么y是x的最低祖先结点,且y的左儿子也是 - node *y = x->p; - while(y != NULL && x == y->right) - { - x = y; - y = y->p; - } - return y; -} -//递归地查询二叉查找树 -node *Red_Black_Tree::RB_Search(node *x, int k) -{ - //找到叶子结点了还没找到,或当前结点是所查找的结点 - if(x->key == -1 || k == x->key) - return x; - //所查找的结点位于当前结点的左子树 - if(k < x->key) - return RB_Search(x->left, k); - //所查找的结点位于当前结点的左子树 - else - return RB_Search(x->right, k); -} -//红黑树的删除 -node *Red_Black_Tree::RB_Delete(node *z) -{ - //找到结点的位置并删除,这一部分与二叉查找树的删除相同 - node *x, *y; - if(z->left == nil || z->right == nil) - y = z; - else y = Tree_Successor(z); - if(y->left != nil) - x = y->left; - else x = y->right; - x->p = y->p; - if(y->p == nil) - root = x; - else if(y == y->p->left) - y->p->left = x; - else - y->p->right = x; - if(y != z) - z->key = y->key; - //如果被删除的结点是黑色的,则需要调整 - if(y->color == BLACK) - RB_Delete_Fixup(x); - return y; -} -void Red_Black_Tree::Print(node *x) -{ - if(x->key == -1) - return; - Print(x->left); - cout<key<<' '<color<right); -} -void Red_Black_Tree::Print() -{ - Print(root); - cout< Date: Mon, 1 Jun 2020 00:40:21 +0800 Subject: [PATCH 10/54] update --- README.md | 2 +- algorithms/__init__.py | 8 +-- algorithms/ch01structure/__init__.py | 13 +++- algorithms/ch01structure/array_queue.py | 64 +++++++++++++++++++ .../{queue.py => linked_queue.py} | 6 +- algorithms/ch01structure/prior_queue.py | 2 +- .../{stack.py => simple_stack.py} | 9 +-- algorithms/ch02sort/base/template.py | 1 - algorithms/ch09sample/m06_hornerpoly.py | 8 +-- .../m16_circle_queue.py} | 0 10 files changed, 87 insertions(+), 26 deletions(-) create mode 100644 algorithms/ch01structure/array_queue.py rename algorithms/ch01structure/{queue.py => linked_queue.py} (92%) rename algorithms/ch01structure/{stack.py => simple_stack.py} (88%) rename algorithms/{ch01structure/circle_queue.py => ch09sample/m16_circle_queue.py} (100%) diff --git a/README.md b/README.md index 320b595..62abd5b 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ ## 作者的话 书中经典的算法示例使用python3语言实现,并且配有详细的算法原理说明。 -整个部分分为两个部分,第一个部分是基于`《算法》第4版` + `《算法导论》第3版`这两本书中的所有例子写的。作为基础算法部分。 +整个部分分为两个部分,第一个部分是基于`《算法导论》第3版`这两本书中的所有例子写的。作为基础算法部分。 第二部分是LeeCode算法题库,选取其中最具代表性的100个算法题来演示。 从2013年就开始写这个系列,写到动态规划后就停了,期间工作太忙根本抽不出时间来写。 diff --git a/algorithms/__init__.py b/algorithms/__init__.py index b54c107..3af313b 100644 --- a/algorithms/__init__.py +++ b/algorithms/__init__.py @@ -1,13 +1,7 @@ #!/usr/bin/env python # -*- encoding: utf-8 -*- """ -《算法》第4版 + 《算法导论》第3版 -使用python3语言实现书中经典的算法示例 +《算法导论》第3版,使用python3语言实现书中经典的算法示例 """ -s = {} -s['1'] = None -s['2'] = None -print(s['1']) - diff --git a/algorithms/ch01structure/__init__.py b/algorithms/ch01structure/__init__.py index 11beac5..662bbe2 100644 --- a/algorithms/ch01structure/__init__.py +++ b/algorithms/ch01structure/__init__.py @@ -1,4 +1,15 @@ # -*- encoding: utf-8 -*- """常见的数据结构 -Some of description... """ + + +class Node: + """ + 节点信息 + """ + def __init__(self, item_, next_=None): + self.item = item_ + self.next = next_ + + def __str__(self): + return str(self.item) diff --git a/algorithms/ch01structure/array_queue.py b/algorithms/ch01structure/array_queue.py new file mode 100644 index 0000000..4958614 --- /dev/null +++ b/algorithms/ch01structure/array_queue.py @@ -0,0 +1,64 @@ +# -*- encoding: utf-8 -*- +"""基于环形数组实现的一个简单队列 +数组A[1..n]实现最多容纳n-1个元素的队列。 +""" + + +class ArrayQueue: + def __init__(self, size): + self.head = 0 # 队头元素下标 + self.tail = 0 # 下一个插入位置 + self._arr = [None] * size # 实际存放数据的数组 + + def is_empty(self): + return self.head == self.tail + + def is_full(self): + return self.size() == len(self._arr) - 1 + + def size(self): + return (len(self._arr) + self.tail - self.head) % len(self._arr) + + def enqueue(self, item): + # 队列满了则抛出异常 + if self.is_full(): + raise LookupError('Queue is full') + self._arr[self.tail] = item + self.tail = (self.tail + 1) % len(self._arr) + + def dequeue(self): + # 队列空则抛出异常 + if self.is_empty(): + raise LookupError('Queue underflow') + item = self._arr[self.head] + self._arr[self.head] = None + self.head = (self.head + 1) % len(self._arr) + return item + + def __iter__(self): + while not self.is_empty(): + yield self.dequeue() + + +if __name__ == '__main__': + q = ArrayQueue(6) + q.enqueue(1) + q.enqueue(2) + q.enqueue(3) + q.enqueue(4) + q.enqueue(5) + print(q.dequeue()) + print(q.dequeue()) + print(q.dequeue()) + print(q.dequeue()) + print(q.dequeue()) + q.enqueue(1) + q.enqueue(2) + q.enqueue(3) + q.enqueue(4) + q.enqueue(5) + print(q.dequeue()) + print(q.dequeue()) + print(q.dequeue()) + print(q.dequeue()) + print(q.dequeue()) diff --git a/algorithms/ch01structure/queue.py b/algorithms/ch01structure/linked_queue.py similarity index 92% rename from algorithms/ch01structure/queue.py rename to algorithms/ch01structure/linked_queue.py index 040480f..4ff4f16 100644 --- a/algorithms/ch01structure/queue.py +++ b/algorithms/ch01structure/linked_queue.py @@ -1,11 +1,11 @@ # -*- encoding: utf-8 -*- -"""自己实现的一个简单队列 +"""基于链表实现的一个简单队列 队尾插入元素,队头取元素。就跟在菜市场排队买菜原理是一样的 """ -from algorithms.ch00structure.stack import Node +from algorithms.ch01structure import Node -class Queue: +class LinkedQueue: def __init__(self): self.first = None # beginning of queue self.last = None # end of queue diff --git a/algorithms/ch01structure/prior_queue.py b/algorithms/ch01structure/prior_queue.py index ab02a76..dfe8f78 100644 --- a/algorithms/ch01structure/prior_queue.py +++ b/algorithms/ch01structure/prior_queue.py @@ -4,7 +4,7 @@ """ from functools import total_ordering -from algorithms.ch00structure.stack import Stack +from algorithms.ch01structure.simple_stack import Stack class MaxPriorQueue: diff --git a/algorithms/ch01structure/stack.py b/algorithms/ch01structure/simple_stack.py similarity index 88% rename from algorithms/ch01structure/stack.py rename to algorithms/ch01structure/simple_stack.py index 1556a49..42a0138 100644 --- a/algorithms/ch01structure/stack.py +++ b/algorithms/ch01structure/simple_stack.py @@ -4,6 +4,7 @@ 另一方面,迭代器应该一直可以迭代。迭代器的 `__iter__` 方法应该返回自身。 一般可使用生成器函数实现更符合python风格的可迭代对象。 """ +from algorithms.ch01structure import Node class Stack: @@ -38,11 +39,3 @@ def __iter__(self): while self.n > 0: yield self.pop() - -class Node: - def __init__(self, item_, next_=None): - self.item = item_ - self.next = next_ - - def __str__(self): - return str(self.item) diff --git a/algorithms/ch02sort/base/template.py b/algorithms/ch02sort/base/template.py index 3e59d2b..b67f7ca 100644 --- a/algorithms/ch02sort/base/template.py +++ b/algorithms/ch02sort/base/template.py @@ -25,7 +25,6 @@ def less(self, val1, val2): def show(self, vals): for val in vals: print("{}".format(val), end=' ') - print() def is_sorted(self, vals): for i in range(1, len(vals)): diff --git a/algorithms/ch09sample/m06_hornerpoly.py b/algorithms/ch09sample/m06_hornerpoly.py index b3d423f..832cece 100644 --- a/algorithms/ch09sample/m06_hornerpoly.py +++ b/algorithms/ch09sample/m06_hornerpoly.py @@ -9,12 +9,12 @@ __author__ = 'Xiong Neng' -def hornerPoly(coefficientArr, x): +def horner_poly(coefficient_arr, x): res = 0 - for i in range(len(coefficientArr))[-1::-1]: - res = coefficientArr[i] + x * res + for i in range(len(coefficient_arr))[-1::-1]: + res = coefficient_arr[i] + x * res return res if __name__ == '__main__': - print(hornerPoly((1, 2, 3), 2)) + print(horner_poly((1, 2, 3), 2)) diff --git a/algorithms/ch01structure/circle_queue.py b/algorithms/ch09sample/m16_circle_queue.py similarity index 100% rename from algorithms/ch01structure/circle_queue.py rename to algorithms/ch09sample/m16_circle_queue.py From b05c6d0064b306810e21e1f0aa00b78f10bdda95 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Sat, 13 Jun 2020 23:54:50 +0800 Subject: [PATCH 11/54] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- algorithms/ch01structure/__init__.py | 6 ++-- algorithms/ch01structure/queue/__init__.py | 5 +++ .../ch01structure/{ => queue}/array_queue.py | 0 .../ch01structure/{ => queue}/linked_queue.py | 2 +- .../ch01structure/{ => queue}/prior_queue.py | 2 +- algorithms/ch01structure/stack/__init__.py | 5 +++ .../linked_stack.py} | 4 +-- algorithms/ch01structure/tree/__init__.py | 5 +++ .../ch01structure/{ => tree}/bisearch_tree.py | 0 .../ch01structure/{ => tree}/redblack_tree.py | 2 +- algorithms/ch03search/__init__.py | 5 --- .../{ch07dynamic => ch05dynamic}/__init__.py | 0 .../at400_cut_steel.py | 31 ++++++++++--------- .../at401_fibonacci.py | 0 .../at402_matrix_chain.py | 0 .../at403_elevator.py | 0 .../{ch07dynamic => ch05dynamic}/at404_lcs.py | 0 .../{ch08greedy => ch06greedy}/__init__.py | 0 .../{ch04graph => ch10graph}/__init__.py | 0 .../{ch05string => ch20string}/__init__.py | 0 .../{ch09sample => ch30sample}/__init__.py | 0 .../{ch09sample => ch30sample}/m01_math.py | 0 .../m02_triangle_str.py | 0 .../m03_duplicate_words.py | 0 .../m04_binary_add.py | 0 .../m05_nine_number.py | 0 .../m06_hornerpoly.py | 0 .../m07_max_subarr.py | 0 .../m08_max_subarr2.py | 0 .../m09_max_subarr3.py | 0 .../m10_code_funny.py | 0 .../m11_rand_permute.py | 0 .../m12_right_shift.py | 0 .../{ch09sample => ch30sample}/m13_sin_cpu.py | 0 .../m14_bestsinger.py | 0 .../m15_bracket_match.py | 0 .../m16_circle_queue.py | 0 37 files changed, 39 insertions(+), 28 deletions(-) create mode 100644 algorithms/ch01structure/queue/__init__.py rename algorithms/ch01structure/{ => queue}/array_queue.py (100%) rename algorithms/ch01structure/{ => queue}/linked_queue.py (97%) rename algorithms/ch01structure/{ => queue}/prior_queue.py (98%) create mode 100644 algorithms/ch01structure/stack/__init__.py rename algorithms/ch01structure/{simple_stack.py => stack/linked_stack.py} (94%) create mode 100644 algorithms/ch01structure/tree/__init__.py rename algorithms/ch01structure/{ => tree}/bisearch_tree.py (100%) rename algorithms/ch01structure/{ => tree}/redblack_tree.py (98%) delete mode 100644 algorithms/ch03search/__init__.py rename algorithms/{ch07dynamic => ch05dynamic}/__init__.py (100%) rename algorithms/{ch07dynamic => ch05dynamic}/at400_cut_steel.py (61%) rename algorithms/{ch07dynamic => ch05dynamic}/at401_fibonacci.py (100%) rename algorithms/{ch07dynamic => ch05dynamic}/at402_matrix_chain.py (100%) rename algorithms/{ch07dynamic => ch05dynamic}/at403_elevator.py (100%) rename algorithms/{ch07dynamic => ch05dynamic}/at404_lcs.py (100%) rename algorithms/{ch08greedy => ch06greedy}/__init__.py (100%) rename algorithms/{ch04graph => ch10graph}/__init__.py (100%) rename algorithms/{ch05string => ch20string}/__init__.py (100%) rename algorithms/{ch09sample => ch30sample}/__init__.py (100%) rename algorithms/{ch09sample => ch30sample}/m01_math.py (100%) rename algorithms/{ch09sample => ch30sample}/m02_triangle_str.py (100%) rename algorithms/{ch09sample => ch30sample}/m03_duplicate_words.py (100%) rename algorithms/{ch09sample => ch30sample}/m04_binary_add.py (100%) rename algorithms/{ch09sample => ch30sample}/m05_nine_number.py (100%) rename algorithms/{ch09sample => ch30sample}/m06_hornerpoly.py (100%) rename algorithms/{ch09sample => ch30sample}/m07_max_subarr.py (100%) rename algorithms/{ch09sample => ch30sample}/m08_max_subarr2.py (100%) rename algorithms/{ch09sample => ch30sample}/m09_max_subarr3.py (100%) rename algorithms/{ch09sample => ch30sample}/m10_code_funny.py (100%) rename algorithms/{ch09sample => ch30sample}/m11_rand_permute.py (100%) rename algorithms/{ch09sample => ch30sample}/m12_right_shift.py (100%) rename algorithms/{ch09sample => ch30sample}/m13_sin_cpu.py (100%) rename algorithms/{ch09sample => ch30sample}/m14_bestsinger.py (100%) rename algorithms/{ch09sample => ch30sample}/m15_bracket_match.py (100%) rename algorithms/{ch09sample => ch30sample}/m16_circle_queue.py (100%) diff --git a/algorithms/ch01structure/__init__.py b/algorithms/ch01structure/__init__.py index 662bbe2..b9d9d5c 100644 --- a/algorithms/ch01structure/__init__.py +++ b/algorithms/ch01structure/__init__.py @@ -7,9 +7,9 @@ class Node: """ 节点信息 """ - def __init__(self, item_, next_=None): - self.item = item_ + def __init__(self, val_, next_=None): + self.val = val_ self.next = next_ def __str__(self): - return str(self.item) + return str(self.val) diff --git a/algorithms/ch01structure/queue/__init__.py b/algorithms/ch01structure/queue/__init__.py new file mode 100644 index 0000000..dbc8407 --- /dev/null +++ b/algorithms/ch01structure/queue/__init__.py @@ -0,0 +1,5 @@ +# -*- encoding: utf-8 -*- +""" +description... +""" + diff --git a/algorithms/ch01structure/array_queue.py b/algorithms/ch01structure/queue/array_queue.py similarity index 100% rename from algorithms/ch01structure/array_queue.py rename to algorithms/ch01structure/queue/array_queue.py diff --git a/algorithms/ch01structure/linked_queue.py b/algorithms/ch01structure/queue/linked_queue.py similarity index 97% rename from algorithms/ch01structure/linked_queue.py rename to algorithms/ch01structure/queue/linked_queue.py index 4ff4f16..3564dd2 100644 --- a/algorithms/ch01structure/linked_queue.py +++ b/algorithms/ch01structure/queue/linked_queue.py @@ -28,7 +28,7 @@ def enqueue(self, item): def dequeue(self): if self.is_empty(): raise LookupError('Queue underflow') - item = self.first.item + item = self.first.val self.first = self.first.next self.n -= 1 if self.is_empty(): diff --git a/algorithms/ch01structure/prior_queue.py b/algorithms/ch01structure/queue/prior_queue.py similarity index 98% rename from algorithms/ch01structure/prior_queue.py rename to algorithms/ch01structure/queue/prior_queue.py index dfe8f78..22ed2f1 100644 --- a/algorithms/ch01structure/prior_queue.py +++ b/algorithms/ch01structure/queue/prior_queue.py @@ -4,7 +4,7 @@ """ from functools import total_ordering -from algorithms.ch01structure.simple_stack import Stack +from algorithms.ch01structure.stack.linked_stack import Stack class MaxPriorQueue: diff --git a/algorithms/ch01structure/stack/__init__.py b/algorithms/ch01structure/stack/__init__.py new file mode 100644 index 0000000..dbc8407 --- /dev/null +++ b/algorithms/ch01structure/stack/__init__.py @@ -0,0 +1,5 @@ +# -*- encoding: utf-8 -*- +""" +description... +""" + diff --git a/algorithms/ch01structure/simple_stack.py b/algorithms/ch01structure/stack/linked_stack.py similarity index 94% rename from algorithms/ch01structure/simple_stack.py rename to algorithms/ch01structure/stack/linked_stack.py index 42a0138..e258edf 100644 --- a/algorithms/ch01structure/simple_stack.py +++ b/algorithms/ch01structure/stack/linked_stack.py @@ -25,7 +25,7 @@ def push(self, item): def pop(self): if self.is_empty(): raise LookupError('Stack underflow') - result = self.first.item + result = self.first.val self.first = self.first.next self.n -= 1 return result @@ -33,7 +33,7 @@ def pop(self): def peek(self): if self.is_empty(): raise LookupError('Stack underflow') - return self.first.item + return self.first.val def __iter__(self): while self.n > 0: diff --git a/algorithms/ch01structure/tree/__init__.py b/algorithms/ch01structure/tree/__init__.py new file mode 100644 index 0000000..dbc8407 --- /dev/null +++ b/algorithms/ch01structure/tree/__init__.py @@ -0,0 +1,5 @@ +# -*- encoding: utf-8 -*- +""" +description... +""" + diff --git a/algorithms/ch01structure/bisearch_tree.py b/algorithms/ch01structure/tree/bisearch_tree.py similarity index 100% rename from algorithms/ch01structure/bisearch_tree.py rename to algorithms/ch01structure/tree/bisearch_tree.py diff --git a/algorithms/ch01structure/redblack_tree.py b/algorithms/ch01structure/tree/redblack_tree.py similarity index 98% rename from algorithms/ch01structure/redblack_tree.py rename to algorithms/ch01structure/tree/redblack_tree.py index 056f617..289d28c 100644 --- a/algorithms/ch01structure/redblack_tree.py +++ b/algorithms/ch01structure/tree/redblack_tree.py @@ -10,7 +10,7 @@ 5,对每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点。 一个有n个内部结点的红黑树的高度最多为2lg(n+1) """ -from algorithms.ch01structure.bisearch_tree import treeMinimum +from algorithms.ch01structure.tree.bisearch_tree import treeMinimum class RBTree(): diff --git a/algorithms/ch03search/__init__.py b/algorithms/ch03search/__init__.py deleted file mode 100644 index f5c7243..0000000 --- a/algorithms/ch03search/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# -*- encoding: utf-8 -*- -"""各类查找算法 -Some of description... -""" - diff --git a/algorithms/ch07dynamic/__init__.py b/algorithms/ch05dynamic/__init__.py similarity index 100% rename from algorithms/ch07dynamic/__init__.py rename to algorithms/ch05dynamic/__init__.py diff --git a/algorithms/ch07dynamic/at400_cut_steel.py b/algorithms/ch05dynamic/at400_cut_steel.py similarity index 61% rename from algorithms/ch07dynamic/at400_cut_steel.py rename to algorithms/ch05dynamic/at400_cut_steel.py index 0c3ddd8..f2fe004 100644 --- a/algorithms/ch07dynamic/at400_cut_steel.py +++ b/algorithms/ch05dynamic/at400_cut_steel.py @@ -18,25 +18,26 @@ def bottom_up_cut_rod(p, n): param p: 价格数组,长度为i的钢条价格为p[i] param n: 钢条总长度 """ - # 先初始化数组r - r = [0] * (n + 1) - # 用来保存每个最优解二维数组,ans[i]表示长度为i的最优解 - ans = [[]] - for j in range(1, n + 1): - q = -999 + # 先初始化数组r,最优解值数组。r[i]表示长度为i的时候的最优解。 + best_incomes = [0] * (n + 1) + # 用来保存每个最优切割方案二维数组,ans[i]表示长度为i的最优切割方案 + best_solutions = [[]] + for j in range(1, n + 1): # 自顶向上迭代 + max_val = -999 # 下面这个内层循环保证长度为j时候所有情况都考虑到了 # 因为i会从1迭代到j,也就是切割方案中左边方案为1,2...j的时候,跟右边已经有最优解的加起来, - # 然后算所有的加起来的和的最大值,那肯定就是最优解了! NB啊 + # 然后算所有的加起来的和的最大值,那肯定就是最优解了! + first = 0 for i in range(1, j + 1): - if q < p[i] + r[j - i]: - q = p[i] + r[j - i] - ii = i - r[j] = q - ans.append([ii] + ans[j - ii]) - return r[n], ans[len(ans) - 1] + if max_val < p[i] + best_incomes[j - i]: + max_val = p[i] + best_incomes[j - i] + first = i + best_incomes[j] = max_val + best_solutions.append([first] + best_solutions[j - first]) + return best_incomes[n], best_solutions[n] if __name__ == '__main__': - parry = [0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30] - for k in range(1, 11): + parry = [0, 1, 5, 8, 9, 10, 17, 18, 20, 21, 23, 25, 26, 30] + for k in range(1, 13): print(bottom_up_cut_rod(parry, k)) diff --git a/algorithms/ch07dynamic/at401_fibonacci.py b/algorithms/ch05dynamic/at401_fibonacci.py similarity index 100% rename from algorithms/ch07dynamic/at401_fibonacci.py rename to algorithms/ch05dynamic/at401_fibonacci.py diff --git a/algorithms/ch07dynamic/at402_matrix_chain.py b/algorithms/ch05dynamic/at402_matrix_chain.py similarity index 100% rename from algorithms/ch07dynamic/at402_matrix_chain.py rename to algorithms/ch05dynamic/at402_matrix_chain.py diff --git a/algorithms/ch07dynamic/at403_elevator.py b/algorithms/ch05dynamic/at403_elevator.py similarity index 100% rename from algorithms/ch07dynamic/at403_elevator.py rename to algorithms/ch05dynamic/at403_elevator.py diff --git a/algorithms/ch07dynamic/at404_lcs.py b/algorithms/ch05dynamic/at404_lcs.py similarity index 100% rename from algorithms/ch07dynamic/at404_lcs.py rename to algorithms/ch05dynamic/at404_lcs.py diff --git a/algorithms/ch08greedy/__init__.py b/algorithms/ch06greedy/__init__.py similarity index 100% rename from algorithms/ch08greedy/__init__.py rename to algorithms/ch06greedy/__init__.py diff --git a/algorithms/ch04graph/__init__.py b/algorithms/ch10graph/__init__.py similarity index 100% rename from algorithms/ch04graph/__init__.py rename to algorithms/ch10graph/__init__.py diff --git a/algorithms/ch05string/__init__.py b/algorithms/ch20string/__init__.py similarity index 100% rename from algorithms/ch05string/__init__.py rename to algorithms/ch20string/__init__.py diff --git a/algorithms/ch09sample/__init__.py b/algorithms/ch30sample/__init__.py similarity index 100% rename from algorithms/ch09sample/__init__.py rename to algorithms/ch30sample/__init__.py diff --git a/algorithms/ch09sample/m01_math.py b/algorithms/ch30sample/m01_math.py similarity index 100% rename from algorithms/ch09sample/m01_math.py rename to algorithms/ch30sample/m01_math.py diff --git a/algorithms/ch09sample/m02_triangle_str.py b/algorithms/ch30sample/m02_triangle_str.py similarity index 100% rename from algorithms/ch09sample/m02_triangle_str.py rename to algorithms/ch30sample/m02_triangle_str.py diff --git a/algorithms/ch09sample/m03_duplicate_words.py b/algorithms/ch30sample/m03_duplicate_words.py similarity index 100% rename from algorithms/ch09sample/m03_duplicate_words.py rename to algorithms/ch30sample/m03_duplicate_words.py diff --git a/algorithms/ch09sample/m04_binary_add.py b/algorithms/ch30sample/m04_binary_add.py similarity index 100% rename from algorithms/ch09sample/m04_binary_add.py rename to algorithms/ch30sample/m04_binary_add.py diff --git a/algorithms/ch09sample/m05_nine_number.py b/algorithms/ch30sample/m05_nine_number.py similarity index 100% rename from algorithms/ch09sample/m05_nine_number.py rename to algorithms/ch30sample/m05_nine_number.py diff --git a/algorithms/ch09sample/m06_hornerpoly.py b/algorithms/ch30sample/m06_hornerpoly.py similarity index 100% rename from algorithms/ch09sample/m06_hornerpoly.py rename to algorithms/ch30sample/m06_hornerpoly.py diff --git a/algorithms/ch09sample/m07_max_subarr.py b/algorithms/ch30sample/m07_max_subarr.py similarity index 100% rename from algorithms/ch09sample/m07_max_subarr.py rename to algorithms/ch30sample/m07_max_subarr.py diff --git a/algorithms/ch09sample/m08_max_subarr2.py b/algorithms/ch30sample/m08_max_subarr2.py similarity index 100% rename from algorithms/ch09sample/m08_max_subarr2.py rename to algorithms/ch30sample/m08_max_subarr2.py diff --git a/algorithms/ch09sample/m09_max_subarr3.py b/algorithms/ch30sample/m09_max_subarr3.py similarity index 100% rename from algorithms/ch09sample/m09_max_subarr3.py rename to algorithms/ch30sample/m09_max_subarr3.py diff --git a/algorithms/ch09sample/m10_code_funny.py b/algorithms/ch30sample/m10_code_funny.py similarity index 100% rename from algorithms/ch09sample/m10_code_funny.py rename to algorithms/ch30sample/m10_code_funny.py diff --git a/algorithms/ch09sample/m11_rand_permute.py b/algorithms/ch30sample/m11_rand_permute.py similarity index 100% rename from algorithms/ch09sample/m11_rand_permute.py rename to algorithms/ch30sample/m11_rand_permute.py diff --git a/algorithms/ch09sample/m12_right_shift.py b/algorithms/ch30sample/m12_right_shift.py similarity index 100% rename from algorithms/ch09sample/m12_right_shift.py rename to algorithms/ch30sample/m12_right_shift.py diff --git a/algorithms/ch09sample/m13_sin_cpu.py b/algorithms/ch30sample/m13_sin_cpu.py similarity index 100% rename from algorithms/ch09sample/m13_sin_cpu.py rename to algorithms/ch30sample/m13_sin_cpu.py diff --git a/algorithms/ch09sample/m14_bestsinger.py b/algorithms/ch30sample/m14_bestsinger.py similarity index 100% rename from algorithms/ch09sample/m14_bestsinger.py rename to algorithms/ch30sample/m14_bestsinger.py diff --git a/algorithms/ch09sample/m15_bracket_match.py b/algorithms/ch30sample/m15_bracket_match.py similarity index 100% rename from algorithms/ch09sample/m15_bracket_match.py rename to algorithms/ch30sample/m15_bracket_match.py diff --git a/algorithms/ch09sample/m16_circle_queue.py b/algorithms/ch30sample/m16_circle_queue.py similarity index 100% rename from algorithms/ch09sample/m16_circle_queue.py rename to algorithms/ch30sample/m16_circle_queue.py From 1532aa1c6da1c0337841b1796eba6dee12b40a71 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Wed, 17 Jun 2020 01:13:36 +0800 Subject: [PATCH 12/54] =?UTF-8?q?=E5=8A=A8=E6=80=81=E8=A7=84=E5=88=92?= =?UTF-8?q?=E8=A7=A3=E5=86=B30-1=E8=83=8C=E5=8C=85=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{at400_cut_steel.py => m01_cut_steel.py} | 16 +++---- .../{at401_fibonacci.py => m02_fibonacci.py} | 0 ...02_matrix_chain.py => m03_matrix_chain.py} | 31 +++++++------ .../{at403_elevator.py => m04_elevator.py} | 0 .../{at404_lcs.py => m05_subsequence.py} | 21 +++++---- algorithms/ch05dynamic/m06_bag.py | 43 +++++++++++++++++++ algorithms/ch06greedy/__init__.py | 1 - algorithms/ch06greedy/m01_activity.py | 21 +++++++++ 8 files changed, 97 insertions(+), 36 deletions(-) rename algorithms/ch05dynamic/{at400_cut_steel.py => m01_cut_steel.py} (81%) rename algorithms/ch05dynamic/{at401_fibonacci.py => m02_fibonacci.py} (100%) rename algorithms/ch05dynamic/{at402_matrix_chain.py => m03_matrix_chain.py} (61%) rename algorithms/ch05dynamic/{at403_elevator.py => m04_elevator.py} (100%) rename algorithms/ch05dynamic/{at404_lcs.py => m05_subsequence.py} (64%) create mode 100644 algorithms/ch05dynamic/m06_bag.py create mode 100644 algorithms/ch06greedy/m01_activity.py diff --git a/algorithms/ch05dynamic/at400_cut_steel.py b/algorithms/ch05dynamic/m01_cut_steel.py similarity index 81% rename from algorithms/ch05dynamic/at400_cut_steel.py rename to algorithms/ch05dynamic/m01_cut_steel.py index f2fe004..e5ab2b6 100644 --- a/algorithms/ch05dynamic/at400_cut_steel.py +++ b/algorithms/ch05dynamic/m01_cut_steel.py @@ -19,22 +19,22 @@ def bottom_up_cut_rod(p, n): param n: 钢条总长度 """ # 先初始化数组r,最优解值数组。r[i]表示长度为i的时候的最优解。 - best_incomes = [0] * (n + 1) + vals = [0] * (n + 1) # 用来保存每个最优切割方案二维数组,ans[i]表示长度为i的最优切割方案 - best_solutions = [[]] - for j in range(1, n + 1): # 自顶向上迭代 + ans = [[]] + for j in range(1, n + 1): # 自底向上迭代 max_val = -999 # 下面这个内层循环保证长度为j时候所有情况都考虑到了 # 因为i会从1迭代到j,也就是切割方案中左边方案为1,2...j的时候,跟右边已经有最优解的加起来, # 然后算所有的加起来的和的最大值,那肯定就是最优解了! first = 0 for i in range(1, j + 1): - if max_val < p[i] + best_incomes[j - i]: - max_val = p[i] + best_incomes[j - i] + if max_val < p[i] + vals[j - i]: + max_val = p[i] + vals[j - i] first = i - best_incomes[j] = max_val - best_solutions.append([first] + best_solutions[j - first]) - return best_incomes[n], best_solutions[n] + vals[j] = max_val + ans.append([first] + ans[j - first]) + return vals[n], ans[n] if __name__ == '__main__': diff --git a/algorithms/ch05dynamic/at401_fibonacci.py b/algorithms/ch05dynamic/m02_fibonacci.py similarity index 100% rename from algorithms/ch05dynamic/at401_fibonacci.py rename to algorithms/ch05dynamic/m02_fibonacci.py diff --git a/algorithms/ch05dynamic/at402_matrix_chain.py b/algorithms/ch05dynamic/m03_matrix_chain.py similarity index 61% rename from algorithms/ch05dynamic/at402_matrix_chain.py rename to algorithms/ch05dynamic/m03_matrix_chain.py index 4fd5deb..19a831e 100644 --- a/algorithms/ch05dynamic/at402_matrix_chain.py +++ b/algorithms/ch05dynamic/m03_matrix_chain.py @@ -3,41 +3,40 @@ """ Topic: 动态规划:最优矩阵链乘法括号化算法 Desc : - 对于矩阵A1A2...An相乘,由于满足结合律,求一个最优括号算法使得计算的次数最少 - 对于矩阵Ai*Aj的计算次数为:p[i-1]*p[i]*p[j],row(左)*column(左)*column(右) + 对于矩阵A[1]A[2]...A[n]相乘,由于满足结合律,求一个最优括号算法使得计算的次数最少 + 对于矩阵A[i]*A[j]的计算次数为:p[i-1]*p[i]*p[j] => row(左)*column(左)*column(右) 算法思路: 给定一个序列p:,对每个Ai 定义一个n*n二维数组m,其中m[i,j]=min(i<= k < j){m[i,k]+m[k+1,j]+p[i-1]*p[k]*p[j]} 再定义一个n-1*n-1二维数组s,其中s[i,j]表示m[i,j]时候的括号分割点,利用s可以获得最后的括号序列 - """ def matrix_order(p): - """:param p: 矩阵规模序列,Ai行列分别为p[i-1],p[i]""" - INF = float('inf') + """:param p: 矩阵规模序列,A[i]行列分别为p[i-1],p[i]""" + INF = float('inf') # 无穷大 n = len(p) - 1 # 矩阵长度 - m = [[0 for zz in range(n)] for z in range(n)] # 保存Ai...Aj最优值 - s = [['-' for zz in range(n)] for z in range(n)] # 保存Ai...Aj最优值时候的括号分割点 + vals = [[0 for _ in range(n)] for _ in range(n)] # 保存子问题A[i]...A[j]最优值 + ans = [[-1 for _ in range(n)] for _ in range(n)] # 保存子问题A[i]...A[j]最优值时候的括号分割点 for chain_len in range(2, n + 1): # chain_len表示每次循环计算链的长度2..n for i in range(0, n - chain_len + 1): j = i + chain_len - 1 - m[i][j] = INF # 上面两层循环则是对m方阵的右上三角(除对角线)进行某个赋值MAX + vals[i][j] = INF # 上面两层循环则是对m方阵的右上三角(除对角线)进行某个赋值MAX for k in range(i, j): # 然后对每个计算最小值 # 此时m[i][k]和m[k + 1][j]一定已经有值了。why??? # 因为对于某个i,比j小的肯定赋值过 # 对于某个j,比i大的肯定也赋值过 # 上面循环方向示意图可以画下,是从右上三角,斜右下右下的循环。 - q = m[i][k] + m[k + 1][j] + p[i] * p[k + 1] * p[j + 1] - if q < m[i][j]: - m[i][j] = q - s[i][j] = k - for mm in m: + q = vals[i][k] + vals[k + 1][j] + p[i] * p[k + 1] * p[j + 1] + if q < vals[i][j]: + vals[i][j] = q + ans[i][j] = k + for mm in vals: print(mm) - for ss in s: + for ss in ans: print(ss) - print_optimal(s, 0, n - 1) - return m, s + print_optimal(ans, 0, n - 1) + return vals, ans def print_optimal(s, i, j): diff --git a/algorithms/ch05dynamic/at403_elevator.py b/algorithms/ch05dynamic/m04_elevator.py similarity index 100% rename from algorithms/ch05dynamic/at403_elevator.py rename to algorithms/ch05dynamic/m04_elevator.py diff --git a/algorithms/ch05dynamic/at404_lcs.py b/algorithms/ch05dynamic/m05_subsequence.py similarity index 64% rename from algorithms/ch05dynamic/at404_lcs.py rename to algorithms/ch05dynamic/m05_subsequence.py index 5bdc0ae..8d24891 100644 --- a/algorithms/ch05dynamic/at404_lcs.py +++ b/algorithms/ch05dynamic/m05_subsequence.py @@ -1,19 +1,18 @@ #!/usr/bin/env python # -*- encoding: utf-8 -*- -# 最长公共子序列:longest-common-subsequence +# 最长公共子序列 # author: XiongNeng """ -Topic: 一个子序列代表,将一个序列中去掉若干元素后得到的序列,可以间隔。 - 公共子序列就是,序列A和序列B的公共子序列 - 最长公共子序列就是,公共子序列里面长度最长的。 +一个子序列代表,将一个序列中去掉若干元素后得到的序列,可以间隔。 +公共子序列就是,序列A和序列B的公共子序列 +最长公共子序列就是,公共子序列里面长度最长的。 - 思路: - 接受两个序列作为输入 - 将两个序列安装下标变成矩阵或者是二维数组c(m+1 * n+1) - 按行主次序(row-major-order)计算表项,即首先计算C的第一行,然后是第二行。。 - 另外还维护一个二维数组b(m * n),b[i,j]指向的表项对应计算c[i,j]时选择的子问题最优解 - c[m-1][n-1]保存了X和Y的LCS的长度 -Desc : +思路: +接受两个序列作为输入 +将两个序列按照下标变成矩阵或者是二维数组c(m+1 * n+1) +按行主次序(row-major-order)计算表项,即首先计算C的第一行,然后是第二行。。 +另外还维护一个二维数组b(m * n),b[i,j]指向的表项对应计算c[i,j]时选择的子问题最优解 +c[m-1][n-1]保存了X和Y的LCS的长度 """ diff --git a/algorithms/ch05dynamic/m06_bag.py b/algorithms/ch05dynamic/m06_bag.py new file mode 100644 index 0000000..89d7afe --- /dev/null +++ b/algorithms/ch05dynamic/m06_bag.py @@ -0,0 +1,43 @@ +# -*- encoding: utf-8 -*- +""" +动态规划解决0-1背包问题 +有n个商品a[0..n],价值v[0..n]美元,重量w[0..n]磅。一个背包最多能承重top磅。 +怎样装商品能获得最大价值。 +""" + + +def bag_choice(v, w, top): + n = len(v) - 1 + # 先初始化最优解值二维数组 + # vals[i][w]表示:对于前i个物品,当前背包的容量为w时,这种情况下可以装下的最大价值 + vals = [[0 for _ in range(top + 1)] for _ in range(n + 1)] + # 用来保存每个最优方案三维数组,ans[i][j]表示前i个物品上限为j时候的最优方案 + ans = [[[0 for _ in range(i + 1)] for _ in range(top + 1)] for i in range(n + 1)] + for i in range(1, n + 1): # 物品选择从1到n + for j in range(1, top + 1): # 重量上限从1到top + if j - w[i] < 0: + # 这时候只能选择不选i + vals[i][j] = vals[i - 1][j] + # 方案为前i-1最优方案+不选择i + ans[i][j] = ans[i - 1][j] + [0] + else: + # 不选择i的时候,则最优解就是前i-1个物品上限为j的最优解 + unchoose_val = vals[i - 1][j] + # 选择i的时候,则最优解就是前i-1个物品上限为j-w[i]最优解+v[i]的和 + choose_val = vals[i - 1][j - w[i]] + v[i] + if unchoose_val > choose_val: + vals[i][j] = unchoose_val + # 方案为前i-1最优方案+不选择i + ans[i][j] = ans[i - 1][j] + [0] + else: + vals[i][j] = choose_val + # 方案为前i-1最优方案+选择i + ans[i][j] = ans[i - 1][j - w[i]] + [1] + return vals[n][top], ans[n][top] + + +if __name__ == '__main__': + w = [0, 1, 2, 12, 1, 4] # 重量数组 + v = [0, 1, 2, 4, 2, 10] # 价值数组 + top = 7 # 背包重量上限 + print(bag_choice(v, w, top)) diff --git a/algorithms/ch06greedy/__init__.py b/algorithms/ch06greedy/__init__.py index 73d01c3..e320ca2 100644 --- a/algorithms/ch06greedy/__init__.py +++ b/algorithms/ch06greedy/__init__.py @@ -1,5 +1,4 @@ # -*- encoding: utf-8 -*- """贪心算法 -Some of description... """ diff --git a/algorithms/ch06greedy/m01_activity.py b/algorithms/ch06greedy/m01_activity.py new file mode 100644 index 0000000..69f269d --- /dev/null +++ b/algorithms/ch06greedy/m01_activity.py @@ -0,0 +1,21 @@ +# -*- encoding: utf-8 -*- +""" +活动选择问题。 +活动序列a[1..n],开始时间序列s[1..n],结束时间序列f[1..n]。 +每个a[i]活动时间为。并且满足按照结束时间升序排列 +""" + + +def greedy_activity_selector(s, f): + n = len(s) + ans = [0] # 初始选择第一个活动,必定在其中,这里保存最终活动下标即可。 + for m in range(1, n): + if s[m] >= f[ans[-1]]: + ans.append(m) + return ans + + +if __name__ == '__main__': + s = [1, 3, 0, 5, 3, 5, 6, 8, 8, 2, 12] + f = [4, 5, 6, 7, 9, 9, 10, 11, 12, 14, 16] + print(greedy_activity_selector(s, f)) From af0fe78ef83324d4e0a708489ffb8678237b7c0c Mon Sep 17 00:00:00 2001 From: xiongneng Date: Sun, 12 Sep 2021 23:50:05 +0800 Subject: [PATCH 13/54] =?UTF-8?q?update=20LeetCode=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- leecode/a70_climbing_stairs.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 leecode/a70_climbing_stairs.py diff --git a/leecode/a70_climbing_stairs.py b/leecode/a70_climbing_stairs.py new file mode 100644 index 0000000..07aa6ef --- /dev/null +++ b/leecode/a70_climbing_stairs.py @@ -0,0 +1,29 @@ +# -*- encoding: utf-8 -*- +""" +70. 爬楼梯 +假设你正在爬楼梯。需要 n阶你才能到达楼顶。 +每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? +注意:给定 n 是一个正整数。 +""" + + +class Solution: + def climb_stairs(self, n: int) -> int: + if n == 1: + return 1 + if n == 2: + return 2 + a, b = 1, 2 + for i in range(3, n + 1): + a, b = b, a + b + + return b + + +if __name__ == '__main__': + import sys + while True: + line = sys.stdin.readline().strip() + if line == '': + break + print(Solution().climb_stairs(int(line))) From b5219b1a5f74933461b6a668e3c8422489dd07a8 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Sun, 19 Dec 2021 23:26:58 +0800 Subject: [PATCH 14/54] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=97=A0=E7=94=A8?= =?UTF-8?q?=E7=9A=84doc=E6=96=87=E4=BB=B6=E5=A4=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/about.md | 23 --------- docs/chapters/chapter1/post01.md | 70 -------------------------- docs/chapters/chapter1/post02.md | 5 -- docs/chapters/chapter2/post03.md | 3 -- docs/chapters/chapter2/post04.md | 3 -- docs/chapters/chapter2/post05.md | 3 -- docs/chapters/chapter2/temp/temp01.md | 3 -- docs/chapters/chapter2/temp/temp02.md | 3 -- docs/chapters/subpage.md | 3 -- docs/chapters/tutorial.md | 22 -------- docs/chapters/usage.md | 3 -- docs/docs/about.md | 23 --------- docs/docs/chapters/subpage.md | 3 -- docs/docs/chapters/tutorial.md | 22 -------- docs/docs/chapters/usage.md | 5 -- docs/docs/index.md | 17 ------- docs/index.md | 17 ------- docs/resources/css/extra.css | 14 ------ docs/resources/img/favicon.ico | Bin 67646 -> 0 bytes 19 files changed, 242 deletions(-) delete mode 100644 docs/about.md delete mode 100644 docs/chapters/chapter1/post01.md delete mode 100644 docs/chapters/chapter1/post02.md delete mode 100644 docs/chapters/chapter2/post03.md delete mode 100644 docs/chapters/chapter2/post04.md delete mode 100644 docs/chapters/chapter2/post05.md delete mode 100644 docs/chapters/chapter2/temp/temp01.md delete mode 100644 docs/chapters/chapter2/temp/temp02.md delete mode 100644 docs/chapters/subpage.md delete mode 100644 docs/chapters/tutorial.md delete mode 100644 docs/chapters/usage.md delete mode 100644 docs/docs/about.md delete mode 100644 docs/docs/chapters/subpage.md delete mode 100644 docs/docs/chapters/tutorial.md delete mode 100644 docs/docs/chapters/usage.md delete mode 100644 docs/docs/index.md delete mode 100644 docs/index.md delete mode 100644 docs/resources/css/extra.css delete mode 100644 docs/resources/img/favicon.ico diff --git a/docs/about.md b/docs/about.md deleted file mode 100644 index a37a1e0..0000000 --- a/docs/about.md +++ /dev/null @@ -1,23 +0,0 @@ -# 关于我 - -这一页是我的一个基本介绍 - -## 学习经历 - -xxx年在哪里学习。 - -## 工作经历 -毕业后去了xx公司实习 - -## 联系方式 - -### 邮件 - -xxxx@gmail.com - -### QQ和微信 - -+ QQ:7969979797 -+ 微信:yixx8989 - - diff --git a/docs/chapters/chapter1/post01.md b/docs/chapters/chapter1/post01.md deleted file mode 100644 index fa0cf4e..0000000 --- a/docs/chapters/chapter1/post01.md +++ /dev/null @@ -1,70 +0,0 @@ - -# 设计背景 - -由于网络安全的不确定性,决定设计这个。 - -## 文本修饰 - -加粗 **bold** - -斜体字 _斜体字_ - -加粗斜体 ___粗斜体___ - -下划线 ^^Insert me^^ - -删除线 ~~Delete me~~ - -增加 {++ add ++} - -修改 {~~ is ~> are ~~} - -删除 {-- del --} - -高亮 {== highlight ==} - -注释 {>> comment <<} - -上标 H^2^O, text^a\ superscript^ - -下标 CH~3~CH~2~OH, text~a\ subscript~ - -行内代码高亮:`:::java System.out.println("hello");` or `#!python println('hello')` - -键盘快捷键标签:++ctrl+alt+f++ - -其他 {++sth++} - -## 提示文字 - -???+ danger highlight blink "custom title or blank" - text vtext text, text, v - text vtext text, text, v - ```python - text1 = "Hello, " - text2 = "world!" - print text1 + text2 - ``` - -!!! note - this is a tip - -## 复选框 - -看看复选框 - -- [x] item1 -- [x] item2 -- [x] item3 - -## 表格演示 - -今年的旅游目标地 - -编号 | 省份 | 日期 ------- | ------- | -------------- -01 | 湖北 | 2020-12-12 -02 | 陕西 | 2020-12-12 -03 | 四川 | 2020-12-12 -04 | ShanXi | 2020-12-12 - diff --git a/docs/chapters/chapter1/post02.md b/docs/chapters/chapter1/post02.md deleted file mode 100644 index bb63a8e..0000000 --- a/docs/chapters/chapter1/post02.md +++ /dev/null @@ -1,5 +0,0 @@ -# post02 - -第2篇。。。。。。。。。 - -这里讨论IO和多线程 diff --git a/docs/chapters/chapter2/post03.md b/docs/chapters/chapter2/post03.md deleted file mode 100644 index 2e14259..0000000 --- a/docs/chapters/chapter2/post03.md +++ /dev/null @@ -1,3 +0,0 @@ -# post03 - -第3篇。。。。。。。。。 \ No newline at end of file diff --git a/docs/chapters/chapter2/post04.md b/docs/chapters/chapter2/post04.md deleted file mode 100644 index fcc27af..0000000 --- a/docs/chapters/chapter2/post04.md +++ /dev/null @@ -1,3 +0,0 @@ -# post04 - -第4篇。。。。。。。。。 \ No newline at end of file diff --git a/docs/chapters/chapter2/post05.md b/docs/chapters/chapter2/post05.md deleted file mode 100644 index 3de089f..0000000 --- a/docs/chapters/chapter2/post05.md +++ /dev/null @@ -1,3 +0,0 @@ -# post05 - -第5篇。。。。。。。。。 \ No newline at end of file diff --git a/docs/chapters/chapter2/temp/temp01.md b/docs/chapters/chapter2/temp/temp01.md deleted file mode 100644 index 605bfb7..0000000 --- a/docs/chapters/chapter2/temp/temp01.md +++ /dev/null @@ -1,3 +0,0 @@ -# 我爱你 - -我爱你我爱你我爱你我爱你我爱你 \ No newline at end of file diff --git a/docs/chapters/chapter2/temp/temp02.md b/docs/chapters/chapter2/temp/temp02.md deleted file mode 100644 index c2bc5d7..0000000 --- a/docs/chapters/chapter2/temp/temp02.md +++ /dev/null @@ -1,3 +0,0 @@ -# 王大锤 - -买个锤子锤子锤子 diff --git a/docs/chapters/subpage.md b/docs/chapters/subpage.md deleted file mode 100644 index 14d441b..0000000 --- a/docs/chapters/subpage.md +++ /dev/null @@ -1,3 +0,0 @@ -# 内部子页面 - -内部子页面,哈哈哈。修改后 \ No newline at end of file diff --git a/docs/chapters/tutorial.md b/docs/chapters/tutorial.md deleted file mode 100644 index 06452b4..0000000 --- a/docs/chapters/tutorial.md +++ /dev/null @@ -1,22 +0,0 @@ -# 简易教程 - -## 介绍 - -xxxx - -## 第一章节 - -11111111111 - - -## 第二章节 - -22222222222 - -### 小章节1 - -笑笑哈哈 - -### 小章节2 - -哈哈哈浪费大是大非 \ No newline at end of file diff --git a/docs/chapters/usage.md b/docs/chapters/usage.md deleted file mode 100644 index abbb6f7..0000000 --- a/docs/chapters/usage.md +++ /dev/null @@ -1,3 +0,0 @@ -# 使用方法 - -入门啦啦啦啊,[进入子页面](subpage.md) diff --git a/docs/docs/about.md b/docs/docs/about.md deleted file mode 100644 index a37a1e0..0000000 --- a/docs/docs/about.md +++ /dev/null @@ -1,23 +0,0 @@ -# 关于我 - -这一页是我的一个基本介绍 - -## 学习经历 - -xxx年在哪里学习。 - -## 工作经历 -毕业后去了xx公司实习 - -## 联系方式 - -### 邮件 - -xxxx@gmail.com - -### QQ和微信 - -+ QQ:7969979797 -+ 微信:yixx8989 - - diff --git a/docs/docs/chapters/subpage.md b/docs/docs/chapters/subpage.md deleted file mode 100644 index 14d441b..0000000 --- a/docs/docs/chapters/subpage.md +++ /dev/null @@ -1,3 +0,0 @@ -# 内部子页面 - -内部子页面,哈哈哈。修改后 \ No newline at end of file diff --git a/docs/docs/chapters/tutorial.md b/docs/docs/chapters/tutorial.md deleted file mode 100644 index 06452b4..0000000 --- a/docs/docs/chapters/tutorial.md +++ /dev/null @@ -1,22 +0,0 @@ -# 简易教程 - -## 介绍 - -xxxx - -## 第一章节 - -11111111111 - - -## 第二章节 - -22222222222 - -### 小章节1 - -笑笑哈哈 - -### 小章节2 - -哈哈哈浪费大是大非 \ No newline at end of file diff --git a/docs/docs/chapters/usage.md b/docs/docs/chapters/usage.md deleted file mode 100644 index 255c9cb..0000000 --- a/docs/docs/chapters/usage.md +++ /dev/null @@ -1,5 +0,0 @@ -# 使用方法 - -入门啦啦啦啊,[进入子页面](../subpage/) - - diff --git a/docs/docs/index.md b/docs/docs/index.md deleted file mode 100644 index 000ea34..0000000 --- a/docs/docs/index.md +++ /dev/null @@ -1,17 +0,0 @@ -# Welcome to MkDocs - -For full documentation visit [mkdocs.org](https://www.mkdocs.org). - -## Commands - -* `mkdocs new [dir-name]` - Create a new project. -* `mkdocs serve` - Start the live-reloading docs server. -* `mkdocs build` - Build the documentation site. -* `mkdocs -h` - Print help message and exit. - -## Project layout - - mkdocs.yml # The configuration file. - docs/ - index.md # The documentation homepage. - ... # Other markdown pages, images and other files. diff --git a/docs/index.md b/docs/index.md deleted file mode 100644 index 000ea34..0000000 --- a/docs/index.md +++ /dev/null @@ -1,17 +0,0 @@ -# Welcome to MkDocs - -For full documentation visit [mkdocs.org](https://www.mkdocs.org). - -## Commands - -* `mkdocs new [dir-name]` - Create a new project. -* `mkdocs serve` - Start the live-reloading docs server. -* `mkdocs build` - Build the documentation site. -* `mkdocs -h` - Print help message and exit. - -## Project layout - - mkdocs.yml # The configuration file. - docs/ - index.md # The documentation homepage. - ... # Other markdown pages, images and other files. diff --git a/docs/resources/css/extra.css b/docs/resources/css/extra.css deleted file mode 100644 index c42c78f..0000000 --- a/docs/resources/css/extra.css +++ /dev/null @@ -1,14 +0,0 @@ -.md-typeset table:not([class]) th { - min-width: 5rem; - padding: .6rem .8rem; - background-color: #9facf6; - color: #fff; - vertical-align: top; -} - -.md-footer-nav__link { - padding-top: 0; - padding-bottom: 0; - -webkit-transition: opacity .25s; - transition: opacity .25s; -} \ No newline at end of file diff --git a/docs/resources/img/favicon.ico b/docs/resources/img/favicon.ico deleted file mode 100644 index a93c7684ab0ee7aa70b837ac5b498379ed4184c5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67646 zcmeHQ2Y3`!7mW=O`B702DIrEgM8t+zKnO)Zq^XFA3eu6@d+$B;&_nMXLWhJ<5(p$A z2@w)P=%Kd&(!%}EnVGjcyV(?wP-MsNvO8O5XWn_|o_p`R6J1=M!GAq_y5L_omwf4; zamni9;*t-Bm-wRgI-l}c=9gVG)AybKI!C}c0?rX|j(~FnoFm{I0p|!fN5DA(&Jl2q zfO7<#Bj6kX=Lk4Qz&QfW5pa%xa|9l%5qK77V{ebu2|7UYxU>r#w%dzcS8a&INwQIR`KZNo*V& za)smN>fJhP&HYn<3c~Y`VfkThFpeq5IjuRB6xNE{3Tx$~vf-RKN8Mm~V0jJWbH2{c zsdL6t=jLDp$Pe-;J1pOUDXzY!7B!Ns!>jsW|4Udw7{`;poZ)euTjCMm*pnX|WB2;sWh#GY zQcgLwppqP$-&rQKC^i7Ee+^UP$+0)<0l%M`jh|CStQFph*UFDO!rBd==lmm{3TvJZ zvF7|N3M&TlfR!{J`5Hgt4&yQTJN$j;W;+7JL2*C-)?qm&?HQO=;^tS7!*e>wp_whD zUfK5=;4>UwjyK1jV@fV2r3V~mWyxV})@<_B?8k{UxlP|g9La5B&ADjCx-|A_WnkqD zp^CAfNNV3hf`4J#I&j%yM#Gc{wzzjl|4sCHp4Tj?eF! z?m@w;js(8tnvOpdqWwDRG^;a+g&Z+XD@yN+-!kJrss0sAz*#yP-w z!uiAV)(oSQxZ#Gd29aUmx87j@0nCv| zADu0Jebe-^q1j8aq4`S^F)WMh^{NfbYe~r1KO}g}@3Lof4cR@ax@;f(eSGo!uhhZ! zI0w``P@FdN+Me5va7xS9`1_oPj5G4UIN#I5o@V^%|1!X+hk0Rz=5=~=Kw!5_vi7eR zWnE)flNTj?$QuUkzgch(8d*(tjrdu1dj2HqdX|iFf8*Ke_`bqV%>_QH*B5;*)P2^jW+>=;^EwhyT!vs)M0gzrCUjFbC);!l6X7= z$4d@_NBJJ{rv`Yy7?Zlgo>mR8=RW!H^|oO-7W)AA6}6s~m4Cu&!!Q^8+h&lxW4{IN zRlxPiz`UYt9rV3{dpYszUsinkeJh)Ldq~T2Z}r2m9wpAn{kDn$r~&z4*xd?(QHMnXJkw3mw>;A3HR^7cj8_KxR;jAeM`xvJ|$#B zFArJW^{e>GA7^Ne<0Xf~qk4}%fH45`zydJFyo`OHCj1rmdELBzjr+6OXC30(BE4w% za}FrOTv%B*gY2L9IrvW8%WAl9?pqp|my(UWiFrqtJcK=!yw)rH+EwhU` z9(+`I+yAbL0hk9W4akh=>0lg}r(v__KI=6lLq@!{*Mhmi-t-tbzL4(YHQY-AcMk*i zZ!Ea4?)s(pbooM7b^ctYHq0A<nMgu9v(`@B8{-xcoU`ZwTu5n0piYxsQPURc9@Wv9<%MaNHMd54c>M2+mrAHzA| zNCPtBJf8*);5G7ERm`t(-+yS1rHuC!){Y+k9$(Pp zeE%Gn7XsHm)wsT_J#qigz&*b#YMoCOwt7$IG|LlTvA~PX@jH)$@8>xXf3pU#?)5a} zfr|Ugd9+#|9zCYD%{t6s+-ElzLWj75@4B|@TvxakG;sd_eAjVb&@!*gZ}G0oYyOVR zZT7ZIYnbcw+nJwvXz^f$!Wrsx{q?nuQ(9&5T;1obxxRz5FAtmaY50(4U#Q$vX~35l zgZwa#Ne0+|RRa|F8SA>iw3r`{rT2}=9-}y(+++CgoF*Utu`Fv(+zWv3AAsxcgX{T3 z$32e)_c={-%j_nuGOKY;@v5069KZLkeL#NK7pfE6;SFBzM{H@KW8MxA8TC$h%;bFW zu~Q1jp~(d$%BzqZ@cL5rjVUgX$X#RR)skIv+o_n8_?v5i|HV9znA13?>Gz2}uaong z^SfqXmKQ+Ju#`Pd~ z7{`a>#4&r4H=aK+XHLuOVZ5iX&xhx{Ugp1Lc8<)sA*Hxa;UC=Z^+ejfpyj*p^W?j` z%xUTduIC2ViF*zc?pejVeioTp?{!(!GK-9@pLvq<%iD+M*c3E0dwAH$oH0?Ob4m0V zSBV(vDq(|jOK?9o3F_r8LA~FR-F@DbJ$>JkJ^k`Y@PPahGO&Pz3@WH&KjahO{~56V zT*5rR0QO%=#KaV6#N@!!hPm91sY;M(k2pdTXsrD5a($AvL5HQ-6a zpXaP_C+574Ofce3ZF7V18b5^8J(uk2kz024d>i-!``&qEci+4^_Wj=n{vQDU4}m?nuVHWE{s?e? zq&@e6y;o`35Bv{71EPJpoyPU6I8bRo0lfC4tp}PhC)drGb1u`@yTgb(^`5yNdCxgt z4)=9%S(27N%UO3=WZz|~!L56um(<10dG7Y+P@ee0KjKe5jw+u8wtV86XXW{vv+7Vf`g;y$o9b6@lOiu?H; za36l3y07_tTkbRFi=^MzxL*eK>vD2nQh8`VEAgM!Ld7BFFcu|Y)Wkfn$1xAI$DICM zVb1d<=A64c|NJn{Wn#`X4)UGXM?c4F<(x0yuzaSbJ33`dw%(&~Us03mfzM$*@OcUE z{ec`qOtk};`V#x5I`)3epEvMV*ju^3joc^p8ux*{J@+-gpP2ia-?!+#^804p2ltJb zFHDR1p!=hWAm%gczKQ#jzLO}#fCpz)m!q2o#A6&P7~?@saIEMjsg)et=V6a>GhBjg_gSzf?zNuRuwPaC1@r}^lkh$t%CRvX5&%w< z_kPV3_UXWT;19p=kG?@$?(2TvG53MJru#bggQ)wKn9t08U~i-Q_KJnN6z83RQ_boA>;yz`F8rRGO#2u$9tAJz}zdO>l=xDe{!7nsRP{Wrq{4vQ~xDdQ$K_3?DV!AA74&_ zySr+-uVOxb#(XxqZ;tuiFk(K&{M3D&`@3)q>V8nKWVo;8dn)F)=RWeiQS|#d_qBYF zy6=Gd(cV>XA5%4n^B*eTeU+yU#)fl%W2o}Lhou2#+{tx?Ie*_?&kNx-v!34*=J;-f z5(QtavuWTvo6gO7Uu1d_IWi!R_(0Q_rIPcj>*=_!ZID6MHhfvuHOwdh@B>H3m64Dh zZl;)@F<(Yg%m@69m`~+SlN?{$Mdl3p(|rE|$CrMU zewMj2`IuH4vFGs>?#jQrrH>>bQ#{f^afWyHW<%g$jRNzjN-(X(Gzg2#Rh-}sH(oL*FJP5n|Ly5&NzUt*ni#QAjw?i(6sk`0Yt zk&R7WMSP!Aj*S0K_75$TWWJ}kpLDGUb%msAJ*@NE*LoQ9CsXUu^F2N0kD99M{=sR) z{wK})_k%b>0!@iTeiNPV6@|eN8qs%Pf8^vr5cpXzsAWDc5?a`&yk(ao@hq zn_R8O9P>M_^Qu~p&V67%wX*2k2lg|5#(nI+$f4Q4%JDTFW#i`~!3Q&a6V;Ca0E zpf@xB>1U`n`C#-t{Cy7?&*h%*AJs6kXQWro)BDEe6#qWi#jkfR@$c&<+xq9h9C%Lx z2IrT+VFhKE=O?mz?ZA$MjKlWSAHkZmnrM|=mZr_RIQQ|EQg z>;7JGexrdqvESVMb@6TS2Kq#^Nz9mUW&iLmwfdgD?&~q1s`KhGpW{03gQ@jIO|Bq1 z_u=<7?pL*NKX!HvIkKRR9NRpYwE*H@21X5_4|anQ8}c+QHqHSan{kHn0h|N;ZE8Nx zqa=*yl%x-MJIgcG7k0`r_t2D_@q315m5p6rmrdQW$mSl|#IIKl+0w^Vw)T5lwhee! zb_~iV0Yg5351FAuVNB5p`;v`Qd+Lg@(`I@OrjARsu<7e@4_PeUat44e2+2T!Rc1+$AbH@ zbAFS;T+WaGOg1-rO^fkta5s2Q&Tnr1hQ@n8V&5vO zY-#nT<^%lOWRtn4KC56O9bjVE!P_kq`X#wV`zFyB)#AM-xye(anY!2WkRJg=r4 zU)5UnEb69e0UT?NJ24<0#D+Mf)u!eF=b7>a)Pp=Qo&)EiMH4E2^>WQ^L*LpEF$(^+ z8??G@I$6^$y{zq!LDqGIf9?#9cF8OoH6QRM=70ko7?QLOgik6h`=*wYLo>?Dt$8Kn z)|_u-cjug%&L_ut4g1z_3UT*u^A>yntX+1j`4z_;C@(?C5B2rE#JX?8eM_y!ah+GM z^*E^WCR6Lt@;$}F+HdaGw;RcqXz)du(JwS7_6w0{Y609uW| z)v&%Z;QAx<`627P54+Z*xPQoo`@kM+!ABPS3H<9y+@{_#Z&-r~7<;n@kb^1)AU+Rc zGy8*#n+IjD6g4q>K0~v0z?$}m*EAiV4@jL3 z>|#EUgbqY{e=qxIRF=58739vsQgUVbSE%=77p3z_abCwhC$P^2?WduiV_+dU>isi% zI`SFod!{gp7Tgx|BNQg754h$s#cf-79ZeP2lQA_*MTkO zd|(jrfmGI$dry5m=30*f-8a>GtlZaQKKlJ53uPqqbw4=q&Dbs7(R#QHJSg@bF zDIZ`>z;QmH>40~6*+0FK9GLZ^M9--v7Zz3$Sz1a?AvWC6A%{iht(*t%4bBtyfX+Jh zfnDB~on74}xbKH@bb57(Kz^8ft;a!6U!qzMxv%&2IIi{RbzV!%hnQc*d}i(+Thc&| zFKr~JHujXw-fdV5P#VA(+zrOMJheGZd;lQ#dQz(O zSh&xakGj9Op6J~FOHM3rA}3cglQUa~%kXwTu@+Do#=MI;7-N73rUAgc*slnxT#h>3xtqw32RCOV@M0FuY z`9Qc)7gG6v(t$$@5JxYrEpf|g$<37&scORZBUwy0x6$ zI!wF=)EfrOsR7Ib^T8gd2H<$w2K+O@y2BoTPk6XGaBwcx&(_u12z`o12= zwI1gC)>;qqy<^DtjxV$4erw?0R!(o|CNUd^uoj^5zyf$~)&L#62mCMQKqc5x82tJD zS}Js)8`lR?s{>!c2NV&m4_I_ynqC*O*MXzU>dT3hf5|DICi2f(<)+^yJ$4J;_(13!|ev8Cn6?3&vBJNi9b_gL#;oi~|U&r#HRRK91+{Z<0*A@IfC-1n%RD82pJu zdzF!+bN-abF(nM{>-TS_)YIpf`>M`s%J&j+za?}Z++PFkuWc`9)_0V1TL+8(%#KR| z3}XP52XZ}-wZMn59)O>5alt&e51()^I)GSETPME%e85%*>S;P~(x;i6TH8u4tZyc_ z*Z(NjmzBmnLLWKgypH`RvJd?|`-Xgq&wVD*<4Vi1dG*l0Th?;_ro%d~rLRZTdQ5d* zV|~w2tw+oEk?%3)XUunMbsJIKKeN8GoZZ}0j&Ji~Z>&Sas3o^omy_6WxK9gOZ_jz+z7O~C68lKp)A2X%<%~if_wfY{w0pMH{hNAUkGa-U z$>{50Ul;p&9MpQubzV!phkT#dGv>45ekVD*p^Kc|)J-nz94DhYSMLQ7m0{m;jd{deSwmN{?u(nR@C?B{V9rzaO#L$81CLNfMo(fAoVAX*$>)Oh>O`YV* z=2nuhzLH#+i~F*GHGRFA^BV33_WL~xW9_)GM2{_jInYp|r&QK^`L+8v*wbg<*JJJJ zV_%Qsd{3|Qs#;InNlt*gK44cDio*IpayoEkeS0~-xrngW5)_@+Ak%OZPC*nMLPuvfT z_(HR&kzY#m=%R9bem(H}7tI%#d-`nhJ)@^j_4U}+c@x)qlH>ll%{}D2Z*RG{XNr83 zH+v-j%{-8`z=zQja?kS$^T4rBFzEn$MUvM6Yp+PEbYM~`*@u3iNG%_zB3eF>tPXU< zn0A#*{=MWM-==bV&G!=Ljr%q1IIm$3+=+eEsIP$k*K%-dF*&iY0oHJTHMkGI|8HtN zX6`fQTh~#}n7QxUOV0cCkxRSA$?TzxhX4?BPl#F%x@Vly`U{u`1!3MWOPp}eI)I+R zl=6X4OI^s34%Be01M77ixZu}aE^qB4*S5kJY^oub7k&$@zmWX~=MNaTE9|4k6p@2t zib{+Z;(>X8!nfDd?%}fMzI|WM5moD1Z1{Z#wH|BC2i@P;Mf3X__x*ayg)M#M;`X6( z)PF2%0Uj`FKpxlwtp(zE4}1gutSiwcgs9qZ;`IUa^_tg-we^7{@&S_$>>2ficK?9Z zH)_^_8I{DM0}J%^ful=p^MNxPbRD?3rH5SJ)>p3X=r6anG?p8yzL(hXMQk`9J({?~ z#sd4X-$)GR+@W#BC^gpv^AcjYCVkkt@++r#eL21_mT_X{ssSj za&g;0xg6{*RlohD20${`0v~!$$o)p8RD%Kh`m`_3!wZyg|)i2ts!61cF>VvN6810G2pc)xRi-vj?M z`LuqnCVB>AwVuIb^8vkgJZ*HKot6(M9f;pCP_FG9DmQ|L%N@VE62A=puQ@MZZsNR- zyN>-~tVbN4h`eBCRrKvN(fYXce%{p7dKmK?bzY;^qvd-WyNMq2Dem{zxPNK;V7VMH zTu$wr5{Du5fSGH7|9U+T$9p6jd_Xb8g5G-HsL}!U4C4L)iw@+({R8H@(EAebfOO!j zy$%EnlIy#M%Z)vwjP)jJJNw+a%1->xfS9iclLToLO?sYw(1AqTuK~aPyCNh zEh8sqR+dw%+MuVWfvK;jk)^Naq&eR+)_835J?g#@^O5`82g&6fLv`-&93k<$M#-g+ z8S#Zaa4U~7W-UqbO85~rd|hr((6K6K7hU} zn|uIk?G_#AiF}}+Tn!j((Sh5c6C@#GirftzBDXgEA*W}RH8`*Hp19Lac$bwE)5=NQ ztRLje>h@UIZIY<3CpEPm-R~>z8-9PMC$JwW@j;{IYS;`}G^X_cj2kt8dEi4?4@?TD zhw(c4#VX+*qNVCyQfpnvssp>V`v+7$fc|jaLo}rv)(9)${sB{6Xd&XWd)0xkiE?+J zx7-aMFA3Y4%jKn2fVYnOapG=Ze{%YFLW`SO5p$p|dODh0xNl$QO65Y!{rLO zA2dp??j9@GLMF=5?UO<P!D&cPmEal%6&~<=+Q{Xf0ZwdtCZwffB3z>9a@%`w)R1q}?!p6#NzlL&Q zQ579~;2t*vxD)$X=r^FvsUl}rVf}G!C+qsIQRhvv)}!e@@;&Ij&VBlQgZsf=avl7? z9x+pPEE?#Iab_Oq2K&!z0It#DwqtNUSKLG789402i~8Rb;Qhq+qXR9Bbz8U1MVFI`M)`_@{|IlEd9Ykih{ zPt$#15AI*veWTQY zF!qfm$_J`R%zUg5XgYxU+;ZwbQV7c%KDhtS-pLyNH})@* zF+J-x#*i}xU>^9y)dJIMy5Rm1SNH%==)lFqI#3zw1NWl?o?2b#_Fm=#Rvoa+f$)iv zu%nG!US3Vdp19A2{|ENx=KUb&=Kmn)SJapDTLxIxcoNrnO|>2)-@Ce7aesnb*SJ4L zZiG*h8PG4p{XtP3?j z-zfWq>~)~GPzSDIeZW!|3Y(|<@!3@lcI3fu>VocFQEM-7gjbvZEt|J z&TC)m(YTLVkA?e)`N;iHo%=V!z2!#4bh){2rd->$AV=7FpQW`H^I#~|2m z_`4znaSxF<`h_l9`-L8?4ybu>ckdXvwY8;OTvAQW&o^)<_6w_Oc5!(vxwxf2YCV1R z^*y7`YhUZJSz%mD*5qEZWmust0KVGO~e{oS&xwzU%@A z8ow6vX=^-so!3(9VZLYKKK;JI{m7Ye>+d;oJ8FR(-#Kdwuwfp^TA)({?qQm2t4EvW?{D~eE#QVfv#eC*kj~4S&_l=lO z<36#UEw}d11^)Bp&Y_j^*YD*j;If~Ho{)Qh=b?QR_-8t_;J4hW&GB)JpNS>jjzj(Gt5i9Ky;b-A*vhFn3-=Q7uKj5@DPt%ot+UY+|lBMiU4 zAKX7MPwqr51pX@|VA%-XC&u-_r=}K|R+9tw5f;NeMBc|&m~{a6;-GKz;uiDz0CixD zB$W>+?9Gn}!Gqt0{pdxK z5VKUSN3A@8@i5;X_Egsa9>mn%&)8P`Ib7bnfof{)3^`65AG)%Tp|gFmdV{CYh_TU zKda-q-C>V?U*Lnl=V2b>^xD?N&^zvZZc}Hu=!c#`^o`org;JvfYA)Q}huAO(Ipx~= zc5~oYiTCY-I^QI{&g+Q#n%`d_cMR^|J+xfz9`=!=yJoM%m?#Z!=7DK2L2&-o)H zyF&+JuUOWJp##D9rURCF5IRb3__dNN%WZwZRlhEBJ#3nx`=)%4G2a1jKU(MhU2;Em zg~;KRaw~Q<|7MKR0B0VU2Kbu~dC9*|l`Go^EWH+Ze>z~91L2e8R$xzw_o;2;3*tAl zlz&vdhgy%8?-|@rIJj8T{kyTtHSCH1-6Lyc>!KlDagJ^?Wb6aQV!S9xN5Wlvu++?jM8SWE*m=fmp@3YV7&Yq!ib&WMPj9*<}ZXy5E zV?LexV(7lYUiSe$60&B@AY7WcFE9nAG_8bdRO^9G4R{2AC-IY9n|=0r@T5A>hrKEJ0KQK> zNC+Jx*EhB>d_fIioN0r(q5tZ&V>@R~$L~0MLXrUCF?gBt;Q14NBMRNxJ7s2S;)J^q zljUXrYL6=z8)6Owk4|z9U`^;Uj_+I#d<=k2;S{uauwrb>tQP~l>fH%X-Y2mC_)hRh zxw^WZ<_m6xj7ee+tdi}Ehcv)%JM+L40C-H^)^q{qk}hh^;KKiePNq+|oRmH=F1WD; zf6E5z2LEjB?r;uV3}3*%8S|gJKkPBVE3HmL^9P&QytE5Kd;;aWdYk_HnR@xocG7s<*86sB=C?CIj!d&}#Ks`tZn;_RV zG{+q1B6m?2R52hQqx~lK!uOpTkajqw^^w&);62_MJ2$N8hM2J{^2lT6xj%mXbp93|KNI@rvCB@;Tc z9?W|Kc#p7id$LEsejdCrvh#0+k8bw#yt#LZ;S;9Gt(}7;A!@GX2hIl1=KovV83R1o zxZ9t-{XAf;H`}iHJ?dTB>9v7A;SO@cgadO>FJ8`CfU_2CKZ5^_eTVa4aGPJgKC)@J z=dEz>V}h74cH5L1xZEfH@5KB!AWM_0a5N8C|Id12UC++vH+AcW=hT0G&bj?}N5Fm_ zun&xV0OY=N9q7M{yZOpE2h=ZO@m$S?r{ij!SLqx9=Lk4Qz&QfW5pa%x za|E0t;2Z(x2slT;IRefRaE^d;1e_z_90BJDI7h%a0?rX|j(~Fnp2883Cvm$`-1e+5 z<>vmS9{iWv;TQ4G9hcmE&h7AX_{Y!X6>Ud*Dssccyx&8Bz2*I$F2xUHpGVQQo-SNB zx9)QXn|lAQzU#tY;by;o$L@W#|BU`|o{F|5wSUQY-^KX6{r+LQ_wD!n)cZa31K98P zw0qyOUtIsZdfUbEzPel&<9*BN836cMzMq@NvwmEE-}-SK0L!oIfT+RZK?u-cJ~1`| zpq}#)`{s{x-*j~C{ln(Z12DgP+_(8Y0JGm$SZasG`=+bKOE}-2+B?QScGtuA&2PK( zu)QAa+guO!{cJv8-1hJQwc14`2YIf8ns*J`P~>J`SJ&(7({rZvU{| k{tdf*96h`e@BFmVE_OC From 73f249e00d0e57eb2cea5a4c527ad7ae89ae7c08 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Sun, 19 Dec 2021 23:29:28 +0800 Subject: [PATCH 15/54] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=97=A0=E7=94=A8?= =?UTF-8?q?=E7=9A=84doc=E6=96=87=E4=BB=B6=E5=A4=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- {leecode => algorithms/leecode}/__init__.py | 0 {leecode => algorithms/leecode}/a70_climbing_stairs.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {leecode => algorithms/leecode}/__init__.py (100%) rename {leecode => algorithms/leecode}/a70_climbing_stairs.py (100%) diff --git a/leecode/__init__.py b/algorithms/leecode/__init__.py similarity index 100% rename from leecode/__init__.py rename to algorithms/leecode/__init__.py diff --git a/leecode/a70_climbing_stairs.py b/algorithms/leecode/a70_climbing_stairs.py similarity index 100% rename from leecode/a70_climbing_stairs.py rename to algorithms/leecode/a70_climbing_stairs.py From 275087910c1fce4cb186f02ca14393fbb5e3d82c Mon Sep 17 00:00:00 2001 From: xiongneng Date: Tue, 8 Mar 2022 23:07:44 +0800 Subject: [PATCH 16/54] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- algorithms/ch01structure/linkedlist/__init__.py | 0 algorithms/ch01structure/linkedlist/lru_cache.py | 13 +++++++++++++ .../linkedlist/palindromic_number.py | 15 +++++++++++++++ algorithms/test.py | 9 +++++++++ 4 files changed, 37 insertions(+) create mode 100644 algorithms/ch01structure/linkedlist/__init__.py create mode 100644 algorithms/ch01structure/linkedlist/lru_cache.py create mode 100644 algorithms/ch01structure/linkedlist/palindromic_number.py create mode 100644 algorithms/test.py diff --git a/algorithms/ch01structure/linkedlist/__init__.py b/algorithms/ch01structure/linkedlist/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/algorithms/ch01structure/linkedlist/lru_cache.py b/algorithms/ch01structure/linkedlist/lru_cache.py new file mode 100644 index 0000000..5a26f47 --- /dev/null +++ b/algorithms/ch01structure/linkedlist/lru_cache.py @@ -0,0 +1,13 @@ +# -*- encoding: utf-8 -*- +""" +用单链表实现LRU缓存淘汰算法 + +我们维护一个单链表,越靠近链表尾部的结点是越早之前访问的。当有一个新的数据被访问时, +我们从链表头开始顺序遍历链表。 + +1. 如果此数据之前已经被缓存在链表中了,我们遍历得到这个数据对应的结点,并将其从原来的位置删除, +然后再插入到链表的头部。 +2. 如果此数据没有在缓存链表中,又可以分为两种情况: + 2.1 如果此时缓存未满,则将此结点直接插入到链表的头部; + 2.2 如果此时缓存已满,则链表尾结点删除,将新的数据结点插入链表的头部。 +""" diff --git a/algorithms/ch01structure/linkedlist/palindromic_number.py b/algorithms/ch01structure/linkedlist/palindromic_number.py new file mode 100644 index 0000000..a75c94e --- /dev/null +++ b/algorithms/ch01structure/linkedlist/palindromic_number.py @@ -0,0 +1,15 @@ +# -*- encoding: utf-8 -*- +""" +用单链表实现回文数的判断 + +由于回文串最重要的就是对称,那么最重要的问题就是找到那个中心,用快指针每步两格走,当他到达链表末端的时候, +慢指针刚好到达中心,慢指针在过来的这趟路上还做了一件事,他把走过的节点反向了,在中心点再开辟一个新的指针用于往回走, +而慢指针继续向前,当慢指针扫完整个链表,就可以判断这是回文串,否则就提前退出。 + +总的来说时间复杂度按慢指针遍历一遍来算是O(n),空间复杂度因为只开辟了3个额外的辅助,所以是o(1) + +1.1 奇数情况,中点位置不需要矫正 +1.2 偶数情况,使用偶数定位中点策略,要确定是返回上中位数或下中位数 + 1.2.1 如果是返回上中位数,后半部分串头取next + 1.2.2 如果是返回下中位数,后半部分串头既是当前节点位置,但前半部分串尾要删除掉当前节点 +""" diff --git a/algorithms/test.py b/algorithms/test.py new file mode 100644 index 0000000..aff6994 --- /dev/null +++ b/algorithms/test.py @@ -0,0 +1,9 @@ +class Father: + def __init__(self, choose_dir): + print(choose_dir) + self.choose_dir = choose_dir + + +if __name__ == '__main__': + Father("aa") + pass \ No newline at end of file From 6642a9a8e64a35fb50d3ac7dc2dbd327fae3704a Mon Sep 17 00:00:00 2001 From: xiongneng Date: Sun, 13 Mar 2022 18:25:24 +0800 Subject: [PATCH 17/54] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=93=BE=E8=A1=A8?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E7=BB=93=E6=9E=84=EF=BC=8C=E5=88=A9=E7=94=A8?= =?UTF-8?q?=E5=8D=95=E9=93=BE=E8=A1=A8=E5=AE=9E=E7=8E=B0LRU=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E7=AE=97=E6=B3=95=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- algorithms/ch01structure/__init__.py | 23 ++++- .../ch01structure/linkedlist/__init__.py | 4 + .../linkedlist/linked_list_double.py | 58 +++++++++++++ .../linkedlist/linked_list_double_cycle.py | 59 +++++++++++++ .../linkedlist/linked_list_single.py | 85 +++++++++++++++++++ .../linkedlist/linked_list_single_cycle.py | 57 +++++++++++++ .../ch01structure/linkedlist/lru_cache.py | 28 ++++++ .../ch01structure/queue/linked_queue.py | 2 +- algorithms/ch01structure/queue/prior_queue.py | 10 +-- .../ch01structure/stack/linked_stack.py | 4 +- algorithms/test.py | 5 +- 11 files changed, 321 insertions(+), 14 deletions(-) create mode 100644 algorithms/ch01structure/linkedlist/linked_list_double.py create mode 100644 algorithms/ch01structure/linkedlist/linked_list_double_cycle.py create mode 100644 algorithms/ch01structure/linkedlist/linked_list_single.py create mode 100644 algorithms/ch01structure/linkedlist/linked_list_single_cycle.py diff --git a/algorithms/ch01structure/__init__.py b/algorithms/ch01structure/__init__.py index b9d9d5c..c22fe25 100644 --- a/algorithms/ch01structure/__init__.py +++ b/algorithms/ch01structure/__init__.py @@ -5,11 +5,26 @@ class Node: """ - 节点信息 + 单指针节点 """ - def __init__(self, val_, next_=None): - self.val = val_ + + def __init__(self, data_, next_=None): + self.data = data_ + self.next = next_ + + def __str__(self): + return str(self.data) + + +class NodeDouble: + """ + 双指针节点 + """ + + def __init__(self, data_, next_=None, pre_=None): + self.data = data_ self.next = next_ + self.pre = pre_ def __str__(self): - return str(self.val) + return str(self.data) diff --git a/algorithms/ch01structure/linkedlist/__init__.py b/algorithms/ch01structure/linkedlist/__init__.py index e69de29..0b388f7 100644 --- a/algorithms/ch01structure/linkedlist/__init__.py +++ b/algorithms/ch01structure/linkedlist/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +链表数据结构 +""" diff --git a/algorithms/ch01structure/linkedlist/linked_list_double.py b/algorithms/ch01structure/linkedlist/linked_list_double.py new file mode 100644 index 0000000..3aaeaaf --- /dev/null +++ b/algorithms/ch01structure/linkedlist/linked_list_double.py @@ -0,0 +1,58 @@ +# -*- encoding: utf-8 -*- +""" +双向链表数据结构 +""" +from algorithms.ch01structure import NodeDouble + + +class LinkedListDouble: + """ + 双向链表,带哨兵 + """ + + def __init__(self): + self.head = NodeDouble(None) + + def insert_node(self, node, new_node): + """ + :param node:插入点节点 + :param new_node:新节点 + :return: + """ + new_node.next = node.next + new_node.pre = node + node.next = new_node + + def remove_node(self, node): + """ + :param node:待删除节点 + :return: + """ + if not node.pre: # 空表 + return + node.pre.next = node.next + if node.next: # 如果node有下一个节点 + node.next.pre = node.pre + + def search(self, data): + """ + 直接比较原始数据 + :param data: 待查询数据 + :return: 查询到的节点 + """ + target = self.head.next + while target and target.data != data: + target = target.next + return target + + def search_equal(self, data, equal): + """ + 通过传入equal比较函数来进行相等判断 + :param data: 待查询数据 + :param equal: 相等函数 + :return: 查询到的节点 + """ + target = self.head.next + while target and equal(target.data, data): + target = target.next + return target diff --git a/algorithms/ch01structure/linkedlist/linked_list_double_cycle.py b/algorithms/ch01structure/linkedlist/linked_list_double_cycle.py new file mode 100644 index 0000000..353a59f --- /dev/null +++ b/algorithms/ch01structure/linkedlist/linked_list_double_cycle.py @@ -0,0 +1,59 @@ +# -*- encoding: utf-8 -*- +""" +双向循环链表数据结构 +""" +from algorithms.ch01structure import NodeDouble + + +class LinkedListDouble: + """ + 双向循环链表,带哨兵 + """ + + def __init__(self): + head = NodeDouble(None) + head.pre = head.next = head # 将pre和next都指向自己 + self.head = head + + def insert_node(self, node, new_node): + """ + :param node:插入点节点 + :param new_node:新节点 + :return: + """ + new_node.next = node.next + new_node.pre = node + node.next = new_node + + def remove_node(self, node): + """ + :param node:待删除节点 + :return: + """ + if node == self.head: # 不能删除头节点 + return + node.pre.next = node.next + node.next.pre = node.pre + + def search(self, data): + """ + 直接比较原始数据 + :param data: 待查询数据 + :return: 查询到的节点 + """ + target = self.head.next + while target != self.head and target.data != data: + target = target.next + return target + + def search_equal(self, data, equal): + """ + 通过传入equal比较函数来进行相等判断 + :param data: 待查询数据 + :param equal: 相等函数 + :return: 查询到的节点 + """ + target = self.head.next + while target != self.head and equal(target.data, data): + target = target.next + return target diff --git a/algorithms/ch01structure/linkedlist/linked_list_single.py b/algorithms/ch01structure/linkedlist/linked_list_single.py new file mode 100644 index 0000000..e93105c --- /dev/null +++ b/algorithms/ch01structure/linkedlist/linked_list_single.py @@ -0,0 +1,85 @@ +# -*- encoding: utf-8 -*- +""" +单向链表数据结构 +""" +from algorithms.ch01structure import Node + + +class LinkedListSingle: + """ + 单向链表,带哨兵 + """ + + def __init__(self, limit): + self.head = Node(None) + self.size = 1 + self.limit = limit + 1 # 预留一个给哨兵头节点 + + def insert(self, node, new_node): + """ + :param node: 插入点节点 + :param new_node: 新节点 + :return: + """ + if self.size >= self.limit: + raise IndexError('list is full') + new_node.next = node.next + node.next = new_node + self.size += 1 + + def is_full(self): + return self.size >= self.limit + + def is_empty(self): + return self.size == 1 + + def remove(self, node): + """ + :param node: 待删除节点 + :return: + """ + if self.is_empty(): + return + pre_node = self.head + while pre_node.next != node: + pre_node = pre_node.next + pre_node.next = node.next + self.size -= 1 + + def get_tail(self): + target = self.head + while target.next: + target = target.next + return target + + def search(self, data): + """ + 直接比较原始数据 + :param data: 待查询数据 + :return: 查询到的节点 + """ + target = self.head.next + while target and target.data != data: + target = target.next + return target + + def search_equal(self, data, equal): + """ + 通过传入equal比较函数来进行相等判断 + :param data: 待查询数据 + :param equal: 相等函数 + :return: 查询到的节点 + """ + target = self.head.next + while target and equal(target.data, data): + target = target.next + return target + + def __iter__(self): + node = self.head.next + while node: + yield node.data + node = node.next + + def print(self): + print(list(x for x in self)) \ No newline at end of file diff --git a/algorithms/ch01structure/linkedlist/linked_list_single_cycle.py b/algorithms/ch01structure/linkedlist/linked_list_single_cycle.py new file mode 100644 index 0000000..ecdb62b --- /dev/null +++ b/algorithms/ch01structure/linkedlist/linked_list_single_cycle.py @@ -0,0 +1,57 @@ +# -*- encoding: utf-8 -*- +""" +单向循环链表数据结构 +""" +from algorithms.ch01structure import Node + + +class LinkedListSingleCycle: + """ + 单向循环链表,带哨兵 + """ + + def __init__(self): + self.head = Node(None) + self.head.next = self.head + + def insert_node(self, node, new_node): + """ + :param node:插入点节点 + :param new_node:新节点 + :return: + """ + new_node.next = node.next + node.next = new_node + + def remove_node(self, node): + """ + :param node:待删除节点 + :return: + """ + pre_node = self.head + while pre_node.next != node: + pre_node = pre_node.next + pre_node.next = node.next + + def search(self, data): + """ + 直接比较原始数据 + :param data: 待查询数据 + :return: 查询到的节点 + """ + target = self.head.next + while target != self.head and target.data != data: + target = target.next + return target + + def search_equal(self, data, equal): + """ + 通过传入equal比较函数来进行相等判断 + :param data: 待查询数据 + :param equal: 相等函数 + :return: 查询到的节点 + """ + target = self.head.next + while target != self.head and equal(target.data, data): + target = target.next + return target diff --git a/algorithms/ch01structure/linkedlist/lru_cache.py b/algorithms/ch01structure/linkedlist/lru_cache.py index 5a26f47..81a4c02 100644 --- a/algorithms/ch01structure/linkedlist/lru_cache.py +++ b/algorithms/ch01structure/linkedlist/lru_cache.py @@ -11,3 +11,31 @@ 2.1 如果此时缓存未满,则将此结点直接插入到链表的头部; 2.2 如果此时缓存已满,则链表尾结点删除,将新的数据结点插入链表的头部。 """ +from algorithms.ch01structure import Node +from algorithms.ch01structure.linkedlist.linked_list_single import LinkedListSingle + + +def lru(list_single_, data): + find_node = list_single_.search(data) + if find_node: + list_single_.remove(find_node) + list_single_.insert(list_single_.head, find_node) + else: + if not list_single_.is_full(): + list_single_.insert(list_single_.head, new_node = Node(data)) + else: + tail = list_single_.get_tail() + new_node = Node(data) + list_single_.remove(tail) + list_single_.insert(list_single_.head, new_node) + list_single_.print() + + +if __name__ == '__main__': + list_single = LinkedListSingle(3) + lru(list_single, 2) + lru(list_single, 3) + lru(list_single, 2) + lru(list_single, 1) + lru(list_single, 5) + lru(list_single, 6) diff --git a/algorithms/ch01structure/queue/linked_queue.py b/algorithms/ch01structure/queue/linked_queue.py index 3564dd2..44c9bc4 100644 --- a/algorithms/ch01structure/queue/linked_queue.py +++ b/algorithms/ch01structure/queue/linked_queue.py @@ -28,7 +28,7 @@ def enqueue(self, item): def dequeue(self): if self.is_empty(): raise LookupError('Queue underflow') - item = self.first.val + item = self.first.data self.first = self.first.next self.n -= 1 if self.is_empty(): diff --git a/algorithms/ch01structure/queue/prior_queue.py b/algorithms/ch01structure/queue/prior_queue.py index 22ed2f1..02a8b1a 100644 --- a/algorithms/ch01structure/queue/prior_queue.py +++ b/algorithms/ch01structure/queue/prior_queue.py @@ -1,6 +1,6 @@ # -*- encoding: utf-8 -*- -"""基于二叉堆实现的优先队列 -Some of description... +""" +基于二叉堆实现的优先队列 """ from functools import total_ordering @@ -69,9 +69,9 @@ def _sink(self, index): @total_ordering class Item: - def __init__(self, key, val, index=-1): + def __init__(self, key, data, index=-1): self.key = key - self.val = val + self.data = data self.index = index def __eq__(self, other): @@ -81,7 +81,7 @@ def __lt__(self, other): return self.key < other.key def __str__(self): - return str((self.val, self.key, self.index)) + return str((self.data, self.key, self.index)) if __name__ == '__main__': diff --git a/algorithms/ch01structure/stack/linked_stack.py b/algorithms/ch01structure/stack/linked_stack.py index e258edf..bcea94d 100644 --- a/algorithms/ch01structure/stack/linked_stack.py +++ b/algorithms/ch01structure/stack/linked_stack.py @@ -25,7 +25,7 @@ def push(self, item): def pop(self): if self.is_empty(): raise LookupError('Stack underflow') - result = self.first.val + result = self.first.data self.first = self.first.next self.n -= 1 return result @@ -33,7 +33,7 @@ def pop(self): def peek(self): if self.is_empty(): raise LookupError('Stack underflow') - return self.first.val + return self.first.data def __iter__(self): while self.n > 0: diff --git a/algorithms/test.py b/algorithms/test.py index aff6994..439f9c3 100644 --- a/algorithms/test.py +++ b/algorithms/test.py @@ -5,5 +5,6 @@ def __init__(self, choose_dir): if __name__ == '__main__': - Father("aa") - pass \ No newline at end of file + a = b = c = 2 + print(a,b,c) + pass From 16d77c37d52e870c8dacde795ae43f4742304949 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Mon, 14 Mar 2022 00:08:38 +0800 Subject: [PATCH 18/54] =?UTF-8?q?=E4=BD=BF=E7=94=A8=E5=BF=AB=E6=85=A2?= =?UTF-8?q?=E6=8C=87=E9=92=88=E5=AE=9E=E7=8E=B0=E5=9B=9E=E6=96=87=E6=95=B0?= =?UTF-8?q?=E7=9A=84=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ch01structure/linkedlist/lru_cache.py | 2 +- .../linkedlist/palindromic_number.py | 58 ++++++++++++++++++- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/algorithms/ch01structure/linkedlist/lru_cache.py b/algorithms/ch01structure/linkedlist/lru_cache.py index 81a4c02..091632c 100644 --- a/algorithms/ch01structure/linkedlist/lru_cache.py +++ b/algorithms/ch01structure/linkedlist/lru_cache.py @@ -1,6 +1,6 @@ # -*- encoding: utf-8 -*- """ -用单链表实现LRU缓存淘汰算法 +Question:怎样用单链表实现LRU缓存淘汰算法? 我们维护一个单链表,越靠近链表尾部的结点是越早之前访问的。当有一个新的数据被访问时, 我们从链表头开始顺序遍历链表。 diff --git a/algorithms/ch01structure/linkedlist/palindromic_number.py b/algorithms/ch01structure/linkedlist/palindromic_number.py index a75c94e..dc5a5d6 100644 --- a/algorithms/ch01structure/linkedlist/palindromic_number.py +++ b/algorithms/ch01structure/linkedlist/palindromic_number.py @@ -1,7 +1,8 @@ # -*- encoding: utf-8 -*- """ -用单链表实现回文数的判断 +Question:如果字符串是通过单链表来存储的,那该如何来判断是一个回文串? +快慢指针法实现过程: 由于回文串最重要的就是对称,那么最重要的问题就是找到那个中心,用快指针每步两格走,当他到达链表末端的时候, 慢指针刚好到达中心,慢指针在过来的这趟路上还做了一件事,他把走过的节点反向了,在中心点再开辟一个新的指针用于往回走, 而慢指针继续向前,当慢指针扫完整个链表,就可以判断这是回文串,否则就提前退出。 @@ -10,6 +11,59 @@ 1.1 奇数情况,中点位置不需要矫正 1.2 偶数情况,使用偶数定位中点策略,要确定是返回上中位数或下中位数 - 1.2.1 如果是返回上中位数,后半部分串头取next + 1.2.1 如果是返回上中位数,后半部分串头取next <<=这里使用这张上中位数数 1.2.2 如果是返回下中位数,后半部分串头既是当前节点位置,但前半部分串尾要删除掉当前节点 """ +from algorithms.ch01structure import Node +from algorithms.ch01structure.linkedlist.linked_list_single import LinkedListSingle + + +def palindromic(list_single_): + if list_single_.is_empty() or list_single_.size == 2: + return True + if list_single_.size == 3: + return list_single_.head.next.data == list_single_.head.next.next.data + + slow = list_single_.head.next.next # slow指向第2个节点 + slow_next = slow.next # 保存下一步的slow后驱节点 + fast = slow.next # fast指向第3个节点 + slow.next = list_single_.head.next # 第一个slow指针反向 + list_single_.head.next.next = None # 第一个节点下一个指针初始化为None + + while fast.next and fast.next.next: # 还能继续往前跑 + fast = fast.next.next # 快指针先往后面走2步 + slow_pre = slow # 临时保存slow + slow = slow_next # slow往后走1步 + slow_next = slow.next # 保存slow下一步的后驱节点 + slow.next = slow_pre # 将slow节点的next反转 + if not fast.next: # 奇数情况 + # 左边指针从slow.next开始,右边指针从slow_next开始 + slow = slow.next + if not slow: + return True + while slow: + if slow.data != slow_next.data: + return False + slow = slow.next + slow_next = slow_next.next + else: # 偶数情况 + # 左边指针从slow开始,右边指针从slow_next开始 + while slow: + if slow.data != slow_next.data: + return False + slow = slow.next + slow_next = slow_next.next + return True + + +if __name__ == '__main__': + list_single = LinkedListSingle(30) + list_single.insert(list_single.head, Node('d')) + list_single.insert(list_single.head, Node('a')) + list_single.insert(list_single.head, Node('b')) + list_single.insert(list_single.head, Node('c')) + list_single.insert(list_single.head, Node('b')) + list_single.insert(list_single.head, Node('a')) + list_single.insert(list_single.head, Node('d')) + list_single.print() + print(palindromic(list_single)) From cd8e54260e570710d64494763aa1cfae04371efd Mon Sep 17 00:00:00 2001 From: xiongneng Date: Mon, 14 Mar 2022 23:20:25 +0800 Subject: [PATCH 19/54] update leetcode 206 --- .../ch01structure/linkedlist/__init__.py | 8 +++ .../leecode/a206_reverse_linked_list.py | 57 +++++++++++++++++++ algorithms/test.py | 6 +- 3 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 algorithms/leecode/a206_reverse_linked_list.py diff --git a/algorithms/ch01structure/linkedlist/__init__.py b/algorithms/ch01structure/linkedlist/__init__.py index 0b388f7..902a5f2 100644 --- a/algorithms/ch01structure/linkedlist/__init__.py +++ b/algorithms/ch01structure/linkedlist/__init__.py @@ -1,4 +1,12 @@ # -*- encoding: utf-8 -*- """ 链表数据结构 + +练习题LeetCode对应编号:206,141,21,19,876 + +* 单链表反转 +* 链表中环的检测 +* 两个有序的链表合并 +* 删除链表倒数第 n 个结点 +* 求链表的中间结点 """ diff --git a/algorithms/leecode/a206_reverse_linked_list.py b/algorithms/leecode/a206_reverse_linked_list.py new file mode 100644 index 0000000..020b94b --- /dev/null +++ b/algorithms/leecode/a206_reverse_linked_list.py @@ -0,0 +1,57 @@ +# -*- encoding: utf-8 -*- +""" +206. 反转链表 +给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 +输入:head = [1,2,3,4,5] +输出:[5,4,3,2,1] + +提示: +链表中节点的数目范围是 [0, 5000] +-5000 <= Node.val <= 5000 + +进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题? +""" + + +# Definition for singly-linked list. +class ListNode: + def __init__(self, val=0, next=None): + self.val = val + self.next = next + + def __str__(self): + return str(self.val) + + +class Solution: + def reverseList(self, head: ListNode) -> ListNode: + if not head: + return None + head_next = head.next # 下一跳 + while head_next: + head_next_next = head_next.next + head_next.next = head + if head.next == head_next: # 头节点变尾结点 + head.next = None + head = head_next # head指针前移 + head_next = head_next_next # 重新赋值下一跳 + return head + + +if __name__ == '__main__': + # 本地运行需要以下输入输出的补充 + list_input = list(input('input list: ').split()) + + head = ListNode(1) + head.next = ListNode(2) + head.next.next = ListNode(3) + head.next.next.next = ListNode(4) + head.next.next.next.next = ListNode(5) + + # solve + solution = Solution() + res = solution.reverseList(head) + print() + # output + + diff --git a/algorithms/test.py b/algorithms/test.py index 439f9c3..be21951 100644 --- a/algorithms/test.py +++ b/algorithms/test.py @@ -5,6 +5,8 @@ def __init__(self, choose_dir): if __name__ == '__main__': - a = b = c = 2 - print(a,b,c) + # a = b = c = 2 + # print(a,b,c) + input("请输入三角形三边的长:") pass + From 580889d786cdd27fe7c5a113146d5cb3b173e1de Mon Sep 17 00:00:00 2001 From: xiongneng Date: Tue, 15 Mar 2022 23:23:08 +0800 Subject: [PATCH 20/54] update leetcode 21, 141 --- algorithms/leecode/a141_linked_list_cycle.py | 48 +++++++++++++++ .../leecode/a21_merge_two_sorted_lists.py | 60 +++++++++++++++++++ algorithms/test.py | 5 +- 3 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 algorithms/leecode/a141_linked_list_cycle.py create mode 100644 algorithms/leecode/a21_merge_two_sorted_lists.py diff --git a/algorithms/leecode/a141_linked_list_cycle.py b/algorithms/leecode/a141_linked_list_cycle.py new file mode 100644 index 0000000..c1b3e9c --- /dev/null +++ b/algorithms/leecode/a141_linked_list_cycle.py @@ -0,0 +1,48 @@ +# -*- encoding: utf-8 -*- +""" +141. 环形链表 +给你一个链表的头节点 head ,判断链表中是否有环。 + +如果链表中有某个节点,可以通过连续跟踪 next指针再次到达,则链表中存在环。 +不能直接通过判定next是否为null来决定是否有环,因为如有环则是一个无限循环。 + +通过快慢指针法,慢指针走一步,快指针走两步。 +如果快指针率先走到尽头结束,无环。 +否则快指针率先进环,慢指针则在后面进环。快指针一定会追上满指针,一旦追上了,循环结束。 +""" +# Definition for singly-linked list. +from typing import Optional + + +class ListNode: + def __init__(self, x): + self.val = x + self.next = None + + +class Solution: + def hasCycle(self, head: Optional[ListNode]) -> bool: + if not head or not head.next or not head.next.next: + return False + slow = head.next + fast = head.next.next + while slow != fast: + if not fast.next or not fast.next.next: + return False + slow = slow.next + fast = fast.next.next + return True + + +if __name__ == '__main__': + a = ListNode(1) + b = ListNode(2) + c = ListNode(3) + d = ListNode(4) + f = ListNode(5) + a.next = b + b.next = c + c.next = d + d.next = f + f.next = b + print(Solution().hasCycle(a)) diff --git a/algorithms/leecode/a21_merge_two_sorted_lists.py b/algorithms/leecode/a21_merge_two_sorted_lists.py new file mode 100644 index 0000000..71b9df4 --- /dev/null +++ b/algorithms/leecode/a21_merge_two_sorted_lists.py @@ -0,0 +1,60 @@ +# -*- encoding: utf-8 -*- +""" +21. 合并两个有序链表 + +将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 + +可使用类似贪吃蛇的算法。当前指针就像一条贪吃蛇一样,将两个队列节点一个个吃掉。 +任何时刻,都有一个队列是蛇,一个队列是食物。但是贪吃蛇一次只能吃一边的一个节点, +当它吃掉一个节点时,该节点所在的队列成为蛇的身体,另外一个队列成为食物。最后食物吃完循环结束。 +""" + +# Definition for singly-linked list. +from typing import Optional + + +class ListNode: + def __init__(self, val=0, next=None): + self.val = val + self.next = next + + def __str__(self): + return self.val + + +class Solution: + def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]: + if not list1: + return list2 + if not list2: + return list1 + result = list1 if list1.val <= list2.val else list2 + snake = result # 贪吃蛇指针 + food = list2 if list1.val <= list2.val else list1 # 要吞并的食物,跟蛇身取反 + while food: # 只要食物还在就一直吃下去 + if not snake.next: # 贪吃蛇自己到头了,就一口吃掉剩余所有食物,循环结束。 + snake.next = food + break + if snake.next.val <= food.val: + snake = snake.next # 自己的身体的下一部分比较小,就先吃自己。 + else: + temp_food = snake.next + snake.next = food # 食物比较小,先吃食物,让食物变成蛇的一部分 + food = temp_food # 将原来剩余的蛇身变成食物。这样完成了蛇身和食物的交换。 + return result + +if __name__ == '__main__': + a = ListNode(1) + b = ListNode(2) + c = ListNode(4) + a.next = b + b.next = c + + aa = ListNode(1) + bb = ListNode(3) + cc = ListNode(4) + aa.next = bb + bb.next = cc + + r = Solution().mergeTwoLists(a, aa) + print(r) diff --git a/algorithms/test.py b/algorithms/test.py index be21951..82c074b 100644 --- a/algorithms/test.py +++ b/algorithms/test.py @@ -7,6 +7,7 @@ def __init__(self, choose_dir): if __name__ == '__main__': # a = b = c = 2 # print(a,b,c) - input("请输入三角形三边的长:") + # input("请输入三角形三边的长:") + if not []: + print('ddd') pass - From 795e6e7243363f1ad7f065541d3d47baf0470ce1 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Wed, 16 Mar 2022 22:27:09 +0800 Subject: [PATCH 21/54] update leetcode 206 --- .../leecode/a206_reverse_linked_list.py | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/algorithms/leecode/a206_reverse_linked_list.py b/algorithms/leecode/a206_reverse_linked_list.py index 020b94b..0d0fab4 100644 --- a/algorithms/leecode/a206_reverse_linked_list.py +++ b/algorithms/leecode/a206_reverse_linked_list.py @@ -10,6 +10,8 @@ -5000 <= Node.val <= 5000 进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题? + +使用贪吃蛇算法,将原始链表比喻成糖葫芦,贪吃蛇一口一个,把糖葫芦吃完为止。 """ @@ -27,20 +29,20 @@ class Solution: def reverseList(self, head: ListNode) -> ListNode: if not head: return None - head_next = head.next # 下一跳 - while head_next: - head_next_next = head_next.next - head_next.next = head - if head.next == head_next: # 头节点变尾结点 - head.next = None - head = head_next # head指针前移 - head_next = head_next_next # 重新赋值下一跳 - return head + food = head + snake = None + + while food: + apple = food # 取下糖葫芦第一个苹果 + food = food.next # 糖葫芦减掉一个 + apple.next = snake # 吞掉一个苹果 + snake = apple # 调整蛇的头部指向这个苹果 + return snake if __name__ == '__main__': # 本地运行需要以下输入输出的补充 - list_input = list(input('input list: ').split()) + # list_input = list(input('input list: ').split()) head = ListNode(1) head.next = ListNode(2) From bd09a09dc8de592a45d8cdfe190c10fb91fa8ec9 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Thu, 17 Mar 2022 23:30:33 +0800 Subject: [PATCH 22/54] update leetcode 19 and 876 --- .../a19_remove_nth_node_from_end_of_list.py | 61 +++++++++++++++++ .../leecode/a876_middle_of_the_linked_list.py | 68 +++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 algorithms/leecode/a19_remove_nth_node_from_end_of_list.py create mode 100644 algorithms/leecode/a876_middle_of_the_linked_list.py diff --git a/algorithms/leecode/a19_remove_nth_node_from_end_of_list.py b/algorithms/leecode/a19_remove_nth_node_from_end_of_list.py new file mode 100644 index 0000000..43362a7 --- /dev/null +++ b/algorithms/leecode/a19_remove_nth_node_from_end_of_list.py @@ -0,0 +1,61 @@ +# -*- encoding: utf-8 -*- +""" +19. 删除单链表的倒数第N个结点 + +给你一个单链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 + +两轮循环: +1、第一轮循环获取链表的节点总数size。 +2、第二轮循环删除第size-n位置上的节点。 +""" + + +# Definition for singly-linked list. +class ListNode: + def __init__(self, val=0, next=None): + self.val = val + self.next = next + + def __str__(self): + return str(self.val) + + +class Solution: + def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode: + if not head: + return head + size = 0 + temp = head + while temp: + size += 1 + temp = temp.next + if n > size: + return head + + pre = None + remove_item = head + for _ in range(size - n): + pre = remove_item + remove_item = remove_item.next + if pre: + pre.next = remove_item.next + else: + head = remove_item.next + return head + + +if __name__ == '__main__': + # 本地运行需要以下输入输出的补充 + head = ListNode(1) + head.next = ListNode(2) + head.next.next = ListNode(3) + head.next.next.next = ListNode(4) + head.next.next.next.next = ListNode(5) + + # solve + solution = Solution() + res = solution.removeNthFromEnd(head, 5) + print() + # output + + diff --git a/algorithms/leecode/a876_middle_of_the_linked_list.py b/algorithms/leecode/a876_middle_of_the_linked_list.py new file mode 100644 index 0000000..936fbea --- /dev/null +++ b/algorithms/leecode/a876_middle_of_the_linked_list.py @@ -0,0 +1,68 @@ +# -*- encoding: utf-8 -*- +""" +876. 链表的中间结点 +给定一个头结点为 head 的非空单链表,返回链表的中间结点。 + +如果有两个中间结点,则返回第二个中间结点。 + +示例 1: +输入:[1,2,3,4,5] +输出:此列表中的结点 3 (序列化形式:[3,4,5]) +返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。 +注意,我们返回了一个 ListNode 类型的对象 ans,这样: +ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL. + +示例 2: +输入:[1,2,3,4,5,6] +输出:此列表中的结点 4 (序列化形式:[4,5,6]) +由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。 + +快慢指针经典案例。 +""" + + +# Definition for singly-linked list. +class ListNode: + def __init__(self, val=0, next=None): + self.val = val + self.next = next + + def __str__(self): + return str(self.val) + + def __iter__(self): + node = self + while node: + yield node.val + node = node.next + +class Solution: + def middleNode(self, head: ListNode) -> ListNode: + if not head: + return head + slow = fast = head + while fast.next and fast.next.next: + slow = slow.next + fast = fast.next.next + if fast.next: # 偶数情况 + return slow.next + else: + return slow + + +if __name__ == '__main__': + # input + # list_input = list(input('input list: ').split()) + head = ListNode(1) + head.next = ListNode(2) + head.next.next = ListNode(3) + head.next.next.next = ListNode(4) + head.next.next.next.next = ListNode(5) + head.next.next.next.next.next = ListNode(6) + # solve + solution = Solution() + res = solution.middleNode(head) + # output + print(list(res)) + + From b918c4612d9b7d74beabf6e1e0d4f99ec20b77f8 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Thu, 17 Mar 2022 23:41:33 +0800 Subject: [PATCH 23/54] update leetcode package --- algorithms/leecode/p000/__init__.py | 4 ++++ .../{ => p000}/a19_remove_nth_node_from_end_of_list.py | 0 algorithms/leecode/{ => p000}/a21_merge_two_sorted_lists.py | 0 algorithms/leecode/{ => p000}/a70_climbing_stairs.py | 0 algorithms/leecode/p100/__init__.py | 4 ++++ algorithms/leecode/{ => p100}/a141_linked_list_cycle.py | 0 algorithms/leecode/p1000/__init__.py | 4 ++++ algorithms/leecode/p1100/__init__.py | 4 ++++ algorithms/leecode/p1200/__init__.py | 4 ++++ algorithms/leecode/p1300/__init__.py | 4 ++++ algorithms/leecode/p1400/__init__.py | 4 ++++ algorithms/leecode/p1500/__init__.py | 4 ++++ algorithms/leecode/p1600/__init__.py | 4 ++++ algorithms/leecode/p1700/__init__.py | 4 ++++ algorithms/leecode/p1800/__init__.py | 4 ++++ algorithms/leecode/p1900/__init__.py | 4 ++++ algorithms/leecode/p200/__init__.py | 4 ++++ algorithms/leecode/{ => p200}/a206_reverse_linked_list.py | 0 algorithms/leecode/p2000/__init__.py | 4 ++++ algorithms/leecode/p2100/__init__.py | 4 ++++ algorithms/leecode/p2200/__init__.py | 4 ++++ algorithms/leecode/p300/__init__.py | 4 ++++ algorithms/leecode/p400/__init__.py | 4 ++++ algorithms/leecode/p500/__init__.py | 4 ++++ algorithms/leecode/p600/__init__.py | 4 ++++ algorithms/leecode/p700/__init__.py | 4 ++++ algorithms/leecode/p800/__init__.py | 4 ++++ .../leecode/{ => p800}/a876_middle_of_the_linked_list.py | 0 algorithms/leecode/p900/__init__.py | 4 ++++ 29 files changed, 92 insertions(+) create mode 100644 algorithms/leecode/p000/__init__.py rename algorithms/leecode/{ => p000}/a19_remove_nth_node_from_end_of_list.py (100%) rename algorithms/leecode/{ => p000}/a21_merge_two_sorted_lists.py (100%) rename algorithms/leecode/{ => p000}/a70_climbing_stairs.py (100%) create mode 100644 algorithms/leecode/p100/__init__.py rename algorithms/leecode/{ => p100}/a141_linked_list_cycle.py (100%) create mode 100644 algorithms/leecode/p1000/__init__.py create mode 100644 algorithms/leecode/p1100/__init__.py create mode 100644 algorithms/leecode/p1200/__init__.py create mode 100644 algorithms/leecode/p1300/__init__.py create mode 100644 algorithms/leecode/p1400/__init__.py create mode 100644 algorithms/leecode/p1500/__init__.py create mode 100644 algorithms/leecode/p1600/__init__.py create mode 100644 algorithms/leecode/p1700/__init__.py create mode 100644 algorithms/leecode/p1800/__init__.py create mode 100644 algorithms/leecode/p1900/__init__.py create mode 100644 algorithms/leecode/p200/__init__.py rename algorithms/leecode/{ => p200}/a206_reverse_linked_list.py (100%) create mode 100644 algorithms/leecode/p2000/__init__.py create mode 100644 algorithms/leecode/p2100/__init__.py create mode 100644 algorithms/leecode/p2200/__init__.py create mode 100644 algorithms/leecode/p300/__init__.py create mode 100644 algorithms/leecode/p400/__init__.py create mode 100644 algorithms/leecode/p500/__init__.py create mode 100644 algorithms/leecode/p600/__init__.py create mode 100644 algorithms/leecode/p700/__init__.py create mode 100644 algorithms/leecode/p800/__init__.py rename algorithms/leecode/{ => p800}/a876_middle_of_the_linked_list.py (100%) create mode 100644 algorithms/leecode/p900/__init__.py diff --git a/algorithms/leecode/p000/__init__.py b/algorithms/leecode/p000/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/leecode/p000/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" diff --git a/algorithms/leecode/a19_remove_nth_node_from_end_of_list.py b/algorithms/leecode/p000/a19_remove_nth_node_from_end_of_list.py similarity index 100% rename from algorithms/leecode/a19_remove_nth_node_from_end_of_list.py rename to algorithms/leecode/p000/a19_remove_nth_node_from_end_of_list.py diff --git a/algorithms/leecode/a21_merge_two_sorted_lists.py b/algorithms/leecode/p000/a21_merge_two_sorted_lists.py similarity index 100% rename from algorithms/leecode/a21_merge_two_sorted_lists.py rename to algorithms/leecode/p000/a21_merge_two_sorted_lists.py diff --git a/algorithms/leecode/a70_climbing_stairs.py b/algorithms/leecode/p000/a70_climbing_stairs.py similarity index 100% rename from algorithms/leecode/a70_climbing_stairs.py rename to algorithms/leecode/p000/a70_climbing_stairs.py diff --git a/algorithms/leecode/p100/__init__.py b/algorithms/leecode/p100/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/leecode/p100/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" diff --git a/algorithms/leecode/a141_linked_list_cycle.py b/algorithms/leecode/p100/a141_linked_list_cycle.py similarity index 100% rename from algorithms/leecode/a141_linked_list_cycle.py rename to algorithms/leecode/p100/a141_linked_list_cycle.py diff --git a/algorithms/leecode/p1000/__init__.py b/algorithms/leecode/p1000/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/leecode/p1000/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" diff --git a/algorithms/leecode/p1100/__init__.py b/algorithms/leecode/p1100/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/leecode/p1100/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" diff --git a/algorithms/leecode/p1200/__init__.py b/algorithms/leecode/p1200/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/leecode/p1200/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" diff --git a/algorithms/leecode/p1300/__init__.py b/algorithms/leecode/p1300/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/leecode/p1300/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" diff --git a/algorithms/leecode/p1400/__init__.py b/algorithms/leecode/p1400/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/leecode/p1400/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" diff --git a/algorithms/leecode/p1500/__init__.py b/algorithms/leecode/p1500/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/leecode/p1500/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" diff --git a/algorithms/leecode/p1600/__init__.py b/algorithms/leecode/p1600/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/leecode/p1600/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" diff --git a/algorithms/leecode/p1700/__init__.py b/algorithms/leecode/p1700/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/leecode/p1700/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" diff --git a/algorithms/leecode/p1800/__init__.py b/algorithms/leecode/p1800/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/leecode/p1800/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" diff --git a/algorithms/leecode/p1900/__init__.py b/algorithms/leecode/p1900/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/leecode/p1900/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" diff --git a/algorithms/leecode/p200/__init__.py b/algorithms/leecode/p200/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/leecode/p200/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" diff --git a/algorithms/leecode/a206_reverse_linked_list.py b/algorithms/leecode/p200/a206_reverse_linked_list.py similarity index 100% rename from algorithms/leecode/a206_reverse_linked_list.py rename to algorithms/leecode/p200/a206_reverse_linked_list.py diff --git a/algorithms/leecode/p2000/__init__.py b/algorithms/leecode/p2000/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/leecode/p2000/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" diff --git a/algorithms/leecode/p2100/__init__.py b/algorithms/leecode/p2100/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/leecode/p2100/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" diff --git a/algorithms/leecode/p2200/__init__.py b/algorithms/leecode/p2200/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/leecode/p2200/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" diff --git a/algorithms/leecode/p300/__init__.py b/algorithms/leecode/p300/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/leecode/p300/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" diff --git a/algorithms/leecode/p400/__init__.py b/algorithms/leecode/p400/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/leecode/p400/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" diff --git a/algorithms/leecode/p500/__init__.py b/algorithms/leecode/p500/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/leecode/p500/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" diff --git a/algorithms/leecode/p600/__init__.py b/algorithms/leecode/p600/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/leecode/p600/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" diff --git a/algorithms/leecode/p700/__init__.py b/algorithms/leecode/p700/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/leecode/p700/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" diff --git a/algorithms/leecode/p800/__init__.py b/algorithms/leecode/p800/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/leecode/p800/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" diff --git a/algorithms/leecode/a876_middle_of_the_linked_list.py b/algorithms/leecode/p800/a876_middle_of_the_linked_list.py similarity index 100% rename from algorithms/leecode/a876_middle_of_the_linked_list.py rename to algorithms/leecode/p800/a876_middle_of_the_linked_list.py diff --git a/algorithms/leecode/p900/__init__.py b/algorithms/leecode/p900/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/leecode/p900/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" From 2bc181f8bfc10bfa2eea3514dfc64bf4ba536a1d Mon Sep 17 00:00:00 2001 From: xiongneng Date: Fri, 18 Mar 2022 22:02:46 +0800 Subject: [PATCH 24/54] leetcode 20 --- algorithms/ch01structure/queue/prior_queue.py | 4 +- algorithms/ch01structure/stack/__init__.py | 5 +- algorithms/ch01structure/stack/stack_array.py | 54 +++++++++++++++++++ .../{linked_stack.py => stack_linked_list.py} | 6 +-- .../leecode/p000/a20_valid_parentheses.py | 52 ++++++++++++++++++ 5 files changed, 115 insertions(+), 6 deletions(-) create mode 100644 algorithms/ch01structure/stack/stack_array.py rename algorithms/ch01structure/stack/{linked_stack.py => stack_linked_list.py} (91%) create mode 100644 algorithms/leecode/p000/a20_valid_parentheses.py diff --git a/algorithms/ch01structure/queue/prior_queue.py b/algorithms/ch01structure/queue/prior_queue.py index 02a8b1a..7c5eb6b 100644 --- a/algorithms/ch01structure/queue/prior_queue.py +++ b/algorithms/ch01structure/queue/prior_queue.py @@ -4,7 +4,7 @@ """ from functools import total_ordering -from algorithms.ch01structure.stack.linked_stack import Stack +from algorithms.ch01structure.stack.stack_linked_list import LinkedStack class MaxPriorQueue: @@ -96,7 +96,7 @@ def __str__(self): for item in items: prior_queue.insert(item) - stack = Stack() + stack = LinkedStack() while not prior_queue.is_empty(): stack.push(prior_queue.del_max()) for item in stack: diff --git a/algorithms/ch01structure/stack/__init__.py b/algorithms/ch01structure/stack/__init__.py index dbc8407..f7d38c9 100644 --- a/algorithms/ch01structure/stack/__init__.py +++ b/algorithms/ch01structure/stack/__init__.py @@ -1,5 +1,8 @@ # -*- encoding: utf-8 -*- """ -description... +栈数据结构 + +LeetCode题目: +20,155,232,844,224,682,496 """ diff --git a/algorithms/ch01structure/stack/stack_array.py b/algorithms/ch01structure/stack/stack_array.py new file mode 100644 index 0000000..a0d1bba --- /dev/null +++ b/algorithms/ch01structure/stack/stack_array.py @@ -0,0 +1,54 @@ +# -*- encoding: utf-8 -*- +""" +基于数组实现的栈结构 +""" +from algorithms.ch01structure import Node + + +class ArrayStack: + def __init__(self, size): + self.items = [None] * size # 初始数组大小 + self.size = size # size of the stack + self.num = 0 # 元素的个数 + + def push(self, item): + """ + 入栈操作 + :param item: 入栈数据 + :return: 是否入栈成功 + """ + # 数组空间不够了,直接返回false,入栈失败。 + if self.num == self.size: + return False + # 将item放到下标为num的位置,并且num加一 + self.items[self.num] = Node(item) + self.num += 1 + return True + + def pop(self): + if self.num == 0: + return None + result = self.items[self.num - 1].data + self.items[self.num - 1] = None + self.num -= 1 + return result + + def peek(self): + if self.num == 0: + return None + return self.items[0].data + + def __iter__(self): + while self.num > 0: + yield self.pop() + +if __name__ == '__main__': + s = ArrayStack(3) + s.push(1) + s.push(2) + s.push(3) + print("-----------------") + print(s.pop()) + print(s.pop()) + print(s.pop()) + print("=================") \ No newline at end of file diff --git a/algorithms/ch01structure/stack/linked_stack.py b/algorithms/ch01structure/stack/stack_linked_list.py similarity index 91% rename from algorithms/ch01structure/stack/linked_stack.py rename to algorithms/ch01structure/stack/stack_linked_list.py index bcea94d..8e1d871 100644 --- a/algorithms/ch01structure/stack/linked_stack.py +++ b/algorithms/ch01structure/stack/stack_linked_list.py @@ -7,7 +7,7 @@ from algorithms.ch01structure import Node -class Stack: +class LinkedStack: def __init__(self): self.first = None # top of stack self.n = 0 # size of the stack @@ -24,7 +24,7 @@ def push(self, item): def pop(self): if self.is_empty(): - raise LookupError('Stack underflow') + return None result = self.first.data self.first = self.first.next self.n -= 1 @@ -32,7 +32,7 @@ def pop(self): def peek(self): if self.is_empty(): - raise LookupError('Stack underflow') + return None return self.first.data def __iter__(self): diff --git a/algorithms/leecode/p000/a20_valid_parentheses.py b/algorithms/leecode/p000/a20_valid_parentheses.py new file mode 100644 index 0000000..dfb688a --- /dev/null +++ b/algorithms/leecode/p000/a20_valid_parentheses.py @@ -0,0 +1,52 @@ +# -*- encoding: utf-8 -*- +""" +20. 有效的括号 + +给定一个只包括 '(',')','{','}','[',']' 的字符串s ,判断字符串是否有效。 + +有效字符串需满足: + +左括号必须用相同类型的右括号闭合。 +左括号必须以正确的顺序闭合。 + +示例 2: +输入:s = "()[]{}" +输出:true + +示例 4: +输入:s = "([)]" +输出:false + +例 5: +输入:s = "{[]}" +输出:true + +算法思路:栈的最简单的应用。左括号入栈,右括号出栈+对比匹配。不匹配则False,最后栈空则True +""" +from algorithms.ch01structure.stack.stack_linked_list import LinkedStack + + +class Solution: + def isValid(self, s: str) -> bool: + p_map = {'{': '}', '[': ']', '(': ')'} + stack = LinkedStack() + for ch in s: + if ch in p_map: + stack.push(ch) + else: + stack_item = stack.pop() + if stack_item not in p_map or ch != p_map[stack_item]: + return False + return stack.is_empty() + + +if __name__ == '__main__': + # print(Solution().isValid(']]]')) + print(Solution().isValid(']')) + # s = input('input something: ') + # print(s) + # while True: + # s = input() + # if not s: + # break + # print(Solution().isValid(s)) From 39be9cf6501496d022feb9fd62d09db34f778d46 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Fri, 18 Mar 2022 23:33:04 +0800 Subject: [PATCH 25/54] leetcode 155 --- algorithms/leecode/p100/a155_min_stack.py | 57 +++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 algorithms/leecode/p100/a155_min_stack.py diff --git a/algorithms/leecode/p100/a155_min_stack.py b/algorithms/leecode/p100/a155_min_stack.py new file mode 100644 index 0000000..4c6f81a --- /dev/null +++ b/algorithms/leecode/p100/a155_min_stack.py @@ -0,0 +1,57 @@ +# -*- encoding: utf-8 -*- +""" +155. 最小栈 +设计一个支持 push、pop、top 操作,并能在常数时间内检索到最小元素的栈。 + +实现 MinStack 类: + +MinStack() 初始化堆栈对象。 +void push(int val) 将元素val推入堆栈。 +void pop() 删除堆栈顶部的元素。 +int top() 获取堆栈顶部的元素。 +int getMin() 获取堆栈中的最小元素。 + +算法思路: +通过空间换时间的方法。将每次入栈的节点包装成一个对象,存储两个信息,一个是节点值,一个是当前栈的最小值。 +这样获取栈顶元素就同时能获取到这两个值了。 +""" +from algorithms.ch01structure import Node + + +class MinStack: + + def __init__(self): + self.first = None # top of stack + + def push(self, val: int) -> None: + current_min = self.getMin() + min_val = min(val, current_min) if current_min is not None else val + self.first = Node((val, min_val), self.first) + + def pop(self) -> None: + if self.first: + self.first = self.first.next + + + def top(self) -> int: + if not self.first: + return None + return self.first.data[0] + + + def getMin(self) -> int: + if not self.first: + return None + return self.first.data[1] + + +if __name__ == '__main__': + pass + # Your MinStack object will be instantiated and called as such: + obj = MinStack() + obj.push(0) + obj.push(1) + obj.push(0) + print(obj.getMin()) + obj.pop() + print(obj.getMin()) From 9047a938e140149361332f971e29f92f3ebb8a09 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Sat, 19 Mar 2022 00:17:51 +0800 Subject: [PATCH 26/54] leetcode 232 --- .../p200/a232_implement_queue_using_stacks.py | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 algorithms/leecode/p200/a232_implement_queue_using_stacks.py diff --git a/algorithms/leecode/p200/a232_implement_queue_using_stacks.py b/algorithms/leecode/p200/a232_implement_queue_using_stacks.py new file mode 100644 index 0000000..98e651f --- /dev/null +++ b/algorithms/leecode/p200/a232_implement_queue_using_stacks.py @@ -0,0 +1,88 @@ +# -*- encoding: utf-8 -*- +""" +232. 用栈实现队列 +请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty) + +实现 MyQueue 类: +void push(int x) 将元素 x 推到队列的末尾 +int pop() 从队列的开头移除并返回元素 +int peek() 返回队列开头的元素 +boolean empty() 如果队列为空,返回 true ;否则,返回 false + +说明: +你只能使用标准的栈操作,也就是只有push to top, peek/pop from top, size,和is empty作是合法的。 +你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。 + +算法思路: +两个栈,左边栈用于最终存放数据,右边栈只是临时来交换数据用。每次push新数据的时候, +先将左边栈所有的数据一个个压到右边栈,然后将新数据压到左边栈底,再将右边栈一个个压到左边栈。 +""" + + +class ListNode: + def __init__(self, val_, next_=None): + self.val = val_ + self.next = next_ + + def __str__(self): + return str(self.val) + + +class MyStack: + def __init__(self): + self.first = None + + def push(self, val): + self.first = ListNode(val, self.first) + + def pop(self): + if not self.first: + return None + res = self.first.val + self.first = self.first.next + return res + + def empty(self): + return self.first is None + + +class MyQueue: + + def __init__(self): + self.left_stack = MyStack() + self.right_stack = MyStack() + + def push(self, x: int) -> None: + # 先将左栈全部压入右栈 + while not self.left_stack.empty(): + self.right_stack.push(self.left_stack.pop()) + # 然后将新数据压入左栈底 + self.left_stack.push(x) + # 最后将右栈全部压入左栈 + while not self.right_stack.empty(): + self.left_stack.push(self.right_stack.pop()) + + def pop(self) -> int: + if self.left_stack.empty(): + return None + return self.left_stack.pop() + + def peek(self) -> int: + if self.left_stack.empty(): + return None + return self.left_stack.first.val + + def empty(self) -> bool: + return self.left_stack.empty() + + +if __name__ == '__main__': + # Your MyQueue object will be instantiated and called as such: + obj = MyQueue() + obj.push(1) + obj.push(2) + obj.push(3) + param_2 = obj.pop() + param_3 = obj.peek() + param_4 = obj.empty() + print(param_2, param_3, param_4) From 4dac4f0b760d40e3bdd1f5a1b848e7f13e95cfd2 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Sat, 19 Mar 2022 13:38:43 +0800 Subject: [PATCH 27/54] leetcode 224 --- algorithms/ch01structure/stack/__init__.py | 2 +- .../leecode/p200/a224_basic_calculator.py | 138 ++++++++++++++++++ algorithms/test.py | 10 +- 3 files changed, 143 insertions(+), 7 deletions(-) create mode 100644 algorithms/leecode/p200/a224_basic_calculator.py diff --git a/algorithms/ch01structure/stack/__init__.py b/algorithms/ch01structure/stack/__init__.py index f7d38c9..a5daaa1 100644 --- a/algorithms/ch01structure/stack/__init__.py +++ b/algorithms/ch01structure/stack/__init__.py @@ -3,6 +3,6 @@ 栈数据结构 LeetCode题目: -20,155,232,844,224,682,496 +20,155,224,232,496,844,682 """ diff --git a/algorithms/leecode/p200/a224_basic_calculator.py b/algorithms/leecode/p200/a224_basic_calculator.py new file mode 100644 index 0000000..4158d11 --- /dev/null +++ b/algorithms/leecode/p200/a224_basic_calculator.py @@ -0,0 +1,138 @@ +# -*- encoding: utf-8 -*- +""" +224. 基本计算器 + +给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。 + +注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval()。 + +输入:s = "1 + 1" +输出:2 + +输入:s = " 2-1 + 2 " +输出:3 + +输入:s = "(1+(4+5+2)-3)+(6+8)" +输出:23 + +算法描述:使用两个栈来实现。 +正常不带括号的+-*/运算的逻辑: + 1)操作数有优先级,+-优先级低,*/优先级高。 + 2)左栈压入数字,右栈压入操作数。 + 3)每次向右栈压入操作数的时候,先对比栈顶操作数跟当前要入栈操作数优先级。 + i:如果当前入栈优先级高,就直接入栈。 + ii:否则将栈顶操作数弹出,并从左栈弹出2个数来做运算。将结果再次压入左栈 + iii:最后将当前要入栈的操作数入栈 + 4)循环结束后,如果操作数栈还有剩余操作数。就每次右栈弹1个操作数,左栈弹2个数做运算。结果入左栈 + 5)最后判断左栈是否只剩下一个数,如果是则返回结果。否则表达式有问题,报错。 + +带括号()的+-*/运算的逻辑: + 1)操作数有优先级,+-优先级低,*/优先级高。 + 2)左栈压入数字,右栈压入操作数。 + 3)每次向右栈压入操作数的时候逻辑如下: + i:如果碰到(直接入栈。 + ii:如果当前为操作符+-*/,并且栈顶为(,直接入栈。 + iii:如果当前为操作符+-*/,并且栈顶不为(,则对比两者优先级 + iii-a:如果当前入栈优先级高,就直接入栈。 + iii-b:否则将栈顶操作数弹出,并从左栈弹出2个数来做运算。将结果再次压入左栈。然后再将当前操作符压入右栈 + IV:如果当前为操作符),则循环从右栈弹1个操作数,左栈弹2个数做运算压入左栈。直到弹出第一个(为止。 + 4)循环结束后,如果操作数栈还有剩余操作数。就每次右栈弹1个操作数,左栈弹2个数做运算。结果入左栈 + 5)最后判断左栈是否只剩下一个数,如果是则返回结果。否则表达式有问题,报错。 +""" +import re + + +class LinkedNode: + def __init__(self, val_, next_=None): + self.val = val_ + self.next = next_ + + def __str__(self): + return str(self.val) + + +class LinkedStack: + def __init__(self): + self.first = None + + def push(self, val): + self.first = LinkedNode(val, self.first) + + def pop(self): + if not self.first: + return None + res = self.first.val + self.first = self.first.next + return res + + def peek(self): + if not self.first: + return None + return self.first.val + + def empty(self): + return self.first is None + + +class Solution: + def __init__(self): + self.left_stack = LinkedStack() + self.right_stack = LinkedStack() + self.calc_funcs = { + '+': lambda a, b: a + b, + '-': lambda a, b: a - b, + '*': lambda a, b: a * b, + '/': lambda a, b: a / b, + } + + def calculate(self, s: str) -> int: + expression = s.replace(' ', '') # 去掉空格 + expression = '0' + expression if expression.startswith('-') else expression + expression = expression.replace('(-', '(0-') + expression_list = [s for s in re.split(r'([()+*/])|((?<=[\d)])-)', expression) if s] + for c in expression_list: + if self.is_number(c): + self.left_stack.push(int(c)) + else: + if c == '(': + self.right_stack.push(c) + elif c in '+-*/' and self.right_stack.peek() == '(': + self.right_stack.push(c) + elif c in '+-*/' and self.right_stack.peek() != '(': + if c in '*/' and self.right_stack.peek() in '+-': + self.right_stack.push(c) + else: + self.calc_unit() + self.right_stack.push(c) + elif c == ')': + while self.right_stack.peek() != '(': + self.calc_unit() + self.right_stack.pop() + else: + raise ValueError('wrong cal expression') + while not self.right_stack.empty(): + self.calc_unit() + if self.left_stack.first.next is not None: + raise ValueError('wrong input expression') + return self.left_stack.pop() + + def is_number(self, str_): + try: + int(str_) + return True + except ValueError: + return False + + def calc_unit(self): + if self.right_stack.empty(): + return + cal = self.right_stack.pop() + val2 = self.left_stack.pop() + val1 = self.left_stack.pop() + if val2 is None or val1 is None: + raise ValueError('wrong number expression') + self.left_stack.push(self.calc_funcs[cal](val1, val2)) + + +if __name__ == '__main__': + print(Solution().calculate("- (3 - (- (4 + 5) ) )")) diff --git a/algorithms/test.py b/algorithms/test.py index 82c074b..3095b32 100644 --- a/algorithms/test.py +++ b/algorithms/test.py @@ -5,9 +5,7 @@ def __init__(self, choose_dir): if __name__ == '__main__': - # a = b = c = 2 - # print(a,b,c) - # input("请输入三角形三边的长:") - if not []: - print('ddd') - pass + import re + ss = re.split(r'([()+*/])|((?<=\d)-)', '(-12+(4+5+2)-3)+(-6+8)') + s = [s for s in ss if s] + print(s) From 988d9bff8a92c740c8fef880f5739b55abd9e0a9 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Sat, 19 Mar 2022 17:54:12 +0800 Subject: [PATCH 28/54] leetcode 496 --- .../leecode/p400/a496_next_greater_element.py | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 algorithms/leecode/p400/a496_next_greater_element.py diff --git a/algorithms/leecode/p400/a496_next_greater_element.py b/algorithms/leecode/p400/a496_next_greater_element.py new file mode 100644 index 0000000..2b94d08 --- /dev/null +++ b/algorithms/leecode/p400/a496_next_greater_element.py @@ -0,0 +1,98 @@ +# -*- encoding: utf-8 -*- +""" +496. 下一个更大元素 I +nums1中数字x的下一个更大元素是指x在nums2中对应位置右侧的第一个比x大的元素。 + +给你两个没有重复元素的数组nums1和nums2,下标从0开始计数,其中nums1是nums2的子集。 + +对于每个 0 <= i < nums1.length ,找出满足 nums1[i] == nums2[j] 的下标 j , +并且在nums2确定nums2[j]的下一个更大元素。如果不存在下一个更大元素,那么本次查询的答案是-1 。 + +返回一个长度为nums1.length的数组 ans 作为答案,满足ans[i]是如上所述的下一个更大元素。 + +输入:nums1 = [4,1,2], nums2 = [1,3,4,2]. +输出:[-1,3,-1] +解释:nums1 中每个值的下一个更大元素如下所述: +- 4 ,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。 +- 1 ,nums2 = [1,3,4,2]。下一个更大元素是 3 。 +- 2 ,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。 + +输入:nums1 = [2,4], nums2 = [1,2,3,4]. +输出:[3,-1] +解释:nums1 中每个值的下一个更大元素如下所述: +- 2 ,nums2 = [1,2,3,4]。下一个更大元素是 3 。 +- 4 ,nums2 = [1,2,3,4]。不存在下一个更大元素,所以答案是 -1。 + +进阶:你可以设计一个时间复杂度为 O(nums1.length + nums2.length) 的解决方案吗? + +算法思路: +这个问题可以这样抽象思考:把数组的元素想象成并列站立的人,元素大小想象成人的身高。这些人面对你站成一列, +如何求元素「2」的 Next Greater Number 呢?很简单,如果能够看到元素「2」, +那么他后面可见的第一个人就是「2」的 Next Greater Number,因为比「2」小的元素身高不够,都被「2」挡住了, +第一个露出来的就是答案。 + +单调栈解决问题的模板。for 循环要从后往前扫描元素,因为我们借助的是栈的结构,倒着入栈, +其实是正着出栈。while 循环是把两个“高个”元素之间的元素排除,因为他们的存在没有意义,前面挡着个“更高”的元素, +所以他们不可能被作为后续进来的元素的 Next Great Number 了。 + +这个算法的时间复杂度不是那么直观,如果你看到 for 循环嵌套 while 循环,可能认为这个算法的复杂度也是 O(n^2), +但是实际上这个算法的复杂度只有 O(n)。 + +分析它的时间复杂度,要从整体来看:总共有 n 个元素,每个元素都被 push 入栈了一次,而最多会被 pop 一次, +没有任何冗余操作。所以总的计算规模是和元素规模 n 成正比的,也就是 O(n) 的复杂度。 + +先用单调栈找到nums2每个元素对应的下个最大元素,然后装入Map中。后面对于num1的求值直接从Map中获取。 +""" +from typing import List + + +class LinkedNode: + def __init__(self, val_, next_=None): + self.val = val_ + self.next = next_ + + def __str__(self): + return str(self.val) + + +class LinkedStack: + def __init__(self): + self.first = None + + def push(self, val): + self.first = LinkedNode(val, self.first) + + def pop(self): + if not self.first: + return None + res = self.first.val + self.first = self.first.next + return res + + def peek(self): + if not self.first: + return None + return self.first.val + + def empty(self): + return self.first is None + + +class Solution: + def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]: + nums2_size = len(nums2) + nums2_map = {} # 存放num2的单调栈 + count = 0 + stack = LinkedStack() # 存放高个元素的栈 + for item in nums2[::-1]: + while not stack.empty() and nums2[nums2_size - 1 - count] > stack.peek(): + stack.pop() # 把中间小的数剔除掉 + nums2_map[item] = -1 if stack.empty() else stack.peek() + stack.push(item) # 然后再把这个数入栈,接受后面的身高判定 + count += 1 + return [nums2_map[i] for i in nums1] + + +if __name__ == '__main__': + ans = Solution().nextGreaterElement([4, 1, 2], [1, 3, 4, 2]) + print(ans) From 3dc95781ba6735d9efa47eaa86d0d8d6bf528087 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Sat, 19 Mar 2022 20:38:54 +0800 Subject: [PATCH 29/54] leetcode 682 --- algorithms/ch01structure/stack/__init__.py | 2 +- algorithms/leecode/p600/a682_baseball_game.py | 109 ++++++++++++++++++ 2 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 algorithms/leecode/p600/a682_baseball_game.py diff --git a/algorithms/ch01structure/stack/__init__.py b/algorithms/ch01structure/stack/__init__.py index a5daaa1..259323b 100644 --- a/algorithms/ch01structure/stack/__init__.py +++ b/algorithms/ch01structure/stack/__init__.py @@ -3,6 +3,6 @@ 栈数据结构 LeetCode题目: -20,155,224,232,496,844,682 +20,155,224,232,496,682,844 """ diff --git a/algorithms/leecode/p600/a682_baseball_game.py b/algorithms/leecode/p600/a682_baseball_game.py new file mode 100644 index 0000000..a7a9b00 --- /dev/null +++ b/algorithms/leecode/p600/a682_baseball_game.py @@ -0,0 +1,109 @@ +# -*- encoding: utf-8 -*- +""" +682. 棒球比赛 +你现在是一场采用特殊赛制棒球比赛的记录员。这场比赛由若干回合组成,过去几回合的得分可能会影响以后几回合的得分。 + +比赛开始时,记录是空白的。你会得到一个记录操作的字符串列表 ops,其中 ops[i] 是你需要记录的第 i 项操作,ops 遵循下述规则: + +整数 x - 表示本回合新获得分数 x +"+" - 表示本回合新获得的得分是前两次得分的总和。题目数据保证记录此操作时前面总是存在两个有效的分数。 +"D" - 表示本回合新获得的得分是前一次得分的两倍。题目数据保证记录此操作时前面总是存在一个有效的分数。 +"C" - 表示前一次得分无效,将其从记录中移除。题目数据保证记录此操作时前面总是存在一个有效的分数。 +请你返回记录中所有得分的总和。 + +输入:ops = ["5","2","C","D","+"] +输出:30 +解释: +"5" - 记录加 5 ,记录现在是 [5] +"2" - 记录加 2 ,记录现在是 [5, 2] +"C" - 使前一次得分的记录无效并将其移除,记录现在是 [5]. +"D" - 记录加 2 * 5 = 10 ,记录现在是 [5, 10]. +"+" - 记录加 5 + 10 = 15 ,记录现在是 [5, 10, 15]. +所有得分的总和 5 + 10 + 15 = 30 + +输入:ops = ["5","-2","4","C","D","9","+","+"] +输出:27 +解释: +"5" - 记录加 5 ,记录现在是 [5] +"-2" - 记录加 -2 ,记录现在是 [5, -2] +"4" - 记录加 4 ,记录现在是 [5, -2, 4] +"C" - 使前一次得分的记录无效并将其移除,记录现在是 [5, -2] +"D" - 记录加 2 * -2 = -4 ,记录现在是 [5, -2, -4] +"9" - 记录加 9 ,记录现在是 [5, -2, -4, 9] +"+" - 记录加 -4 + 9 = 5 ,记录现在是 [5, -2, -4, 9, 5] +"+" - 记录加 9 + 5 = 14 ,记录现在是 [5, -2, -4, 9, 5, 14] +所有得分的总和 5 + -2 + -4 + 9 + 5 + 14 = 27 + +算法思路: +跟加减乘除思路类似,这里的C、D、+代表操作符,优先级一样。 +准备两个栈,左栈作为操作数,右栈作为操作符。遇到数字压入左栈,遇到操作符根据规则进行计算即可。 +""" +from typing import List + + +class LinkedNode: + def __init__(self, val_, next_=None): + self.val = val_ + self.next = next_ + + def __str__(self): + return str(self.val) + + +class LinkedStack: + def __init__(self): + self.first = None + + def push(self, val): + self.first = LinkedNode(val, self.first) + + def pop(self): + if not self.first: + return None + res = self.first.val + self.first = self.first.next + return res + + def peek(self): + if not self.first: + return None + return self.first.val + + def empty(self): + return self.first is None + + def __iter__(self): + while self.first: + yield self.first.val + self.first = self.first.next + + +class Solution: + + def __init__(self): + self.left_stack = LinkedStack() + self.right_stack = LinkedStack() + + def calPoints(self, ops: List[str]) -> int: + for op in ops: + if self.is_number(op): + self.left_stack.push(int(op)) + else: + if op == 'C': + self.left_stack.pop() + elif op == 'D': + self.left_stack.push(self.left_stack.peek() * 2) + elif op == '+': + self.left_stack.push(self.left_stack.peek() + self.left_stack.first.next.val) + return sum(self.left_stack) + + def is_number(self, str_): + try: + int(str_) + return True + except ValueError: + return False + + +if __name__ == '__main__': + print(Solution().calPoints(["5", "2", "C", "D", "+"])) From c45763cfe1e9e72160e3a326d97d5b3682451c65 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Sat, 19 Mar 2022 21:46:50 +0800 Subject: [PATCH 30/54] leetcode 844 --- .../p800/a844_backspace_string_compare.py | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 algorithms/leecode/p800/a844_backspace_string_compare.py diff --git a/algorithms/leecode/p800/a844_backspace_string_compare.py b/algorithms/leecode/p800/a844_backspace_string_compare.py new file mode 100644 index 0000000..acf8977 --- /dev/null +++ b/algorithms/leecode/p800/a844_backspace_string_compare.py @@ -0,0 +1,94 @@ +# -*- encoding: utf-8 -*- +""" +844. 比较含退格的字符串 +给定s和t两个字符串,当它们分别被输入到空白的文本编辑器后,如果两者相等,返回 true 。# 代表退格字符。 + +注意:如果对空文本输入退格字符,文本继续为空。 + +输入:s = "ab#c", t = "ad#c" +输出:true +解释:s 和 t 都会变成 "ac"。 + +输入:s = "ab##", t = "c#d#" +输出:true +解释:s 和 t 都会变成 ""。 + +输入:s = "a#c", t = "b" +输出:false +解释:s 会变成 "c",但 t 仍然是 "b"。 + +算法思路: +用两个栈遍历两个字符串,遇到#号就从栈弹出一个元素。最后再依次对比两个栈的每个元素。 +""" + + +class LinkedNode: + def __init__(self, val_, next_=None): + self.val = val_ + self.next = next_ + + def __str__(self): + return str(self.val) + + +class LinkedStack: + def __init__(self): + self.first = None + + def push(self, val): + self.first = LinkedNode(val, self.first) + + def pop(self): + if not self.first: + return None + res = self.first.val + self.first = self.first.next + return res + + def peek(self): + if not self.first: + return None + return self.first.val + + def empty(self): + return self.first is None + + def __iter__(self): + while self.first: + yield self.first.val + self.first = self.first.next + + +class Solution: + def __init__(self): + self.left_stack = LinkedStack() + self.right_stack = LinkedStack() + + def backspaceCompare(self, s: str, t: str) -> bool: + for left_val in s: + if left_val == '#': + if not self.left_stack.empty(): + self.left_stack.pop() + else: + self.left_stack.push(left_val) + for right_val in t: + if right_val == '#': + if not self.right_stack.empty(): + self.right_stack.pop() + else: + self.right_stack.push(right_val) + while not self.left_stack.empty() and not self.right_stack.empty(): + if self.left_stack.pop() != self.right_stack.pop(): + return False + if not self.left_stack.empty() and self.right_stack.empty(): + return False + if self.left_stack.empty() and not self.right_stack.empty(): + return False + return True + + +if __name__ == '__main__': + print(Solution().backspaceCompare("ab##", "c#d#")) + print(Solution().backspaceCompare("ab#c", "ad#c")) + print(Solution().backspaceCompare("a#c", "b")) + print(Solution().backspaceCompare("y#fo##f", "y#f#o##f")) From 4e41dd673145e773f915070179e1b8754ccc5af5 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Sun, 27 Mar 2022 13:29:22 +0800 Subject: [PATCH 31/54] leetcode 392 --- .../leecode/p300/a392_is_subsequence.py | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 algorithms/leecode/p300/a392_is_subsequence.py diff --git a/algorithms/leecode/p300/a392_is_subsequence.py b/algorithms/leecode/p300/a392_is_subsequence.py new file mode 100644 index 0000000..2f54213 --- /dev/null +++ b/algorithms/leecode/p300/a392_is_subsequence.py @@ -0,0 +1,34 @@ +# -*- encoding: utf-8 -*- +""" +392. 判断子序列 +给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 + +字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。 +(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。 + +进阶: +如果有大量输入的 S,称作 S1, S2, ... , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。 +在这种情况下,你会怎样改变代码? + +算法思路: +通过双指针遍历两个序列,两个相等时,左指针向前一步,直到左指针跑完左边字符串s即可。 +python中可通过生成器方式简化算法的写法。 + +输入:s = "abc", t = "ahbgdc" +输出:true + +输入:s = "axc", t = "ahbgdc" +输出:false +""" + + +class Solution: + def isSubsequence(self, s: str, t: str) -> bool: + t_iter = iter(t) # 这里需要单独提取出来,否则for中每次都会生成新的迭代器。 + return all(i in t_iter for i in s) + + +if __name__ == '__main__': + print(Solution().isSubsequence('abc', 'ahbgdc')) + print(Solution().isSubsequence('axc', 'ahbgdc')) + print(Solution().isSubsequence('acb', 'ahbgdc')) From 218ed99c386b0a09688aa7eadf15bd2633694361 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Mon, 4 Apr 2022 22:48:16 +0800 Subject: [PATCH 32/54] update --- algorithms/ch02sort/base/sortutil.py | 4 ++-- algorithms/ch02sort/m00_bubble_sort.py | 29 ++++++++++++++++++++++++++ algorithms/ch02sort/m01_select_sort.py | 1 + algorithms/ch02sort/m02_insert_sort.py | 11 +++++++--- 4 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 algorithms/ch02sort/m00_bubble_sort.py diff --git a/algorithms/ch02sort/base/sortutil.py b/algorithms/ch02sort/base/sortutil.py index 86ea247..c41a4c4 100644 --- a/algorithms/ch02sort/base/sortutil.py +++ b/algorithms/ch02sort/base/sortutil.py @@ -1,6 +1,6 @@ # -*- encoding: utf-8 -*- -"""将重复的方法抽取出来 -Some of description... +""" +将重复的方法抽取出来 """ diff --git a/algorithms/ch02sort/m00_bubble_sort.py b/algorithms/ch02sort/m00_bubble_sort.py new file mode 100644 index 0000000..f2ccee5 --- /dev/null +++ b/algorithms/ch02sort/m00_bubble_sort.py @@ -0,0 +1,29 @@ +# -*- encoding: utf-8 -*- +""" +冒泡排序 +当某次冒泡操作已经没有数据交换时,说明已经达到完全有序,不用再继续执行后续的冒泡操作。 + +算法复杂度:N^2 +稳定排序:重复元素排序完后仍然保持原来的相对位置。 +""" +from algorithms.ch02sort.base.template import SortTemplate + + +class BubbleSort(SortTemplate): + + def sort(self): + le = len(self.seq) + for i in range(le): + # 提前退出排序的标志,本次循环是否有数据交换 + has_exchange = False + for j in range(0, le - i - 1): + if self.seq[j] > self.seq[j + 1]: + self.seq[j], self.seq[j + 1] = self.seq[j + 1], self.seq[j] + has_exchange = True # 表示有数据交换 + if not has_exchange: + break + + +if __name__ == '__main__': + bubble_sort = BubbleSort([4, 2, 5, 1, 6, 3]) + bubble_sort.main() diff --git a/algorithms/ch02sort/m01_select_sort.py b/algorithms/ch02sort/m01_select_sort.py index 9ce2faf..f156fdd 100644 --- a/algorithms/ch02sort/m01_select_sort.py +++ b/algorithms/ch02sort/m01_select_sort.py @@ -5,6 +5,7 @@ 2. 在剩下的元素中找到最小元素,将其与数组第二个元素交换位置。 3. 如此反复,直到剩下元素为1个,整个数组排序完。 +不稳定排序,使用场景少。 复杂度:O(N^2),大约需要N^2/2次比较和N次交换。 """ from algorithms.ch02sort.base.template import SortTemplate diff --git a/algorithms/ch02sort/m02_insert_sort.py b/algorithms/ch02sort/m02_insert_sort.py index 011862e..a7e1067 100644 --- a/algorithms/ch02sort/m02_insert_sort.py +++ b/algorithms/ch02sort/m02_insert_sort.py @@ -1,10 +1,15 @@ #!/usr/bin/env python """插入排序 -索引从1开始往右边遍历,将元素插入到左边已排序好的数组中,索引左边的所有元素都是有序的, -但是它们的最终位置并不确定,为了给更小元素腾出空间,它们可能会被移动。当索引到达最右端的时候,数组排序完成。 +我们将数组中的数据分为两个区间,已排序区间和未排序区间。初始已排序区间只有一个元素,就是数组的第一个元素。 +插入算法的核心思想是取未排序区间中的元素,在已排序区间中找到合适的插入位置将其插入,并保证已排序区间数据一直有序。 +重复这个过程,直到未排序区间中元素为空,算法结束。 由于其内层循环非常紧凑,对于小规模的输入,插入排序是一种非常快的原址排序算法。 -注: 如果输入数组中仅有常数个元素需要在排序过程中存储在数组外,则称这种排序算法是原址的。 +注:如果输入数组中仅有常数个元素需要在排序过程中存储在数组外,则称这种排序算法是原址的。 + +冒泡排序的数据交换要比插入排序的数据移动要复杂,冒泡排序需要3个赋值操作,而插入排序只需要1个。 +所以,虽然冒泡排序和插入排序在时间复杂度上是一样的,都是 O(n2),但是如果我们希望把性能优化做到极致, +那肯定首选插入排序。 算法复杂度:N^2 稳定排序:重复元素排序完后仍然保持原来的相对位置。 From 53b210d4ee150a6dd347d133a95a1b40e2f92dc1 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Tue, 5 Apr 2022 12:09:50 +0800 Subject: [PATCH 33/54] update --- ...{m02_insert_sort.py => m01_insert_sort.py} | 0 ...{m01_select_sort.py => m02_select_sort.py} | 0 algorithms/ch02sort/m03_merge_sort.py | 2 ++ algorithms/ch02sort/m04_merge_insert_sort.py | 4 ++- algorithms/ch02sort/m05_quick_sort.py | 33 ++++++++++--------- 5 files changed, 23 insertions(+), 16 deletions(-) rename algorithms/ch02sort/{m02_insert_sort.py => m01_insert_sort.py} (100%) rename algorithms/ch02sort/{m01_select_sort.py => m02_select_sort.py} (100%) diff --git a/algorithms/ch02sort/m02_insert_sort.py b/algorithms/ch02sort/m01_insert_sort.py similarity index 100% rename from algorithms/ch02sort/m02_insert_sort.py rename to algorithms/ch02sort/m01_insert_sort.py diff --git a/algorithms/ch02sort/m01_select_sort.py b/algorithms/ch02sort/m02_select_sort.py similarity index 100% rename from algorithms/ch02sort/m01_select_sort.py rename to algorithms/ch02sort/m02_select_sort.py diff --git a/algorithms/ch02sort/m03_merge_sort.py b/algorithms/ch02sort/m03_merge_sort.py index e872e4a..ccec0de 100644 --- a/algorithms/ch02sort/m03_merge_sort.py +++ b/algorithms/ch02sort/m03_merge_sort.py @@ -7,6 +7,8 @@ 复杂度:N*lg(N) 稳定排序:重复元素排序完后仍然保持原来的相对位置。 + +它有一个致命的“弱点”,那就是归并排序不是原地排序算法。 """ from algorithms.ch02sort.base.template import SortTemplate diff --git a/algorithms/ch02sort/m04_merge_insert_sort.py b/algorithms/ch02sort/m04_merge_insert_sort.py index 47639e3..fd54437 100644 --- a/algorithms/ch02sort/m04_merge_insert_sort.py +++ b/algorithms/ch02sort/m04_merge_insert_sort.py @@ -11,10 +11,12 @@ k如果大于lgn,则比归并排序复杂度大了。左边可以写成nk+nlgn-nlgk,k等于lgn时, 就是2nlgn-nlglgn.忽略恒定系数,则与归并排序是一样的。 - 最后结论: k < lg(n)的时候,使用插入排序 + 最后结论:k < lg(n)的时候,使用插入排序 复杂度为: O(nlgn) 稳定排序:重复元素排序完后仍然保持原来的相对位置。 + +它有一个致命的“弱点”,那就是归并排序不是原地排序算法。 """ from math import log diff --git a/algorithms/ch02sort/m05_quick_sort.py b/algorithms/ch02sort/m05_quick_sort.py index 2397632..ca4c06f 100644 --- a/algorithms/ch02sort/m05_quick_sort.py +++ b/algorithms/ch02sort/m05_quick_sort.py @@ -1,17 +1,19 @@ #!/usr/bin/env python -"""快速排序 - 采用分治法思想: - 分解: 将数组A[p..r]划分成两个(也可能是空)的子数组A[p..q-1]和A[q+1..r], - 使得左边数组中的元素都小于A[p],而右边数组元素都大于A[p] - 解决: 通过递归调用快速排序,对子数组A[p..q-1]和A[q+1..r]进行排序 - 合并: 原址排序,不需要合并,数组已经排好序了 - - 快速排序的优点: - 最坏情况下时间复杂度为O(n^2),但是期望时间是O(nlg(n)), - 而且O(nlg(n))隐含常数因子非常的小,而且还是原址排序, - 所以实际中使用最多的排序算法就是快速排序 - - 性质T:快速排序是最快的通用排序算法。 +""" +快速排序 +采用分治法思想: +分解: 将数组A[p..r]划分成两个(也可能是空)的子数组A[p..q-1]和A[q+1..r], + 使得左边数组中的元素都小于A[p],而右边数组元素都大于A[p] +解决: 通过递归调用快速排序,对子数组A[p..q-1]和A[q+1..r]进行排序 +合并: 原址排序,不需要合并,数组已经排好序了 + +快速排序的优点: +最坏情况下时间复杂度为O(n^2),但是期望时间是O(nlg(n)), +而且O(n*lg(n))隐含常数因子非常的小,而且还是原址排序, +所以实际中使用最多的排序算法就是快速排序 + +复杂度为: O(n*lgn) +快速排序的缺点是它是一个不稳定排序算法。如果要保持原有的相同元素顺序,则不能选择快排。 """ from random import randint @@ -30,13 +32,13 @@ def _quick_sub_sort_tail(self, start, end): pivot = self._rand_partition(start, end) if pivot - start < end - pivot: self._quick_sub_sort_tail(start, pivot - 1) - start = pivot + 1 + start = pivot + 1 # 巧妙的通过改变start来实现右边数组的递归 else: self._quick_sub_sort_tail(pivot + 1, end) end = pivot - 1 def _rand_partition(self, start, end): - """分解子数组: 随机化版本""" + """分解子数组:随机化版本""" pivot = randint(start, end) # 随机的pivot # 还是将这个pivot放到最后 self.seq[pivot], self.seq[end] = self.seq[end], self.seq[pivot] @@ -45,6 +47,7 @@ def _rand_partition(self, start, end): for j in range(start, end): if self.seq[j] <= pivot_value: i += 1 + # 只需要确保所有不大于标杆的元素被蛇吞掉即可。 self.seq[i], self.seq[j] = self.seq[j], self.seq[i] self.seq[i + 1], self.seq[end] = self.seq[end], self.seq[i + 1] return i + 1 From 9cc615e56c700b78db92a824be87e0c94bf689be Mon Sep 17 00:00:00 2001 From: xiongneng Date: Tue, 5 Apr 2022 16:25:40 +0800 Subject: [PATCH 34/54] leetcode 215 --- .../a215_kth_largest_element_in_an_array.py | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 algorithms/leecode/p200/a215_kth_largest_element_in_an_array.py diff --git a/algorithms/leecode/p200/a215_kth_largest_element_in_an_array.py b/algorithms/leecode/p200/a215_kth_largest_element_in_an_array.py new file mode 100644 index 0000000..1033b79 --- /dev/null +++ b/algorithms/leecode/p200/a215_kth_largest_element_in_an_array.py @@ -0,0 +1,52 @@ +# -*- encoding: utf-8 -*- +""" +215. 数组中的第K个最大元素 + +给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。 +请注意,你需要找的是数组排序后的第k个最大的元素,而不是第k个不同的元素。 + +输入: [3,2,1,5,6,4] 和 k = 2 +输出: 5 + +输入: [3,2,3,1,2,4,5,5,6] 和 k = 4 +输出: 4 + +算法思路: +采用快排的分治思想。我们选择数组区间 A[0...n-1]的最后一个元素 A[n-1]作为 pivot, +对数组 A[0...n-1]原地分区,左边大右边小。分区完成后数组就分成了三部分,A[0...p-1]、A[p]、A[p+1...n-1]。 +如果 p+1=K,那 A[p]就是要求解的元素; +如果 p+1K,说明第 K 大元素出现在左边 A[0...p-1]区间。 +我们再按照上面的思路递归地在 A[p+1...n-1] 或者A[0...p-1]区间内存查找。 +""" +from typing import List + + +class Solution: + def findKthLargest(self, nums: List[int], k: int) -> int: + return self.recursive_choose_pivot(nums, 0, len(nums) - 1, k) + + def recursive_choose_pivot(self, nums: List[int], start, end, k: int) -> int: + while start <= end: + pivot = self.choose_pivot_by_last(nums, start, end) + if pivot + 1 == k: + return nums[pivot] + if pivot + 1 < k: + return self.recursive_choose_pivot(nums, pivot + 1, end, k) + else: + return self.recursive_choose_pivot(nums, start, pivot - 1, k) + + def choose_pivot_by_last(self, nums: List[int], start, end) -> int: + pivot_value = nums[end] # 将最后一个元素定为pivot + i = start - 1 # 以退为进,初始值设置为start-1 + for j in range(start, end): + if nums[j] >= pivot_value: # 将大的数放左边 + i += 1 + nums[i], nums[j] = nums[j], nums[i] + nums[i + 1], nums[end] = nums[end], nums[i + 1] + return i + 1 + + +if __name__ == '__main__': + res = Solution().findKthLargest([3, 2, 1, 5, 6, 4], 2) + assert res == 5 From 0001b99202f1c7a1b43a8b8bda8f0471f392847d Mon Sep 17 00:00:00 2001 From: xiongneng Date: Thu, 14 Apr 2022 23:52:44 +0800 Subject: [PATCH 35/54] update package --- README.md | 14 ++++++++++++++ .../{ch01structure => ch01linear}/__init__.py | 3 ++- .../linkedlist/__init__.py | 0 .../linkedlist/linked_list_double.py | 2 +- .../linkedlist/linked_list_double_cycle.py | 2 +- .../linkedlist/linked_list_single.py | 2 +- .../linkedlist/linked_list_single_cycle.py | 2 +- .../linkedlist/lru_cache.py | 4 ++-- .../linkedlist/palindromic_number.py | 4 ++-- .../queue/__init__.py | 0 .../queue/array_queue.py | 0 .../queue/linked_queue.py | 2 +- .../queue/prior_queue.py | 2 +- .../stack/__init__.py | 0 .../stack/stack_array.py | 2 +- .../stack/stack_linked_list.py | 2 +- algorithms/ch03search/__init__.py | 4 ++++ algorithms/ch04tree/__init__.py | 4 ++++ .../tree => ch04tree}/bisearch_tree.py | 4 ++-- .../tree => ch04tree}/redblack_tree.py | 2 +- algorithms/{ch10graph => ch05graph}/__init__.py | 0 algorithms/{ch20string => ch06string}/__init__.py | 0 .../{ch01structure/tree => ch07greedy}/__init__.py | 2 +- .../{ch06greedy => ch07greedy}/m01_activity.py | 0 algorithms/{ch06greedy => ch08divide}/__init__.py | 4 ++-- algorithms/ch09backtrack/__init__.py | 4 ++++ .../{ch05dynamic => ch10dynamic}/__init__.py | 3 ++- .../{ch05dynamic => ch10dynamic}/m01_cut_steel.py | 0 .../{ch05dynamic => ch10dynamic}/m02_fibonacci.py | 0 .../m03_matrix_chain.py | 0 .../{ch05dynamic => ch10dynamic}/m04_elevator.py | 0 .../m05_subsequence.py | 0 algorithms/{ch05dynamic => ch10dynamic}/m06_bag.py | 0 algorithms/ch11advanced/__init__.py | 6 ++++++ algorithms/{ch30sample => ch20sample}/__init__.py | 0 algorithms/{ch30sample => ch20sample}/m01_math.py | 0 .../{ch30sample => ch20sample}/m02_triangle_str.py | 0 .../m03_duplicate_words.py | 0 .../{ch30sample => ch20sample}/m04_binary_add.py | 0 .../{ch30sample => ch20sample}/m05_nine_number.py | 0 .../{ch30sample => ch20sample}/m06_hornerpoly.py | 0 .../{ch30sample => ch20sample}/m07_max_subarr.py | 0 .../{ch30sample => ch20sample}/m08_max_subarr2.py | 0 .../{ch30sample => ch20sample}/m09_max_subarr3.py | 0 .../{ch30sample => ch20sample}/m10_code_funny.py | 0 .../{ch30sample => ch20sample}/m11_rand_permute.py | 0 .../{ch30sample => ch20sample}/m12_right_shift.py | 0 .../{ch30sample => ch20sample}/m13_sin_cpu.py | 0 .../{ch30sample => ch20sample}/m14_bestsinger.py | 0 .../m15_bracket_match.py | 0 .../{ch30sample => ch20sample}/m16_circle_queue.py | 0 algorithms/leecode/p000/a20_valid_parentheses.py | 2 +- algorithms/leecode/p100/a155_min_stack.py | 2 +- 53 files changed, 56 insertions(+), 22 deletions(-) rename algorithms/{ch01structure => ch01linear}/__init__.py (88%) rename algorithms/{ch01structure => ch01linear}/linkedlist/__init__.py (100%) rename algorithms/{ch01structure => ch01linear}/linkedlist/linked_list_double.py (96%) rename algorithms/{ch01structure => ch01linear}/linkedlist/linked_list_double_cycle.py (96%) rename algorithms/{ch01structure => ch01linear}/linkedlist/linked_list_single.py (97%) rename algorithms/{ch01structure => ch01linear}/linkedlist/linked_list_single_cycle.py (97%) rename algorithms/{ch01structure => ch01linear}/linkedlist/lru_cache.py (92%) rename algorithms/{ch01structure => ch01linear}/linkedlist/palindromic_number.py (96%) rename algorithms/{ch01structure => ch01linear}/queue/__init__.py (100%) rename algorithms/{ch01structure => ch01linear}/queue/array_queue.py (100%) rename algorithms/{ch01structure => ch01linear}/queue/linked_queue.py (96%) rename algorithms/{ch01structure => ch01linear}/queue/prior_queue.py (97%) rename algorithms/{ch01structure => ch01linear}/stack/__init__.py (100%) rename algorithms/{ch01structure => ch01linear}/stack/stack_array.py (96%) rename algorithms/{ch01structure => ch01linear}/stack/stack_linked_list.py (96%) create mode 100644 algorithms/ch03search/__init__.py create mode 100644 algorithms/ch04tree/__init__.py rename algorithms/{ch01structure/tree => ch04tree}/bisearch_tree.py (96%) rename algorithms/{ch01structure/tree => ch04tree}/redblack_tree.py (98%) rename algorithms/{ch10graph => ch05graph}/__init__.py (100%) rename algorithms/{ch20string => ch06string}/__init__.py (100%) rename algorithms/{ch01structure/tree => ch07greedy}/__init__.py (70%) rename algorithms/{ch06greedy => ch07greedy}/m01_activity.py (100%) rename algorithms/{ch06greedy => ch08divide}/__init__.py (63%) create mode 100644 algorithms/ch09backtrack/__init__.py rename algorithms/{ch05dynamic => ch10dynamic}/__init__.py (75%) rename algorithms/{ch05dynamic => ch10dynamic}/m01_cut_steel.py (100%) rename algorithms/{ch05dynamic => ch10dynamic}/m02_fibonacci.py (100%) rename algorithms/{ch05dynamic => ch10dynamic}/m03_matrix_chain.py (100%) rename algorithms/{ch05dynamic => ch10dynamic}/m04_elevator.py (100%) rename algorithms/{ch05dynamic => ch10dynamic}/m05_subsequence.py (100%) rename algorithms/{ch05dynamic => ch10dynamic}/m06_bag.py (100%) create mode 100644 algorithms/ch11advanced/__init__.py rename algorithms/{ch30sample => ch20sample}/__init__.py (100%) rename algorithms/{ch30sample => ch20sample}/m01_math.py (100%) rename algorithms/{ch30sample => ch20sample}/m02_triangle_str.py (100%) rename algorithms/{ch30sample => ch20sample}/m03_duplicate_words.py (100%) rename algorithms/{ch30sample => ch20sample}/m04_binary_add.py (100%) rename algorithms/{ch30sample => ch20sample}/m05_nine_number.py (100%) rename algorithms/{ch30sample => ch20sample}/m06_hornerpoly.py (100%) rename algorithms/{ch30sample => ch20sample}/m07_max_subarr.py (100%) rename algorithms/{ch30sample => ch20sample}/m08_max_subarr2.py (100%) rename algorithms/{ch30sample => ch20sample}/m09_max_subarr3.py (100%) rename algorithms/{ch30sample => ch20sample}/m10_code_funny.py (100%) rename algorithms/{ch30sample => ch20sample}/m11_rand_permute.py (100%) rename algorithms/{ch30sample => ch20sample}/m12_right_shift.py (100%) rename algorithms/{ch30sample => ch20sample}/m13_sin_cpu.py (100%) rename algorithms/{ch30sample => ch20sample}/m14_bestsinger.py (100%) rename algorithms/{ch30sample => ch20sample}/m15_bracket_match.py (100%) rename algorithms/{ch30sample => ch20sample}/m16_circle_queue.py (100%) diff --git a/README.md b/README.md index 62abd5b..cbf9bcb 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,20 @@ * 《算法导论》第3版 * 《LeeCode算法题库》 +章节说明: + +1. 线性表数据结构:数组、链表、队列、栈。 +2. 各类排序算法:(冒泡、插入、选择)、(快排、归并)、(桶、计数、基数)。 +3. 查找算法:二分查找、调表、散列表、哈希算法 +4. 树数据结构:二叉树、红黑树、递归树、堆。 +5. 图数据结构 +6. 字符串匹配算法 +7. 贪心算法 +8. 分治算法 +9. 回溯算法 +10. 动态规划算法 +11. 高级数据结构和算法 + ## 作者的话 书中经典的算法示例使用python3语言实现,并且配有详细的算法原理说明。 diff --git a/algorithms/ch01structure/__init__.py b/algorithms/ch01linear/__init__.py similarity index 88% rename from algorithms/ch01structure/__init__.py rename to algorithms/ch01linear/__init__.py index c22fe25..adb9640 100644 --- a/algorithms/ch01structure/__init__.py +++ b/algorithms/ch01linear/__init__.py @@ -1,5 +1,6 @@ # -*- encoding: utf-8 -*- -"""常见的数据结构 +""" +线性表数据结构:数组、链表、队列、栈。 """ diff --git a/algorithms/ch01structure/linkedlist/__init__.py b/algorithms/ch01linear/linkedlist/__init__.py similarity index 100% rename from algorithms/ch01structure/linkedlist/__init__.py rename to algorithms/ch01linear/linkedlist/__init__.py diff --git a/algorithms/ch01structure/linkedlist/linked_list_double.py b/algorithms/ch01linear/linkedlist/linked_list_double.py similarity index 96% rename from algorithms/ch01structure/linkedlist/linked_list_double.py rename to algorithms/ch01linear/linkedlist/linked_list_double.py index 3aaeaaf..691cfde 100644 --- a/algorithms/ch01structure/linkedlist/linked_list_double.py +++ b/algorithms/ch01linear/linkedlist/linked_list_double.py @@ -2,7 +2,7 @@ """ 双向链表数据结构 """ -from algorithms.ch01structure import NodeDouble +from algorithms.ch01linear import NodeDouble class LinkedListDouble: diff --git a/algorithms/ch01structure/linkedlist/linked_list_double_cycle.py b/algorithms/ch01linear/linkedlist/linked_list_double_cycle.py similarity index 96% rename from algorithms/ch01structure/linkedlist/linked_list_double_cycle.py rename to algorithms/ch01linear/linkedlist/linked_list_double_cycle.py index 353a59f..c700796 100644 --- a/algorithms/ch01structure/linkedlist/linked_list_double_cycle.py +++ b/algorithms/ch01linear/linkedlist/linked_list_double_cycle.py @@ -2,7 +2,7 @@ """ 双向循环链表数据结构 """ -from algorithms.ch01structure import NodeDouble +from algorithms.ch01linear import NodeDouble class LinkedListDouble: diff --git a/algorithms/ch01structure/linkedlist/linked_list_single.py b/algorithms/ch01linear/linkedlist/linked_list_single.py similarity index 97% rename from algorithms/ch01structure/linkedlist/linked_list_single.py rename to algorithms/ch01linear/linkedlist/linked_list_single.py index e93105c..fb543ad 100644 --- a/algorithms/ch01structure/linkedlist/linked_list_single.py +++ b/algorithms/ch01linear/linkedlist/linked_list_single.py @@ -2,7 +2,7 @@ """ 单向链表数据结构 """ -from algorithms.ch01structure import Node +from algorithms.ch01linear import Node class LinkedListSingle: diff --git a/algorithms/ch01structure/linkedlist/linked_list_single_cycle.py b/algorithms/ch01linear/linkedlist/linked_list_single_cycle.py similarity index 97% rename from algorithms/ch01structure/linkedlist/linked_list_single_cycle.py rename to algorithms/ch01linear/linkedlist/linked_list_single_cycle.py index ecdb62b..4a06152 100644 --- a/algorithms/ch01structure/linkedlist/linked_list_single_cycle.py +++ b/algorithms/ch01linear/linkedlist/linked_list_single_cycle.py @@ -2,7 +2,7 @@ """ 单向循环链表数据结构 """ -from algorithms.ch01structure import Node +from algorithms.ch01linear import Node class LinkedListSingleCycle: diff --git a/algorithms/ch01structure/linkedlist/lru_cache.py b/algorithms/ch01linear/linkedlist/lru_cache.py similarity index 92% rename from algorithms/ch01structure/linkedlist/lru_cache.py rename to algorithms/ch01linear/linkedlist/lru_cache.py index 091632c..2e4b723 100644 --- a/algorithms/ch01structure/linkedlist/lru_cache.py +++ b/algorithms/ch01linear/linkedlist/lru_cache.py @@ -11,8 +11,8 @@ 2.1 如果此时缓存未满,则将此结点直接插入到链表的头部; 2.2 如果此时缓存已满,则链表尾结点删除,将新的数据结点插入链表的头部。 """ -from algorithms.ch01structure import Node -from algorithms.ch01structure.linkedlist.linked_list_single import LinkedListSingle +from algorithms.ch01linear import Node +from algorithms.ch01linear.linkedlist.linked_list_single import LinkedListSingle def lru(list_single_, data): diff --git a/algorithms/ch01structure/linkedlist/palindromic_number.py b/algorithms/ch01linear/linkedlist/palindromic_number.py similarity index 96% rename from algorithms/ch01structure/linkedlist/palindromic_number.py rename to algorithms/ch01linear/linkedlist/palindromic_number.py index dc5a5d6..49d6e7b 100644 --- a/algorithms/ch01structure/linkedlist/palindromic_number.py +++ b/algorithms/ch01linear/linkedlist/palindromic_number.py @@ -14,8 +14,8 @@ 1.2.1 如果是返回上中位数,后半部分串头取next <<=这里使用这张上中位数数 1.2.2 如果是返回下中位数,后半部分串头既是当前节点位置,但前半部分串尾要删除掉当前节点 """ -from algorithms.ch01structure import Node -from algorithms.ch01structure.linkedlist.linked_list_single import LinkedListSingle +from algorithms.ch01linear import Node +from algorithms.ch01linear.linkedlist.linked_list_single import LinkedListSingle def palindromic(list_single_): diff --git a/algorithms/ch01structure/queue/__init__.py b/algorithms/ch01linear/queue/__init__.py similarity index 100% rename from algorithms/ch01structure/queue/__init__.py rename to algorithms/ch01linear/queue/__init__.py diff --git a/algorithms/ch01structure/queue/array_queue.py b/algorithms/ch01linear/queue/array_queue.py similarity index 100% rename from algorithms/ch01structure/queue/array_queue.py rename to algorithms/ch01linear/queue/array_queue.py diff --git a/algorithms/ch01structure/queue/linked_queue.py b/algorithms/ch01linear/queue/linked_queue.py similarity index 96% rename from algorithms/ch01structure/queue/linked_queue.py rename to algorithms/ch01linear/queue/linked_queue.py index 44c9bc4..a8ba1ae 100644 --- a/algorithms/ch01structure/queue/linked_queue.py +++ b/algorithms/ch01linear/queue/linked_queue.py @@ -2,7 +2,7 @@ """基于链表实现的一个简单队列 队尾插入元素,队头取元素。就跟在菜市场排队买菜原理是一样的 """ -from algorithms.ch01structure import Node +from algorithms.ch01linear import Node class LinkedQueue: diff --git a/algorithms/ch01structure/queue/prior_queue.py b/algorithms/ch01linear/queue/prior_queue.py similarity index 97% rename from algorithms/ch01structure/queue/prior_queue.py rename to algorithms/ch01linear/queue/prior_queue.py index 7c5eb6b..8e3a373 100644 --- a/algorithms/ch01structure/queue/prior_queue.py +++ b/algorithms/ch01linear/queue/prior_queue.py @@ -4,7 +4,7 @@ """ from functools import total_ordering -from algorithms.ch01structure.stack.stack_linked_list import LinkedStack +from algorithms.ch01linear.stack.stack_linked_list import LinkedStack class MaxPriorQueue: diff --git a/algorithms/ch01structure/stack/__init__.py b/algorithms/ch01linear/stack/__init__.py similarity index 100% rename from algorithms/ch01structure/stack/__init__.py rename to algorithms/ch01linear/stack/__init__.py diff --git a/algorithms/ch01structure/stack/stack_array.py b/algorithms/ch01linear/stack/stack_array.py similarity index 96% rename from algorithms/ch01structure/stack/stack_array.py rename to algorithms/ch01linear/stack/stack_array.py index a0d1bba..ebd760a 100644 --- a/algorithms/ch01structure/stack/stack_array.py +++ b/algorithms/ch01linear/stack/stack_array.py @@ -2,7 +2,7 @@ """ 基于数组实现的栈结构 """ -from algorithms.ch01structure import Node +from algorithms.ch01linear import Node class ArrayStack: diff --git a/algorithms/ch01structure/stack/stack_linked_list.py b/algorithms/ch01linear/stack/stack_linked_list.py similarity index 96% rename from algorithms/ch01structure/stack/stack_linked_list.py rename to algorithms/ch01linear/stack/stack_linked_list.py index 8e1d871..d2b80c0 100644 --- a/algorithms/ch01structure/stack/stack_linked_list.py +++ b/algorithms/ch01linear/stack/stack_linked_list.py @@ -4,7 +4,7 @@ 另一方面,迭代器应该一直可以迭代。迭代器的 `__iter__` 方法应该返回自身。 一般可使用生成器函数实现更符合python风格的可迭代对象。 """ -from algorithms.ch01structure import Node +from algorithms.ch01linear import Node class LinkedStack: diff --git a/algorithms/ch03search/__init__.py b/algorithms/ch03search/__init__.py new file mode 100644 index 0000000..334a6a5 --- /dev/null +++ b/algorithms/ch03search/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +二分查找、调表、散列表、哈希算法 +""" diff --git a/algorithms/ch04tree/__init__.py b/algorithms/ch04tree/__init__.py new file mode 100644 index 0000000..40e8162 --- /dev/null +++ b/algorithms/ch04tree/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +树结构、堆结构。 +""" diff --git a/algorithms/ch01structure/tree/bisearch_tree.py b/algorithms/ch04tree/bisearch_tree.py similarity index 96% rename from algorithms/ch01structure/tree/bisearch_tree.py rename to algorithms/ch04tree/bisearch_tree.py index fc8fdce..68033e7 100644 --- a/algorithms/ch01structure/tree/bisearch_tree.py +++ b/algorithms/ch04tree/bisearch_tree.py @@ -1,8 +1,8 @@ #!/usr/bin/env python # -*- encoding: utf-8 -*- """ -Desc : 二叉搜索树 - 二叉搜索树是指:对每个节点,其左子树元素不大于它,右子树元素不小于它 +二叉搜索树 +二叉搜索树是指:对每个节点,其左子树元素不大于它,右子树元素不小于它 """ diff --git a/algorithms/ch01structure/tree/redblack_tree.py b/algorithms/ch04tree/redblack_tree.py similarity index 98% rename from algorithms/ch01structure/tree/redblack_tree.py rename to algorithms/ch04tree/redblack_tree.py index 289d28c..1b36149 100644 --- a/algorithms/ch01structure/tree/redblack_tree.py +++ b/algorithms/ch04tree/redblack_tree.py @@ -10,7 +10,7 @@ 5,对每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点。 一个有n个内部结点的红黑树的高度最多为2lg(n+1) """ -from algorithms.ch01structure.tree.bisearch_tree import treeMinimum +from algorithms.ch04tree.bisearch_tree import treeMinimum class RBTree(): diff --git a/algorithms/ch10graph/__init__.py b/algorithms/ch05graph/__init__.py similarity index 100% rename from algorithms/ch10graph/__init__.py rename to algorithms/ch05graph/__init__.py diff --git a/algorithms/ch20string/__init__.py b/algorithms/ch06string/__init__.py similarity index 100% rename from algorithms/ch20string/__init__.py rename to algorithms/ch06string/__init__.py diff --git a/algorithms/ch01structure/tree/__init__.py b/algorithms/ch07greedy/__init__.py similarity index 70% rename from algorithms/ch01structure/tree/__init__.py rename to algorithms/ch07greedy/__init__.py index dbc8407..44df38a 100644 --- a/algorithms/ch01structure/tree/__init__.py +++ b/algorithms/ch07greedy/__init__.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- """ -description... +贪心算法 """ diff --git a/algorithms/ch06greedy/m01_activity.py b/algorithms/ch07greedy/m01_activity.py similarity index 100% rename from algorithms/ch06greedy/m01_activity.py rename to algorithms/ch07greedy/m01_activity.py diff --git a/algorithms/ch06greedy/__init__.py b/algorithms/ch08divide/__init__.py similarity index 63% rename from algorithms/ch06greedy/__init__.py rename to algorithms/ch08divide/__init__.py index e320ca2..84eb509 100644 --- a/algorithms/ch06greedy/__init__.py +++ b/algorithms/ch08divide/__init__.py @@ -1,4 +1,4 @@ # -*- encoding: utf-8 -*- -"""贪心算法 """ - +分治算法 +""" diff --git a/algorithms/ch09backtrack/__init__.py b/algorithms/ch09backtrack/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/ch09backtrack/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" diff --git a/algorithms/ch05dynamic/__init__.py b/algorithms/ch10dynamic/__init__.py similarity index 75% rename from algorithms/ch05dynamic/__init__.py rename to algorithms/ch10dynamic/__init__.py index 1c690ea..e75dc1c 100644 --- a/algorithms/ch05dynamic/__init__.py +++ b/algorithms/ch10dynamic/__init__.py @@ -1,4 +1,5 @@ #!/usr/bin/env python # -*- encoding: utf-8 -*- -"""动态规划 +""" +动态规划 """ diff --git a/algorithms/ch05dynamic/m01_cut_steel.py b/algorithms/ch10dynamic/m01_cut_steel.py similarity index 100% rename from algorithms/ch05dynamic/m01_cut_steel.py rename to algorithms/ch10dynamic/m01_cut_steel.py diff --git a/algorithms/ch05dynamic/m02_fibonacci.py b/algorithms/ch10dynamic/m02_fibonacci.py similarity index 100% rename from algorithms/ch05dynamic/m02_fibonacci.py rename to algorithms/ch10dynamic/m02_fibonacci.py diff --git a/algorithms/ch05dynamic/m03_matrix_chain.py b/algorithms/ch10dynamic/m03_matrix_chain.py similarity index 100% rename from algorithms/ch05dynamic/m03_matrix_chain.py rename to algorithms/ch10dynamic/m03_matrix_chain.py diff --git a/algorithms/ch05dynamic/m04_elevator.py b/algorithms/ch10dynamic/m04_elevator.py similarity index 100% rename from algorithms/ch05dynamic/m04_elevator.py rename to algorithms/ch10dynamic/m04_elevator.py diff --git a/algorithms/ch05dynamic/m05_subsequence.py b/algorithms/ch10dynamic/m05_subsequence.py similarity index 100% rename from algorithms/ch05dynamic/m05_subsequence.py rename to algorithms/ch10dynamic/m05_subsequence.py diff --git a/algorithms/ch05dynamic/m06_bag.py b/algorithms/ch10dynamic/m06_bag.py similarity index 100% rename from algorithms/ch05dynamic/m06_bag.py rename to algorithms/ch10dynamic/m06_bag.py diff --git a/algorithms/ch11advanced/__init__.py b/algorithms/ch11advanced/__init__.py new file mode 100644 index 0000000..1cd9106 --- /dev/null +++ b/algorithms/ch11advanced/__init__.py @@ -0,0 +1,6 @@ +# -*- encoding: utf-8 -*- +""" +高级数据结构和算法: +拓扑排序、最短路径、位图、概率统计、向量空间、B+树。 +搜索、索引、并行计算 +""" diff --git a/algorithms/ch30sample/__init__.py b/algorithms/ch20sample/__init__.py similarity index 100% rename from algorithms/ch30sample/__init__.py rename to algorithms/ch20sample/__init__.py diff --git a/algorithms/ch30sample/m01_math.py b/algorithms/ch20sample/m01_math.py similarity index 100% rename from algorithms/ch30sample/m01_math.py rename to algorithms/ch20sample/m01_math.py diff --git a/algorithms/ch30sample/m02_triangle_str.py b/algorithms/ch20sample/m02_triangle_str.py similarity index 100% rename from algorithms/ch30sample/m02_triangle_str.py rename to algorithms/ch20sample/m02_triangle_str.py diff --git a/algorithms/ch30sample/m03_duplicate_words.py b/algorithms/ch20sample/m03_duplicate_words.py similarity index 100% rename from algorithms/ch30sample/m03_duplicate_words.py rename to algorithms/ch20sample/m03_duplicate_words.py diff --git a/algorithms/ch30sample/m04_binary_add.py b/algorithms/ch20sample/m04_binary_add.py similarity index 100% rename from algorithms/ch30sample/m04_binary_add.py rename to algorithms/ch20sample/m04_binary_add.py diff --git a/algorithms/ch30sample/m05_nine_number.py b/algorithms/ch20sample/m05_nine_number.py similarity index 100% rename from algorithms/ch30sample/m05_nine_number.py rename to algorithms/ch20sample/m05_nine_number.py diff --git a/algorithms/ch30sample/m06_hornerpoly.py b/algorithms/ch20sample/m06_hornerpoly.py similarity index 100% rename from algorithms/ch30sample/m06_hornerpoly.py rename to algorithms/ch20sample/m06_hornerpoly.py diff --git a/algorithms/ch30sample/m07_max_subarr.py b/algorithms/ch20sample/m07_max_subarr.py similarity index 100% rename from algorithms/ch30sample/m07_max_subarr.py rename to algorithms/ch20sample/m07_max_subarr.py diff --git a/algorithms/ch30sample/m08_max_subarr2.py b/algorithms/ch20sample/m08_max_subarr2.py similarity index 100% rename from algorithms/ch30sample/m08_max_subarr2.py rename to algorithms/ch20sample/m08_max_subarr2.py diff --git a/algorithms/ch30sample/m09_max_subarr3.py b/algorithms/ch20sample/m09_max_subarr3.py similarity index 100% rename from algorithms/ch30sample/m09_max_subarr3.py rename to algorithms/ch20sample/m09_max_subarr3.py diff --git a/algorithms/ch30sample/m10_code_funny.py b/algorithms/ch20sample/m10_code_funny.py similarity index 100% rename from algorithms/ch30sample/m10_code_funny.py rename to algorithms/ch20sample/m10_code_funny.py diff --git a/algorithms/ch30sample/m11_rand_permute.py b/algorithms/ch20sample/m11_rand_permute.py similarity index 100% rename from algorithms/ch30sample/m11_rand_permute.py rename to algorithms/ch20sample/m11_rand_permute.py diff --git a/algorithms/ch30sample/m12_right_shift.py b/algorithms/ch20sample/m12_right_shift.py similarity index 100% rename from algorithms/ch30sample/m12_right_shift.py rename to algorithms/ch20sample/m12_right_shift.py diff --git a/algorithms/ch30sample/m13_sin_cpu.py b/algorithms/ch20sample/m13_sin_cpu.py similarity index 100% rename from algorithms/ch30sample/m13_sin_cpu.py rename to algorithms/ch20sample/m13_sin_cpu.py diff --git a/algorithms/ch30sample/m14_bestsinger.py b/algorithms/ch20sample/m14_bestsinger.py similarity index 100% rename from algorithms/ch30sample/m14_bestsinger.py rename to algorithms/ch20sample/m14_bestsinger.py diff --git a/algorithms/ch30sample/m15_bracket_match.py b/algorithms/ch20sample/m15_bracket_match.py similarity index 100% rename from algorithms/ch30sample/m15_bracket_match.py rename to algorithms/ch20sample/m15_bracket_match.py diff --git a/algorithms/ch30sample/m16_circle_queue.py b/algorithms/ch20sample/m16_circle_queue.py similarity index 100% rename from algorithms/ch30sample/m16_circle_queue.py rename to algorithms/ch20sample/m16_circle_queue.py diff --git a/algorithms/leecode/p000/a20_valid_parentheses.py b/algorithms/leecode/p000/a20_valid_parentheses.py index dfb688a..2860296 100644 --- a/algorithms/leecode/p000/a20_valid_parentheses.py +++ b/algorithms/leecode/p000/a20_valid_parentheses.py @@ -23,7 +23,7 @@ 算法思路:栈的最简单的应用。左括号入栈,右括号出栈+对比匹配。不匹配则False,最后栈空则True """ -from algorithms.ch01structure.stack.stack_linked_list import LinkedStack +from algorithms.ch01linear.stack.stack_linked_list import LinkedStack class Solution: diff --git a/algorithms/leecode/p100/a155_min_stack.py b/algorithms/leecode/p100/a155_min_stack.py index 4c6f81a..a58027a 100644 --- a/algorithms/leecode/p100/a155_min_stack.py +++ b/algorithms/leecode/p100/a155_min_stack.py @@ -15,7 +15,7 @@ 通过空间换时间的方法。将每次入栈的节点包装成一个对象,存储两个信息,一个是节点值,一个是当前栈的最小值。 这样获取栈顶元素就同时能获取到这两个值了。 """ -from algorithms.ch01structure import Node +from algorithms.ch01linear import Node class MinStack: From 0ca9b0d0c5110f042d13dd37ca8f4ee8b6162988 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Fri, 15 Apr 2022 00:03:06 +0800 Subject: [PATCH 36/54] update package --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cbf9bcb..489db78 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ * 《算法导论》第3版 * 《LeeCode算法题库》 -章节说明: +## 章节说明 1. 线性表数据结构:数组、链表、队列、栈。 2. 各类排序算法:(冒泡、插入、选择)、(快排、归并)、(桶、计数、基数)。 @@ -27,7 +27,7 @@ 第二部分是LeeCode算法题库,选取其中最具代表性的100个算法题来演示。 从2013年就开始写这个系列,写到动态规划后就停了,期间工作太忙根本抽不出时间来写。 -今年2020年决定继续把之前的捡起来,重新更新这个系列,做事情得有始有终,希望能把这个系列坚持写完。 +今年2021年开始决定继续把之前的捡起来,重新更新这个系列,做事情得有始有终,希望能把这个系列坚持写完。 希望对算法感兴趣的能在杂货铺里挑到自己想要的。 有任何问题都可以联系我: From cbeef319f79f9de7684a72c0908bf4d2159e3b55 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Fri, 15 Apr 2022 00:11:52 +0800 Subject: [PATCH 37/54] update package --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 489db78..dcaa0db 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## 算法杂货铺 - python3实现 +## 飞污熊算法杂货铺 - python3实现 算法参考书籍列表,建议按照顺序阅读: @@ -23,12 +23,12 @@ ## 作者的话 书中经典的算法示例使用python3语言实现,并且配有详细的算法原理说明。 -整个部分分为两个部分,第一个部分是基于`《算法导论》第3版`这两本书中的所有例子写的。作为基础算法部分。 -第二部分是LeeCode算法题库,选取其中最具代表性的100个算法题来演示。 -从2013年就开始写这个系列,写到动态规划后就停了,期间工作太忙根本抽不出时间来写。 -今年2021年开始决定继续把之前的捡起来,重新更新这个系列,做事情得有始有终,希望能把这个系列坚持写完。 -希望对算法感兴趣的能在杂货铺里挑到自己想要的。 +整个部分分为两个部分。第一部分是基于`《算法》第4版`和`《算法导论》第3版`这两本书中的所有例子写的,作为基础算法部分。 +第二部分是LeeCode算法题库的实现,总共实现了XX道题,力争每一道题都会对算法解题思路做一个详细讲解。 + +从2013年就开始写这个系列,写到动态规划后就停了,那段时间实在是太懒了。 +今年2020年开始决定继续把之前的捡起来,重新更新这个系列,做事情得有始有终,希望能把这个系列坚持写完。 有任何问题都可以联系我: From 0d60163fd21a2fe4f82dc954468af301c59d0f54 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Fri, 15 Apr 2022 00:13:01 +0800 Subject: [PATCH 38/54] update package --- mkdocs.yml | 74 ------------------------------------------------------ 1 file changed, 74 deletions(-) delete mode 100644 mkdocs.yml diff --git a/mkdocs.yml b/mkdocs.yml deleted file mode 100644 index 33e703a..0000000 --- a/mkdocs.yml +++ /dev/null @@ -1,74 +0,0 @@ -site_name: 'core-algorithm' -site_author: '熊能' -site_description: '看我七十二变' -site_url: 'https://www.xncoding.com/' -copyright: Copyright © 2020 XiongNeng - -# 源码地址 -#repo_name: 'yidao620c/core-algorithm' -#repo_url: 'https://github.com/yidao620c/core-algorithm' -#edit_uri: 'blob/master/docs/' - -nav: -- Index: index.md -- Documents: - - 第一部分: - - 数据结构: chapters/chapter1/post01.md - - IO操作: chapters/chapter1/post02.md - - 第二部分: - - 多线程: chapters/chapter2/post03.md - - 面向对象编程: chapters/chapter2/post04.md - - 网络编程: chapters/chapter2/post05.md - - 备忘录: - - 我爱你: chapters/chapter2/temp/temp01.md - - 买个锤子: chapters/chapter2/temp/temp02.md -- 关于我们: - - About: about.md - -#主题 -theme: - name: 'material' - language: 'zh' # 配置语言 - palette: # 颜色 - primary: 'light blue' - accent: 'indigo' - feature: - tabs: true # 横向导航 - custom_dir: 'docs/resources/' - -markdown_extensions: - - admonition # 提示块 - - footnotes # 脚注 - - meta # 定义元数据,通过文章上下文控制,如disqus - - pymdownx.caret # 下划线上标 - - pymdownx.tilde # 删除线下标 - - pymdownx.critic # 增加删除修改高亮注释,可修饰行内或段落 - - pymdownx.details # 提示块可折叠 - - pymdownx.inlinehilite # 行内代码高亮 - - pymdownx.keys # 键盘快捷键 - - pymdownx.mark # 文本高亮 - - pymdownx.smartsymbols # 符号转换 - - pymdownx.superfences # 代码嵌套在列表里 - - codehilite: # 代码高亮,显示行号 - guess_lang: false - linenums: true - - toc: # 锚点 - permalink: true -# - pymdownx.arithmatex # 数学公式 - - pymdownx.betterem: # 对加粗和斜体更好的检测 - smart_enable: all -# - pymdownx.emoji: # 表情 -# emoji_generator: !!python/name:pymdownx.emoji.to_svg -# - pymdownx.magiclink # 自动识别超链接 - - pymdownx.tasklist: # 复选框checklist - custom_checkbox: true - -# PDF导出插件 -plugins: - - search -# - pdf-export #这个插件还有点问题,没有更新 - -#扩展样式 -extra_css: - - resources/css/extra.css - From 4d06cb50b9ae0fae481da43dfbeac2e5735b4a49 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Sun, 17 Apr 2022 11:06:52 +0800 Subject: [PATCH 39/54] update --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index dcaa0db..2bee266 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## 飞污熊算法杂货铺 - python3实现 +## 飞污熊算法笔记 - python3实现 算法参考书籍列表,建议按照顺序阅读: @@ -24,7 +24,7 @@ 书中经典的算法示例使用python3语言实现,并且配有详细的算法原理说明。 -整个部分分为两个部分。第一部分是基于`《算法》第4版`和`《算法导论》第3版`这两本书中的所有例子写的,作为基础算法部分。 +整个部分分为两个部分。第一部分是阅读经典算法书籍后自己的总结,作为基础算法部分。 第二部分是LeeCode算法题库的实现,总共实现了XX道题,力争每一道题都会对算法解题思路做一个详细讲解。 从2013年就开始写这个系列,写到动态规划后就停了,那段时间实在是太懒了。 From 3897fef22b170721294666b0f38d492f63aae091 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Thu, 3 Aug 2023 03:29:32 +0800 Subject: [PATCH 40/54] update --- README.md | 39 +++--- .../{ch01linear => c01_linear}/__init__.py | 0 .../linkedlist/__init__.py | 0 .../linkedlist/linked_list_double.py | 2 +- .../linkedlist/linked_list_double_cycle.py | 2 +- .../linkedlist/linked_list_single.py | 2 +- .../linkedlist/linked_list_single_cycle.py | 2 +- .../linkedlist/lru_cache.py | 4 +- .../linkedlist/palindromic_number.py | 4 +- .../queue/__init__.py | 0 .../queue/array_queue.py | 0 .../queue/linked_queue.py | 2 +- .../queue/prior_queue.py | 2 +- .../stack/__init__.py | 0 .../stack/stack_array.py | 2 +- .../stack/stack_linked_list.py | 2 +- algorithms/{ch02sort => c02_sort}/__init__.py | 0 .../{ch02sort => c02_sort}/base/__init__.py | 0 .../{ch02sort => c02_sort}/base/sortutil.py | 0 .../{ch02sort => c02_sort}/base/template.py | 0 .../{ch02sort => c02_sort}/m00_bubble_sort.py | 2 +- .../{ch02sort => c02_sort}/m01_insert_sort.py | 4 +- .../{ch02sort => c02_sort}/m02_select_sort.py | 2 +- .../{ch02sort => c02_sort}/m03_merge_sort.py | 2 +- .../m04_merge_insert_sort.py | 4 +- .../{ch02sort => c02_sort}/m05_quick_sort.py | 2 +- .../{ch02sort => c02_sort}/m06_heap_sort.py | 2 +- .../{ch02sort => c02_sort}/m07_count_sort.py | 0 .../{ch02sort => c02_sort}/m08_radix_sort.py | 0 .../{ch02sort => c02_sort}/m09_bucket_sort.py | 2 +- .../{ch02sort => c02_sort}/m10_find_minmax.py | 0 .../{ch02sort => c02_sort}/m11_imin_select.py | 0 .../m12_imin_select2.py | 2 +- .../{ch02sort => c02_sort}/m13_imin_list.py | 2 +- .../{ch03search => c03_search}/__init__.py | 0 algorithms/{ch04tree => c04_tree}/__init__.py | 0 .../{ch04tree => c04_tree}/bisearch_tree.py | 0 algorithms/c04_tree/btree.py | 129 ++++++++++++++++++ .../{ch04tree => c04_tree}/redblack_tree.py | 2 +- .../{ch05graph => c05_graph}/__init__.py | 0 .../{ch06string => c06_string}/__init__.py | 0 .../{ch07greedy => c07_greedy}/__init__.py | 0 .../m01_activity.py | 0 .../{ch08divide => c08_divide}/__init__.py | 0 .../__init__.py | 0 .../{ch10dynamic => c10_dynamic}/__init__.py | 0 .../m01_cut_steel.py | 0 .../m02_fibonacci.py | 0 .../m03_matrix_chain.py | 0 .../m04_elevator.py | 0 .../m05_subsequence.py | 0 .../{ch10dynamic => c10_dynamic}/m06_bag.py | 0 .../__init__.py | 0 .../{leecode/p000 => c12_ai}/__init__.py | 0 .../{ch20sample => c13_sample}/__init__.py | 0 .../{ch20sample => c13_sample}/m01_math.py | 0 .../m02_triangle_str.py | 0 .../m03_duplicate_words.py | 0 .../m04_binary_add.py | 0 .../m05_nine_number.py | 0 .../m06_hornerpoly.py | 0 .../m07_max_subarr.py | 0 .../m08_max_subarr2.py | 0 .../m09_max_subarr3.py | 0 .../m10_code_funny.py | 0 .../m11_rand_permute.py | 0 .../m12_right_shift.py | 0 .../{ch20sample => c13_sample}/m13_sin_cpu.py | 0 .../m14_bestsinger.py | 0 .../m15_bracket_match.py | 0 .../m16_circle_queue.py | 0 .../{leecode => c14_leetcode}/__init__.py | 0 .../p100 => c14_leetcode/p000}/__init__.py | 0 .../a19_remove_nth_node_from_end_of_list.py | 0 .../p000/a20_valid_parentheses.py | 2 +- .../p000/a21_merge_two_sorted_lists.py | 0 .../p000/a70_climbing_stairs.py | 0 .../p1000 => c14_leetcode/p100}/__init__.py | 0 .../p100/a141_linked_list_cycle.py | 0 .../p100/a155_min_stack.py | 2 +- .../p1100 => c14_leetcode/p1000}/__init__.py | 0 .../p1200 => c14_leetcode/p1100}/__init__.py | 0 .../p1300 => c14_leetcode/p1200}/__init__.py | 0 .../p1400 => c14_leetcode/p1300}/__init__.py | 0 .../p1500 => c14_leetcode/p1400}/__init__.py | 0 .../p1600 => c14_leetcode/p1500}/__init__.py | 0 .../p1700 => c14_leetcode/p1600}/__init__.py | 0 .../p1800 => c14_leetcode/p1700}/__init__.py | 0 .../p1900 => c14_leetcode/p1800}/__init__.py | 0 .../p200 => c14_leetcode/p1900}/__init__.py | 0 .../p2000 => c14_leetcode/p200}/__init__.py | 0 .../p200/a206_reverse_linked_list.py | 0 .../a215_kth_largest_element_in_an_array.py | 0 .../p200/a224_basic_calculator.py | 0 .../p200/a232_implement_queue_using_stacks.py | 0 .../p2100 => c14_leetcode/p2000}/__init__.py | 0 .../p2200 => c14_leetcode/p2100}/__init__.py | 0 .../p300 => c14_leetcode/p2200}/__init__.py | 0 .../p400 => c14_leetcode/p300}/__init__.py | 0 .../p300/a392_is_subsequence.py | 0 .../p500 => c14_leetcode/p400}/__init__.py | 0 .../p400/a496_next_greater_element.py | 0 .../p600 => c14_leetcode/p500}/__init__.py | 0 .../p700 => c14_leetcode/p600}/__init__.py | 0 .../p600/a682_baseball_game.py | 0 .../p800 => c14_leetcode/p700}/__init__.py | 0 .../p900 => c14_leetcode/p800}/__init__.py | 0 .../p800/a844_backspace_string_compare.py | 0 .../p800/a876_middle_of_the_linked_list.py | 0 algorithms/c14_leetcode/p900/__init__.py | 4 + 110 files changed, 182 insertions(+), 44 deletions(-) rename algorithms/{ch01linear => c01_linear}/__init__.py (100%) rename algorithms/{ch01linear => c01_linear}/linkedlist/__init__.py (100%) rename algorithms/{ch01linear => c01_linear}/linkedlist/linked_list_double.py (96%) rename algorithms/{ch01linear => c01_linear}/linkedlist/linked_list_double_cycle.py (97%) rename algorithms/{ch01linear => c01_linear}/linkedlist/linked_list_single.py (98%) rename algorithms/{ch01linear => c01_linear}/linkedlist/linked_list_single_cycle.py (97%) rename algorithms/{ch01linear => c01_linear}/linkedlist/lru_cache.py (93%) rename algorithms/{ch01linear => c01_linear}/linkedlist/palindromic_number.py (96%) rename algorithms/{ch01linear => c01_linear}/queue/__init__.py (100%) rename algorithms/{ch01linear => c01_linear}/queue/array_queue.py (100%) rename algorithms/{ch01linear => c01_linear}/queue/linked_queue.py (97%) rename algorithms/{ch01linear => c01_linear}/queue/prior_queue.py (98%) rename algorithms/{ch01linear => c01_linear}/stack/__init__.py (100%) rename algorithms/{ch01linear => c01_linear}/stack/stack_array.py (97%) rename algorithms/{ch01linear => c01_linear}/stack/stack_linked_list.py (96%) rename algorithms/{ch02sort => c02_sort}/__init__.py (100%) rename algorithms/{ch02sort => c02_sort}/base/__init__.py (100%) rename algorithms/{ch02sort => c02_sort}/base/sortutil.py (100%) rename algorithms/{ch02sort => c02_sort}/base/template.py (100%) rename algorithms/{ch02sort => c02_sort}/m00_bubble_sort.py (93%) rename algorithms/{ch02sort => c02_sort}/m01_insert_sort.py (91%) rename algorithms/{ch02sort => c02_sort}/m02_select_sort.py (94%) rename algorithms/{ch02sort => c02_sort}/m03_merge_sort.py (97%) rename algorithms/{ch02sort => c02_sort}/m04_merge_insert_sort.py (96%) rename algorithms/{ch02sort => c02_sort}/m05_quick_sort.py (97%) rename algorithms/{ch02sort => c02_sort}/m06_heap_sort.py (97%) rename algorithms/{ch02sort => c02_sort}/m07_count_sort.py (100%) rename algorithms/{ch02sort => c02_sort}/m08_radix_sort.py (100%) rename algorithms/{ch02sort => c02_sort}/m09_bucket_sort.py (94%) rename algorithms/{ch02sort => c02_sort}/m10_find_minmax.py (100%) rename algorithms/{ch02sort => c02_sort}/m11_imin_select.py (100%) rename algorithms/{ch02sort => c02_sort}/m12_imin_select2.py (97%) rename algorithms/{ch02sort => c02_sort}/m13_imin_list.py (94%) rename algorithms/{ch03search => c03_search}/__init__.py (100%) rename algorithms/{ch04tree => c04_tree}/__init__.py (100%) rename algorithms/{ch04tree => c04_tree}/bisearch_tree.py (100%) create mode 100644 algorithms/c04_tree/btree.py rename algorithms/{ch04tree => c04_tree}/redblack_tree.py (99%) rename algorithms/{ch05graph => c05_graph}/__init__.py (100%) rename algorithms/{ch06string => c06_string}/__init__.py (100%) rename algorithms/{ch07greedy => c07_greedy}/__init__.py (100%) rename algorithms/{ch07greedy => c07_greedy}/m01_activity.py (100%) rename algorithms/{ch08divide => c08_divide}/__init__.py (100%) rename algorithms/{ch09backtrack => c09_backtrack}/__init__.py (100%) rename algorithms/{ch10dynamic => c10_dynamic}/__init__.py (100%) rename algorithms/{ch10dynamic => c10_dynamic}/m01_cut_steel.py (100%) rename algorithms/{ch10dynamic => c10_dynamic}/m02_fibonacci.py (100%) rename algorithms/{ch10dynamic => c10_dynamic}/m03_matrix_chain.py (100%) rename algorithms/{ch10dynamic => c10_dynamic}/m04_elevator.py (100%) rename algorithms/{ch10dynamic => c10_dynamic}/m05_subsequence.py (100%) rename algorithms/{ch10dynamic => c10_dynamic}/m06_bag.py (100%) rename algorithms/{ch11advanced => c11_advanced}/__init__.py (100%) rename algorithms/{leecode/p000 => c12_ai}/__init__.py (100%) rename algorithms/{ch20sample => c13_sample}/__init__.py (100%) rename algorithms/{ch20sample => c13_sample}/m01_math.py (100%) rename algorithms/{ch20sample => c13_sample}/m02_triangle_str.py (100%) rename algorithms/{ch20sample => c13_sample}/m03_duplicate_words.py (100%) rename algorithms/{ch20sample => c13_sample}/m04_binary_add.py (100%) rename algorithms/{ch20sample => c13_sample}/m05_nine_number.py (100%) rename algorithms/{ch20sample => c13_sample}/m06_hornerpoly.py (100%) rename algorithms/{ch20sample => c13_sample}/m07_max_subarr.py (100%) rename algorithms/{ch20sample => c13_sample}/m08_max_subarr2.py (100%) rename algorithms/{ch20sample => c13_sample}/m09_max_subarr3.py (100%) rename algorithms/{ch20sample => c13_sample}/m10_code_funny.py (100%) rename algorithms/{ch20sample => c13_sample}/m11_rand_permute.py (100%) rename algorithms/{ch20sample => c13_sample}/m12_right_shift.py (100%) rename algorithms/{ch20sample => c13_sample}/m13_sin_cpu.py (100%) rename algorithms/{ch20sample => c13_sample}/m14_bestsinger.py (100%) rename algorithms/{ch20sample => c13_sample}/m15_bracket_match.py (100%) rename algorithms/{ch20sample => c13_sample}/m16_circle_queue.py (100%) rename algorithms/{leecode => c14_leetcode}/__init__.py (100%) rename algorithms/{leecode/p100 => c14_leetcode/p000}/__init__.py (100%) rename algorithms/{leecode => c14_leetcode}/p000/a19_remove_nth_node_from_end_of_list.py (100%) rename algorithms/{leecode => c14_leetcode}/p000/a20_valid_parentheses.py (95%) rename algorithms/{leecode => c14_leetcode}/p000/a21_merge_two_sorted_lists.py (100%) rename algorithms/{leecode => c14_leetcode}/p000/a70_climbing_stairs.py (100%) rename algorithms/{leecode/p1000 => c14_leetcode/p100}/__init__.py (100%) rename algorithms/{leecode => c14_leetcode}/p100/a141_linked_list_cycle.py (100%) rename algorithms/{leecode => c14_leetcode}/p100/a155_min_stack.py (97%) rename algorithms/{leecode/p1100 => c14_leetcode/p1000}/__init__.py (100%) rename algorithms/{leecode/p1200 => c14_leetcode/p1100}/__init__.py (100%) rename algorithms/{leecode/p1300 => c14_leetcode/p1200}/__init__.py (100%) rename algorithms/{leecode/p1400 => c14_leetcode/p1300}/__init__.py (100%) rename algorithms/{leecode/p1500 => c14_leetcode/p1400}/__init__.py (100%) rename algorithms/{leecode/p1600 => c14_leetcode/p1500}/__init__.py (100%) rename algorithms/{leecode/p1700 => c14_leetcode/p1600}/__init__.py (100%) rename algorithms/{leecode/p1800 => c14_leetcode/p1700}/__init__.py (100%) rename algorithms/{leecode/p1900 => c14_leetcode/p1800}/__init__.py (100%) rename algorithms/{leecode/p200 => c14_leetcode/p1900}/__init__.py (100%) rename algorithms/{leecode/p2000 => c14_leetcode/p200}/__init__.py (100%) rename algorithms/{leecode => c14_leetcode}/p200/a206_reverse_linked_list.py (100%) rename algorithms/{leecode => c14_leetcode}/p200/a215_kth_largest_element_in_an_array.py (100%) rename algorithms/{leecode => c14_leetcode}/p200/a224_basic_calculator.py (100%) rename algorithms/{leecode => c14_leetcode}/p200/a232_implement_queue_using_stacks.py (100%) rename algorithms/{leecode/p2100 => c14_leetcode/p2000}/__init__.py (100%) rename algorithms/{leecode/p2200 => c14_leetcode/p2100}/__init__.py (100%) rename algorithms/{leecode/p300 => c14_leetcode/p2200}/__init__.py (100%) rename algorithms/{leecode/p400 => c14_leetcode/p300}/__init__.py (100%) rename algorithms/{leecode => c14_leetcode}/p300/a392_is_subsequence.py (100%) rename algorithms/{leecode/p500 => c14_leetcode/p400}/__init__.py (100%) rename algorithms/{leecode => c14_leetcode}/p400/a496_next_greater_element.py (100%) rename algorithms/{leecode/p600 => c14_leetcode/p500}/__init__.py (100%) rename algorithms/{leecode/p700 => c14_leetcode/p600}/__init__.py (100%) rename algorithms/{leecode => c14_leetcode}/p600/a682_baseball_game.py (100%) rename algorithms/{leecode/p800 => c14_leetcode/p700}/__init__.py (100%) rename algorithms/{leecode/p900 => c14_leetcode/p800}/__init__.py (100%) rename algorithms/{leecode => c14_leetcode}/p800/a844_backspace_string_compare.py (100%) rename algorithms/{leecode => c14_leetcode}/p800/a876_middle_of_the_linked_list.py (100%) create mode 100644 algorithms/c14_leetcode/p900/__init__.py diff --git a/README.md b/README.md index 2bee266..2bed321 100644 --- a/README.md +++ b/README.md @@ -2,30 +2,35 @@ 算法参考书籍列表,建议按照顺序阅读: -* 《算法》第4版 -* 《算法导论》第3版 -* 《LeeCode算法题库》 +* 《算法图解》 +* 《啊哈算法》 +* 《算法导论》 +* 《人工智能算法图解》 +* 《labuladong的算法小抄》 ## 章节说明 -1. 线性表数据结构:数组、链表、队列、栈。 -2. 各类排序算法:(冒泡、插入、选择)、(快排、归并)、(桶、计数、基数)。 -3. 查找算法:二分查找、调表、散列表、哈希算法 -4. 树数据结构:二叉树、红黑树、递归树、堆。 -5. 图数据结构 -6. 字符串匹配算法 -7. 贪心算法 -8. 分治算法 -9. 回溯算法 -10. 动态规划算法 -11. 高级数据结构和算法 +1. 【第一章】线性表数据结构:数组、链表、队列、栈。 +2. 【第二章】各类排序算法:(冒泡、插入、选择)、(快排、归并)、(桶、计数、基数)。 +3. 【第三章】各类搜索算法:二分查找、调表、散列表、哈希算法 +4. 【第四章】树数据结构:二叉树、红黑树、递归树、堆。 +5. 【第五章】图数据结构 +6. 【第六章】字符串匹配算法 +7. 【第七章】贪心算法 +8. 【第八章】分治算法 +9. 【第九章】回溯算法 +10. 【第十章】动态规划算法 +11. 【第十一章】高级数据结构和算法 +12. 【第十二章】AI算法 +13. 【第十三章】算法示例程序 +14. 【第十四章】LeetCode刷题记录 ## 作者的话 -书中经典的算法示例使用python3语言实现,并且配有详细的算法原理说明。 +书中经典的算法示例使用python3语言实现。 -整个部分分为两个部分。第一部分是阅读经典算法书籍后自己的总结,作为基础算法部分。 -第二部分是LeeCode算法题库的实现,总共实现了XX道题,力争每一道题都会对算法解题思路做一个详细讲解。 +整个工程分为三个部分。第1部分是阅读经典算法书籍后自己的总结,作为基础算法部分。 +第2部分是人工智能AI算法示例,第3部分是自己在LeetCode上面的刷题总结。 从2013年就开始写这个系列,写到动态规划后就停了,那段时间实在是太懒了。 今年2020年开始决定继续把之前的捡起来,重新更新这个系列,做事情得有始有终,希望能把这个系列坚持写完。 diff --git a/algorithms/ch01linear/__init__.py b/algorithms/c01_linear/__init__.py similarity index 100% rename from algorithms/ch01linear/__init__.py rename to algorithms/c01_linear/__init__.py diff --git a/algorithms/ch01linear/linkedlist/__init__.py b/algorithms/c01_linear/linkedlist/__init__.py similarity index 100% rename from algorithms/ch01linear/linkedlist/__init__.py rename to algorithms/c01_linear/linkedlist/__init__.py diff --git a/algorithms/ch01linear/linkedlist/linked_list_double.py b/algorithms/c01_linear/linkedlist/linked_list_double.py similarity index 96% rename from algorithms/ch01linear/linkedlist/linked_list_double.py rename to algorithms/c01_linear/linkedlist/linked_list_double.py index 691cfde..414d099 100644 --- a/algorithms/ch01linear/linkedlist/linked_list_double.py +++ b/algorithms/c01_linear/linkedlist/linked_list_double.py @@ -2,7 +2,7 @@ """ 双向链表数据结构 """ -from algorithms.ch01linear import NodeDouble +from algorithms.c01_linear import NodeDouble class LinkedListDouble: diff --git a/algorithms/ch01linear/linkedlist/linked_list_double_cycle.py b/algorithms/c01_linear/linkedlist/linked_list_double_cycle.py similarity index 97% rename from algorithms/ch01linear/linkedlist/linked_list_double_cycle.py rename to algorithms/c01_linear/linkedlist/linked_list_double_cycle.py index c700796..a988215 100644 --- a/algorithms/ch01linear/linkedlist/linked_list_double_cycle.py +++ b/algorithms/c01_linear/linkedlist/linked_list_double_cycle.py @@ -2,7 +2,7 @@ """ 双向循环链表数据结构 """ -from algorithms.ch01linear import NodeDouble +from algorithms.c01_linear import NodeDouble class LinkedListDouble: diff --git a/algorithms/ch01linear/linkedlist/linked_list_single.py b/algorithms/c01_linear/linkedlist/linked_list_single.py similarity index 98% rename from algorithms/ch01linear/linkedlist/linked_list_single.py rename to algorithms/c01_linear/linkedlist/linked_list_single.py index fb543ad..d1b1b30 100644 --- a/algorithms/ch01linear/linkedlist/linked_list_single.py +++ b/algorithms/c01_linear/linkedlist/linked_list_single.py @@ -2,7 +2,7 @@ """ 单向链表数据结构 """ -from algorithms.ch01linear import Node +from algorithms.c01_linear import Node class LinkedListSingle: diff --git a/algorithms/ch01linear/linkedlist/linked_list_single_cycle.py b/algorithms/c01_linear/linkedlist/linked_list_single_cycle.py similarity index 97% rename from algorithms/ch01linear/linkedlist/linked_list_single_cycle.py rename to algorithms/c01_linear/linkedlist/linked_list_single_cycle.py index 4a06152..9a73142 100644 --- a/algorithms/ch01linear/linkedlist/linked_list_single_cycle.py +++ b/algorithms/c01_linear/linkedlist/linked_list_single_cycle.py @@ -2,7 +2,7 @@ """ 单向循环链表数据结构 """ -from algorithms.ch01linear import Node +from algorithms.c01_linear import Node class LinkedListSingleCycle: diff --git a/algorithms/ch01linear/linkedlist/lru_cache.py b/algorithms/c01_linear/linkedlist/lru_cache.py similarity index 93% rename from algorithms/ch01linear/linkedlist/lru_cache.py rename to algorithms/c01_linear/linkedlist/lru_cache.py index 2e4b723..a1ce6af 100644 --- a/algorithms/ch01linear/linkedlist/lru_cache.py +++ b/algorithms/c01_linear/linkedlist/lru_cache.py @@ -11,8 +11,8 @@ 2.1 如果此时缓存未满,则将此结点直接插入到链表的头部; 2.2 如果此时缓存已满,则链表尾结点删除,将新的数据结点插入链表的头部。 """ -from algorithms.ch01linear import Node -from algorithms.ch01linear.linkedlist.linked_list_single import LinkedListSingle +from algorithms.c01_linear import Node +from algorithms.c01_linear.linkedlist.linked_list_single import LinkedListSingle def lru(list_single_, data): diff --git a/algorithms/ch01linear/linkedlist/palindromic_number.py b/algorithms/c01_linear/linkedlist/palindromic_number.py similarity index 96% rename from algorithms/ch01linear/linkedlist/palindromic_number.py rename to algorithms/c01_linear/linkedlist/palindromic_number.py index 49d6e7b..7ba3720 100644 --- a/algorithms/ch01linear/linkedlist/palindromic_number.py +++ b/algorithms/c01_linear/linkedlist/palindromic_number.py @@ -14,8 +14,8 @@ 1.2.1 如果是返回上中位数,后半部分串头取next <<=这里使用这张上中位数数 1.2.2 如果是返回下中位数,后半部分串头既是当前节点位置,但前半部分串尾要删除掉当前节点 """ -from algorithms.ch01linear import Node -from algorithms.ch01linear.linkedlist.linked_list_single import LinkedListSingle +from algorithms.c01_linear import Node +from algorithms.c01_linear.linkedlist.linked_list_single import LinkedListSingle def palindromic(list_single_): diff --git a/algorithms/ch01linear/queue/__init__.py b/algorithms/c01_linear/queue/__init__.py similarity index 100% rename from algorithms/ch01linear/queue/__init__.py rename to algorithms/c01_linear/queue/__init__.py diff --git a/algorithms/ch01linear/queue/array_queue.py b/algorithms/c01_linear/queue/array_queue.py similarity index 100% rename from algorithms/ch01linear/queue/array_queue.py rename to algorithms/c01_linear/queue/array_queue.py diff --git a/algorithms/ch01linear/queue/linked_queue.py b/algorithms/c01_linear/queue/linked_queue.py similarity index 97% rename from algorithms/ch01linear/queue/linked_queue.py rename to algorithms/c01_linear/queue/linked_queue.py index a8ba1ae..1ae58d7 100644 --- a/algorithms/ch01linear/queue/linked_queue.py +++ b/algorithms/c01_linear/queue/linked_queue.py @@ -2,7 +2,7 @@ """基于链表实现的一个简单队列 队尾插入元素,队头取元素。就跟在菜市场排队买菜原理是一样的 """ -from algorithms.ch01linear import Node +from algorithms.c01_linear import Node class LinkedQueue: diff --git a/algorithms/ch01linear/queue/prior_queue.py b/algorithms/c01_linear/queue/prior_queue.py similarity index 98% rename from algorithms/ch01linear/queue/prior_queue.py rename to algorithms/c01_linear/queue/prior_queue.py index 8e3a373..51c138a 100644 --- a/algorithms/ch01linear/queue/prior_queue.py +++ b/algorithms/c01_linear/queue/prior_queue.py @@ -4,7 +4,7 @@ """ from functools import total_ordering -from algorithms.ch01linear.stack.stack_linked_list import LinkedStack +from algorithms.c01_linear.stack.stack_linked_list import LinkedStack class MaxPriorQueue: diff --git a/algorithms/ch01linear/stack/__init__.py b/algorithms/c01_linear/stack/__init__.py similarity index 100% rename from algorithms/ch01linear/stack/__init__.py rename to algorithms/c01_linear/stack/__init__.py diff --git a/algorithms/ch01linear/stack/stack_array.py b/algorithms/c01_linear/stack/stack_array.py similarity index 97% rename from algorithms/ch01linear/stack/stack_array.py rename to algorithms/c01_linear/stack/stack_array.py index ebd760a..029f53a 100644 --- a/algorithms/ch01linear/stack/stack_array.py +++ b/algorithms/c01_linear/stack/stack_array.py @@ -2,7 +2,7 @@ """ 基于数组实现的栈结构 """ -from algorithms.ch01linear import Node +from algorithms.c01_linear import Node class ArrayStack: diff --git a/algorithms/ch01linear/stack/stack_linked_list.py b/algorithms/c01_linear/stack/stack_linked_list.py similarity index 96% rename from algorithms/ch01linear/stack/stack_linked_list.py rename to algorithms/c01_linear/stack/stack_linked_list.py index d2b80c0..02417bc 100644 --- a/algorithms/ch01linear/stack/stack_linked_list.py +++ b/algorithms/c01_linear/stack/stack_linked_list.py @@ -4,7 +4,7 @@ 另一方面,迭代器应该一直可以迭代。迭代器的 `__iter__` 方法应该返回自身。 一般可使用生成器函数实现更符合python风格的可迭代对象。 """ -from algorithms.ch01linear import Node +from algorithms.c01_linear import Node class LinkedStack: diff --git a/algorithms/ch02sort/__init__.py b/algorithms/c02_sort/__init__.py similarity index 100% rename from algorithms/ch02sort/__init__.py rename to algorithms/c02_sort/__init__.py diff --git a/algorithms/ch02sort/base/__init__.py b/algorithms/c02_sort/base/__init__.py similarity index 100% rename from algorithms/ch02sort/base/__init__.py rename to algorithms/c02_sort/base/__init__.py diff --git a/algorithms/ch02sort/base/sortutil.py b/algorithms/c02_sort/base/sortutil.py similarity index 100% rename from algorithms/ch02sort/base/sortutil.py rename to algorithms/c02_sort/base/sortutil.py diff --git a/algorithms/ch02sort/base/template.py b/algorithms/c02_sort/base/template.py similarity index 100% rename from algorithms/ch02sort/base/template.py rename to algorithms/c02_sort/base/template.py diff --git a/algorithms/ch02sort/m00_bubble_sort.py b/algorithms/c02_sort/m00_bubble_sort.py similarity index 93% rename from algorithms/ch02sort/m00_bubble_sort.py rename to algorithms/c02_sort/m00_bubble_sort.py index f2ccee5..516c0dd 100644 --- a/algorithms/ch02sort/m00_bubble_sort.py +++ b/algorithms/c02_sort/m00_bubble_sort.py @@ -6,7 +6,7 @@ 算法复杂度:N^2 稳定排序:重复元素排序完后仍然保持原来的相对位置。 """ -from algorithms.ch02sort.base.template import SortTemplate +from algorithms.c02_sort.base.template import SortTemplate class BubbleSort(SortTemplate): diff --git a/algorithms/ch02sort/m01_insert_sort.py b/algorithms/c02_sort/m01_insert_sort.py similarity index 91% rename from algorithms/ch02sort/m01_insert_sort.py rename to algorithms/c02_sort/m01_insert_sort.py index a7e1067..abb2428 100644 --- a/algorithms/ch02sort/m01_insert_sort.py +++ b/algorithms/c02_sort/m01_insert_sort.py @@ -14,8 +14,8 @@ 算法复杂度:N^2 稳定排序:重复元素排序完后仍然保持原来的相对位置。 """ -from algorithms.ch02sort.base.sortutil import insert_sort -from algorithms.ch02sort.base.template import SortTemplate +from algorithms.c02_sort.base.sortutil import insert_sort +from algorithms.c02_sort.base.template import SortTemplate class InsertSort(SortTemplate): diff --git a/algorithms/ch02sort/m02_select_sort.py b/algorithms/c02_sort/m02_select_sort.py similarity index 94% rename from algorithms/ch02sort/m02_select_sort.py rename to algorithms/c02_sort/m02_select_sort.py index f156fdd..693b5b6 100644 --- a/algorithms/ch02sort/m02_select_sort.py +++ b/algorithms/c02_sort/m02_select_sort.py @@ -8,7 +8,7 @@ 不稳定排序,使用场景少。 复杂度:O(N^2),大约需要N^2/2次比较和N次交换。 """ -from algorithms.ch02sort.base.template import SortTemplate +from algorithms.c02_sort.base.template import SortTemplate class SelectSort(SortTemplate): diff --git a/algorithms/ch02sort/m03_merge_sort.py b/algorithms/c02_sort/m03_merge_sort.py similarity index 97% rename from algorithms/ch02sort/m03_merge_sort.py rename to algorithms/c02_sort/m03_merge_sort.py index ccec0de..bf427ab 100644 --- a/algorithms/ch02sort/m03_merge_sort.py +++ b/algorithms/c02_sort/m03_merge_sort.py @@ -10,7 +10,7 @@ 它有一个致命的“弱点”,那就是归并排序不是原地排序算法。 """ -from algorithms.ch02sort.base.template import SortTemplate +from algorithms.c02_sort.base.template import SortTemplate class MergeSort(SortTemplate): diff --git a/algorithms/ch02sort/m04_merge_insert_sort.py b/algorithms/c02_sort/m04_merge_insert_sort.py similarity index 96% rename from algorithms/ch02sort/m04_merge_insert_sort.py rename to algorithms/c02_sort/m04_merge_insert_sort.py index fd54437..03a453b 100644 --- a/algorithms/ch02sort/m04_merge_insert_sort.py +++ b/algorithms/c02_sort/m04_merge_insert_sort.py @@ -20,8 +20,8 @@ """ from math import log -from algorithms.ch02sort.base.sortutil import insert_sort -from algorithms.ch02sort.base.template import SortTemplate +from algorithms.c02_sort.base.sortutil import insert_sort +from algorithms.c02_sort.base.template import SortTemplate class MergeAndInsertSort(SortTemplate): diff --git a/algorithms/ch02sort/m05_quick_sort.py b/algorithms/c02_sort/m05_quick_sort.py similarity index 97% rename from algorithms/ch02sort/m05_quick_sort.py rename to algorithms/c02_sort/m05_quick_sort.py index ca4c06f..0904519 100644 --- a/algorithms/ch02sort/m05_quick_sort.py +++ b/algorithms/c02_sort/m05_quick_sort.py @@ -17,7 +17,7 @@ """ from random import randint -from algorithms.ch02sort.base.template import SortTemplate +from algorithms.c02_sort.base.template import SortTemplate class QuickSort(SortTemplate): diff --git a/algorithms/ch02sort/m06_heap_sort.py b/algorithms/c02_sort/m06_heap_sort.py similarity index 97% rename from algorithms/ch02sort/m06_heap_sort.py rename to algorithms/c02_sort/m06_heap_sort.py index 7efc658..2cf3eef 100644 --- a/algorithms/ch02sort/m06_heap_sort.py +++ b/algorithms/c02_sort/m06_heap_sort.py @@ -2,7 +2,7 @@ """使用二叉堆实现堆排序最优雅代码 原理:如果左右子树都已经是最大堆了,则通过下沉当前根节点操作即可重新构造为一个最大堆。 """ -from algorithms.ch02sort.base.template import SortTemplate +from algorithms.c02_sort.base.template import SortTemplate class HeapSort(SortTemplate): diff --git a/algorithms/ch02sort/m07_count_sort.py b/algorithms/c02_sort/m07_count_sort.py similarity index 100% rename from algorithms/ch02sort/m07_count_sort.py rename to algorithms/c02_sort/m07_count_sort.py diff --git a/algorithms/ch02sort/m08_radix_sort.py b/algorithms/c02_sort/m08_radix_sort.py similarity index 100% rename from algorithms/ch02sort/m08_radix_sort.py rename to algorithms/c02_sort/m08_radix_sort.py diff --git a/algorithms/ch02sort/m09_bucket_sort.py b/algorithms/c02_sort/m09_bucket_sort.py similarity index 94% rename from algorithms/ch02sort/m09_bucket_sort.py rename to algorithms/c02_sort/m09_bucket_sort.py index 15dc8d1..a5fcb1f 100644 --- a/algorithms/ch02sort/m09_bucket_sort.py +++ b/algorithms/c02_sort/m09_bucket_sort.py @@ -11,7 +11,7 @@ """ from math import floor -from algorithms.ch02sort.base.sortutil import insert_sort +from algorithms.c02_sort.base.sortutil import insert_sort def bucketSort(A): diff --git a/algorithms/ch02sort/m10_find_minmax.py b/algorithms/c02_sort/m10_find_minmax.py similarity index 100% rename from algorithms/ch02sort/m10_find_minmax.py rename to algorithms/c02_sort/m10_find_minmax.py diff --git a/algorithms/ch02sort/m11_imin_select.py b/algorithms/c02_sort/m11_imin_select.py similarity index 100% rename from algorithms/ch02sort/m11_imin_select.py rename to algorithms/c02_sort/m11_imin_select.py diff --git a/algorithms/ch02sort/m12_imin_select2.py b/algorithms/c02_sort/m12_imin_select2.py similarity index 97% rename from algorithms/ch02sort/m12_imin_select2.py rename to algorithms/c02_sort/m12_imin_select2.py index 4065d31..727f120 100644 --- a/algorithms/ch02sort/m12_imin_select2.py +++ b/algorithms/c02_sort/m12_imin_select2.py @@ -6,7 +6,7 @@ Desc : 顺序统计量的选择算法(最坏情况下O(n)) 利用中位数的中位数作为pivot划分数组 """ -from algorithms.ch02sort.base.sortutil import insert_sort +from algorithms.c02_sort.base.sortutil import insert_sort def iminSelect2(A, i): diff --git a/algorithms/ch02sort/m13_imin_list.py b/algorithms/c02_sort/m13_imin_list.py similarity index 94% rename from algorithms/ch02sort/m13_imin_list.py rename to algorithms/c02_sort/m13_imin_list.py index ff17fac..1a04ac5 100644 --- a/algorithms/ch02sort/m13_imin_list.py +++ b/algorithms/c02_sort/m13_imin_list.py @@ -7,7 +7,7 @@ 先通过找到第i小的数,然后将这个数作为pivot去划分这个数组, 左边 + 这个pivot即是解 """ -from algorithms.ch02sort.m12_imin_select2 import iminSelect2 +from algorithms.c02_sort.m12_imin_select2 import iminSelect2 def iminList(A, i): diff --git a/algorithms/ch03search/__init__.py b/algorithms/c03_search/__init__.py similarity index 100% rename from algorithms/ch03search/__init__.py rename to algorithms/c03_search/__init__.py diff --git a/algorithms/ch04tree/__init__.py b/algorithms/c04_tree/__init__.py similarity index 100% rename from algorithms/ch04tree/__init__.py rename to algorithms/c04_tree/__init__.py diff --git a/algorithms/ch04tree/bisearch_tree.py b/algorithms/c04_tree/bisearch_tree.py similarity index 100% rename from algorithms/ch04tree/bisearch_tree.py rename to algorithms/c04_tree/bisearch_tree.py diff --git a/algorithms/c04_tree/btree.py b/algorithms/c04_tree/btree.py new file mode 100644 index 0000000..15a223c --- /dev/null +++ b/algorithms/c04_tree/btree.py @@ -0,0 +1,129 @@ +# -*- encoding: utf-8 -*- +""" +description +""" + + +class BTreeNode: + def __init__(self, leaf=False): + self.keys = [] + self.children = [] + self.leaf = leaf + + def split(self, parent, key): + new_node = BTreeNode(self.leaf) + + mid = len(self.keys) // 2 + split_key = self.keys[mid] + + parent.add_key(split_key) + + new_node.children = self.children[mid + 1:] + self.children = self.children[:mid + 1] + + new_node.keys = self.keys[mid + 1:] + self.keys = self.keys[:mid] + + parent.children = parent.add_child(new_node) + + if key < split_key: + return self + else: + return new_node + + def add_key(self, key): + self.keys.append(key) + self.keys.sort() + + def add_child(self, new_node): + i = len(self.children) - 1 + while i >= 0 and self.children[i].keys[0] > new_node.keys[0]: + i -= 1 + return self.children[:i + 1] + [new_node] + self.children[i + 1:] + + def __str__(self): + return str(self.keys) + + +class BTree: + def __init__(self, t): + self.t = t + self.root = BTreeNode(leaf=True) + + def insert(self, key): + node = self.root + + if len(node.keys) == (2 * self.t) - 1: + new_root = BTreeNode() + new_root.children.append(self.root) + new_root.leaf = False + + node = node.split(new_root, key) + self.root = new_root + while not node.leaf: + i = 0 + while i < len(node.keys) and key > node.keys[i]: + i += 1 + + if len(node.children[i].keys) == (2 * self.t) - 1: + node = node.split(node, i) + if key > node.keys[i]: + i += 1 + + node = node.children[i] + + if key not in node.keys: + node.add_key(key) + + if len(node.keys) == (2 * self.t) - 1: + self.split(node) + + def split(self, node): + new_node = BTreeNode(node.leaf) + + mid = len(node.keys) // 2 + split_key = node.keys[mid] + + parent = node + parent.add_key(split_key) + + new_node.children = node.children[mid + 1:] + node.children = node.children[:mid + 1] + + new_node.keys = node.keys[mid + 1:] + node.keys = node.keys[:mid] + + parent.children = parent.add_child(new_node) + + def __str__(self): + return str(self.root) + + +# Example usage: +tree = BTree(t=2) + +tree.insert(1) +tree.insert(3) +tree.insert(7) +tree.insert(10) +tree.insert(11) +tree.insert(13) +tree.insert(14) +tree.insert(15) +tree.insert(18) +tree.insert(16) +tree.insert(19) +tree.insert(24) +tree.insert(25) +tree.insert(26) +tree.insert(21) +tree.insert(4) +tree.insert(5) +tree.insert(20) +tree.insert(22) +tree.insert(2) +tree.insert(17) +tree.insert(12) +tree.insert(6) + +print(tree) diff --git a/algorithms/ch04tree/redblack_tree.py b/algorithms/c04_tree/redblack_tree.py similarity index 99% rename from algorithms/ch04tree/redblack_tree.py rename to algorithms/c04_tree/redblack_tree.py index 1b36149..6bb155c 100644 --- a/algorithms/ch04tree/redblack_tree.py +++ b/algorithms/c04_tree/redblack_tree.py @@ -10,7 +10,7 @@ 5,对每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点。 一个有n个内部结点的红黑树的高度最多为2lg(n+1) """ -from algorithms.ch04tree.bisearch_tree import treeMinimum +from algorithms.c04_tree.bisearch_tree import treeMinimum class RBTree(): diff --git a/algorithms/ch05graph/__init__.py b/algorithms/c05_graph/__init__.py similarity index 100% rename from algorithms/ch05graph/__init__.py rename to algorithms/c05_graph/__init__.py diff --git a/algorithms/ch06string/__init__.py b/algorithms/c06_string/__init__.py similarity index 100% rename from algorithms/ch06string/__init__.py rename to algorithms/c06_string/__init__.py diff --git a/algorithms/ch07greedy/__init__.py b/algorithms/c07_greedy/__init__.py similarity index 100% rename from algorithms/ch07greedy/__init__.py rename to algorithms/c07_greedy/__init__.py diff --git a/algorithms/ch07greedy/m01_activity.py b/algorithms/c07_greedy/m01_activity.py similarity index 100% rename from algorithms/ch07greedy/m01_activity.py rename to algorithms/c07_greedy/m01_activity.py diff --git a/algorithms/ch08divide/__init__.py b/algorithms/c08_divide/__init__.py similarity index 100% rename from algorithms/ch08divide/__init__.py rename to algorithms/c08_divide/__init__.py diff --git a/algorithms/ch09backtrack/__init__.py b/algorithms/c09_backtrack/__init__.py similarity index 100% rename from algorithms/ch09backtrack/__init__.py rename to algorithms/c09_backtrack/__init__.py diff --git a/algorithms/ch10dynamic/__init__.py b/algorithms/c10_dynamic/__init__.py similarity index 100% rename from algorithms/ch10dynamic/__init__.py rename to algorithms/c10_dynamic/__init__.py diff --git a/algorithms/ch10dynamic/m01_cut_steel.py b/algorithms/c10_dynamic/m01_cut_steel.py similarity index 100% rename from algorithms/ch10dynamic/m01_cut_steel.py rename to algorithms/c10_dynamic/m01_cut_steel.py diff --git a/algorithms/ch10dynamic/m02_fibonacci.py b/algorithms/c10_dynamic/m02_fibonacci.py similarity index 100% rename from algorithms/ch10dynamic/m02_fibonacci.py rename to algorithms/c10_dynamic/m02_fibonacci.py diff --git a/algorithms/ch10dynamic/m03_matrix_chain.py b/algorithms/c10_dynamic/m03_matrix_chain.py similarity index 100% rename from algorithms/ch10dynamic/m03_matrix_chain.py rename to algorithms/c10_dynamic/m03_matrix_chain.py diff --git a/algorithms/ch10dynamic/m04_elevator.py b/algorithms/c10_dynamic/m04_elevator.py similarity index 100% rename from algorithms/ch10dynamic/m04_elevator.py rename to algorithms/c10_dynamic/m04_elevator.py diff --git a/algorithms/ch10dynamic/m05_subsequence.py b/algorithms/c10_dynamic/m05_subsequence.py similarity index 100% rename from algorithms/ch10dynamic/m05_subsequence.py rename to algorithms/c10_dynamic/m05_subsequence.py diff --git a/algorithms/ch10dynamic/m06_bag.py b/algorithms/c10_dynamic/m06_bag.py similarity index 100% rename from algorithms/ch10dynamic/m06_bag.py rename to algorithms/c10_dynamic/m06_bag.py diff --git a/algorithms/ch11advanced/__init__.py b/algorithms/c11_advanced/__init__.py similarity index 100% rename from algorithms/ch11advanced/__init__.py rename to algorithms/c11_advanced/__init__.py diff --git a/algorithms/leecode/p000/__init__.py b/algorithms/c12_ai/__init__.py similarity index 100% rename from algorithms/leecode/p000/__init__.py rename to algorithms/c12_ai/__init__.py diff --git a/algorithms/ch20sample/__init__.py b/algorithms/c13_sample/__init__.py similarity index 100% rename from algorithms/ch20sample/__init__.py rename to algorithms/c13_sample/__init__.py diff --git a/algorithms/ch20sample/m01_math.py b/algorithms/c13_sample/m01_math.py similarity index 100% rename from algorithms/ch20sample/m01_math.py rename to algorithms/c13_sample/m01_math.py diff --git a/algorithms/ch20sample/m02_triangle_str.py b/algorithms/c13_sample/m02_triangle_str.py similarity index 100% rename from algorithms/ch20sample/m02_triangle_str.py rename to algorithms/c13_sample/m02_triangle_str.py diff --git a/algorithms/ch20sample/m03_duplicate_words.py b/algorithms/c13_sample/m03_duplicate_words.py similarity index 100% rename from algorithms/ch20sample/m03_duplicate_words.py rename to algorithms/c13_sample/m03_duplicate_words.py diff --git a/algorithms/ch20sample/m04_binary_add.py b/algorithms/c13_sample/m04_binary_add.py similarity index 100% rename from algorithms/ch20sample/m04_binary_add.py rename to algorithms/c13_sample/m04_binary_add.py diff --git a/algorithms/ch20sample/m05_nine_number.py b/algorithms/c13_sample/m05_nine_number.py similarity index 100% rename from algorithms/ch20sample/m05_nine_number.py rename to algorithms/c13_sample/m05_nine_number.py diff --git a/algorithms/ch20sample/m06_hornerpoly.py b/algorithms/c13_sample/m06_hornerpoly.py similarity index 100% rename from algorithms/ch20sample/m06_hornerpoly.py rename to algorithms/c13_sample/m06_hornerpoly.py diff --git a/algorithms/ch20sample/m07_max_subarr.py b/algorithms/c13_sample/m07_max_subarr.py similarity index 100% rename from algorithms/ch20sample/m07_max_subarr.py rename to algorithms/c13_sample/m07_max_subarr.py diff --git a/algorithms/ch20sample/m08_max_subarr2.py b/algorithms/c13_sample/m08_max_subarr2.py similarity index 100% rename from algorithms/ch20sample/m08_max_subarr2.py rename to algorithms/c13_sample/m08_max_subarr2.py diff --git a/algorithms/ch20sample/m09_max_subarr3.py b/algorithms/c13_sample/m09_max_subarr3.py similarity index 100% rename from algorithms/ch20sample/m09_max_subarr3.py rename to algorithms/c13_sample/m09_max_subarr3.py diff --git a/algorithms/ch20sample/m10_code_funny.py b/algorithms/c13_sample/m10_code_funny.py similarity index 100% rename from algorithms/ch20sample/m10_code_funny.py rename to algorithms/c13_sample/m10_code_funny.py diff --git a/algorithms/ch20sample/m11_rand_permute.py b/algorithms/c13_sample/m11_rand_permute.py similarity index 100% rename from algorithms/ch20sample/m11_rand_permute.py rename to algorithms/c13_sample/m11_rand_permute.py diff --git a/algorithms/ch20sample/m12_right_shift.py b/algorithms/c13_sample/m12_right_shift.py similarity index 100% rename from algorithms/ch20sample/m12_right_shift.py rename to algorithms/c13_sample/m12_right_shift.py diff --git a/algorithms/ch20sample/m13_sin_cpu.py b/algorithms/c13_sample/m13_sin_cpu.py similarity index 100% rename from algorithms/ch20sample/m13_sin_cpu.py rename to algorithms/c13_sample/m13_sin_cpu.py diff --git a/algorithms/ch20sample/m14_bestsinger.py b/algorithms/c13_sample/m14_bestsinger.py similarity index 100% rename from algorithms/ch20sample/m14_bestsinger.py rename to algorithms/c13_sample/m14_bestsinger.py diff --git a/algorithms/ch20sample/m15_bracket_match.py b/algorithms/c13_sample/m15_bracket_match.py similarity index 100% rename from algorithms/ch20sample/m15_bracket_match.py rename to algorithms/c13_sample/m15_bracket_match.py diff --git a/algorithms/ch20sample/m16_circle_queue.py b/algorithms/c13_sample/m16_circle_queue.py similarity index 100% rename from algorithms/ch20sample/m16_circle_queue.py rename to algorithms/c13_sample/m16_circle_queue.py diff --git a/algorithms/leecode/__init__.py b/algorithms/c14_leetcode/__init__.py similarity index 100% rename from algorithms/leecode/__init__.py rename to algorithms/c14_leetcode/__init__.py diff --git a/algorithms/leecode/p100/__init__.py b/algorithms/c14_leetcode/p000/__init__.py similarity index 100% rename from algorithms/leecode/p100/__init__.py rename to algorithms/c14_leetcode/p000/__init__.py diff --git a/algorithms/leecode/p000/a19_remove_nth_node_from_end_of_list.py b/algorithms/c14_leetcode/p000/a19_remove_nth_node_from_end_of_list.py similarity index 100% rename from algorithms/leecode/p000/a19_remove_nth_node_from_end_of_list.py rename to algorithms/c14_leetcode/p000/a19_remove_nth_node_from_end_of_list.py diff --git a/algorithms/leecode/p000/a20_valid_parentheses.py b/algorithms/c14_leetcode/p000/a20_valid_parentheses.py similarity index 95% rename from algorithms/leecode/p000/a20_valid_parentheses.py rename to algorithms/c14_leetcode/p000/a20_valid_parentheses.py index 2860296..46ef4cc 100644 --- a/algorithms/leecode/p000/a20_valid_parentheses.py +++ b/algorithms/c14_leetcode/p000/a20_valid_parentheses.py @@ -23,7 +23,7 @@ 算法思路:栈的最简单的应用。左括号入栈,右括号出栈+对比匹配。不匹配则False,最后栈空则True """ -from algorithms.ch01linear.stack.stack_linked_list import LinkedStack +from algorithms.c01_linear.stack.stack_linked_list import LinkedStack class Solution: diff --git a/algorithms/leecode/p000/a21_merge_two_sorted_lists.py b/algorithms/c14_leetcode/p000/a21_merge_two_sorted_lists.py similarity index 100% rename from algorithms/leecode/p000/a21_merge_two_sorted_lists.py rename to algorithms/c14_leetcode/p000/a21_merge_two_sorted_lists.py diff --git a/algorithms/leecode/p000/a70_climbing_stairs.py b/algorithms/c14_leetcode/p000/a70_climbing_stairs.py similarity index 100% rename from algorithms/leecode/p000/a70_climbing_stairs.py rename to algorithms/c14_leetcode/p000/a70_climbing_stairs.py diff --git a/algorithms/leecode/p1000/__init__.py b/algorithms/c14_leetcode/p100/__init__.py similarity index 100% rename from algorithms/leecode/p1000/__init__.py rename to algorithms/c14_leetcode/p100/__init__.py diff --git a/algorithms/leecode/p100/a141_linked_list_cycle.py b/algorithms/c14_leetcode/p100/a141_linked_list_cycle.py similarity index 100% rename from algorithms/leecode/p100/a141_linked_list_cycle.py rename to algorithms/c14_leetcode/p100/a141_linked_list_cycle.py diff --git a/algorithms/leecode/p100/a155_min_stack.py b/algorithms/c14_leetcode/p100/a155_min_stack.py similarity index 97% rename from algorithms/leecode/p100/a155_min_stack.py rename to algorithms/c14_leetcode/p100/a155_min_stack.py index a58027a..d08c4a2 100644 --- a/algorithms/leecode/p100/a155_min_stack.py +++ b/algorithms/c14_leetcode/p100/a155_min_stack.py @@ -15,7 +15,7 @@ 通过空间换时间的方法。将每次入栈的节点包装成一个对象,存储两个信息,一个是节点值,一个是当前栈的最小值。 这样获取栈顶元素就同时能获取到这两个值了。 """ -from algorithms.ch01linear import Node +from algorithms.c01_linear import Node class MinStack: diff --git a/algorithms/leecode/p1100/__init__.py b/algorithms/c14_leetcode/p1000/__init__.py similarity index 100% rename from algorithms/leecode/p1100/__init__.py rename to algorithms/c14_leetcode/p1000/__init__.py diff --git a/algorithms/leecode/p1200/__init__.py b/algorithms/c14_leetcode/p1100/__init__.py similarity index 100% rename from algorithms/leecode/p1200/__init__.py rename to algorithms/c14_leetcode/p1100/__init__.py diff --git a/algorithms/leecode/p1300/__init__.py b/algorithms/c14_leetcode/p1200/__init__.py similarity index 100% rename from algorithms/leecode/p1300/__init__.py rename to algorithms/c14_leetcode/p1200/__init__.py diff --git a/algorithms/leecode/p1400/__init__.py b/algorithms/c14_leetcode/p1300/__init__.py similarity index 100% rename from algorithms/leecode/p1400/__init__.py rename to algorithms/c14_leetcode/p1300/__init__.py diff --git a/algorithms/leecode/p1500/__init__.py b/algorithms/c14_leetcode/p1400/__init__.py similarity index 100% rename from algorithms/leecode/p1500/__init__.py rename to algorithms/c14_leetcode/p1400/__init__.py diff --git a/algorithms/leecode/p1600/__init__.py b/algorithms/c14_leetcode/p1500/__init__.py similarity index 100% rename from algorithms/leecode/p1600/__init__.py rename to algorithms/c14_leetcode/p1500/__init__.py diff --git a/algorithms/leecode/p1700/__init__.py b/algorithms/c14_leetcode/p1600/__init__.py similarity index 100% rename from algorithms/leecode/p1700/__init__.py rename to algorithms/c14_leetcode/p1600/__init__.py diff --git a/algorithms/leecode/p1800/__init__.py b/algorithms/c14_leetcode/p1700/__init__.py similarity index 100% rename from algorithms/leecode/p1800/__init__.py rename to algorithms/c14_leetcode/p1700/__init__.py diff --git a/algorithms/leecode/p1900/__init__.py b/algorithms/c14_leetcode/p1800/__init__.py similarity index 100% rename from algorithms/leecode/p1900/__init__.py rename to algorithms/c14_leetcode/p1800/__init__.py diff --git a/algorithms/leecode/p200/__init__.py b/algorithms/c14_leetcode/p1900/__init__.py similarity index 100% rename from algorithms/leecode/p200/__init__.py rename to algorithms/c14_leetcode/p1900/__init__.py diff --git a/algorithms/leecode/p2000/__init__.py b/algorithms/c14_leetcode/p200/__init__.py similarity index 100% rename from algorithms/leecode/p2000/__init__.py rename to algorithms/c14_leetcode/p200/__init__.py diff --git a/algorithms/leecode/p200/a206_reverse_linked_list.py b/algorithms/c14_leetcode/p200/a206_reverse_linked_list.py similarity index 100% rename from algorithms/leecode/p200/a206_reverse_linked_list.py rename to algorithms/c14_leetcode/p200/a206_reverse_linked_list.py diff --git a/algorithms/leecode/p200/a215_kth_largest_element_in_an_array.py b/algorithms/c14_leetcode/p200/a215_kth_largest_element_in_an_array.py similarity index 100% rename from algorithms/leecode/p200/a215_kth_largest_element_in_an_array.py rename to algorithms/c14_leetcode/p200/a215_kth_largest_element_in_an_array.py diff --git a/algorithms/leecode/p200/a224_basic_calculator.py b/algorithms/c14_leetcode/p200/a224_basic_calculator.py similarity index 100% rename from algorithms/leecode/p200/a224_basic_calculator.py rename to algorithms/c14_leetcode/p200/a224_basic_calculator.py diff --git a/algorithms/leecode/p200/a232_implement_queue_using_stacks.py b/algorithms/c14_leetcode/p200/a232_implement_queue_using_stacks.py similarity index 100% rename from algorithms/leecode/p200/a232_implement_queue_using_stacks.py rename to algorithms/c14_leetcode/p200/a232_implement_queue_using_stacks.py diff --git a/algorithms/leecode/p2100/__init__.py b/algorithms/c14_leetcode/p2000/__init__.py similarity index 100% rename from algorithms/leecode/p2100/__init__.py rename to algorithms/c14_leetcode/p2000/__init__.py diff --git a/algorithms/leecode/p2200/__init__.py b/algorithms/c14_leetcode/p2100/__init__.py similarity index 100% rename from algorithms/leecode/p2200/__init__.py rename to algorithms/c14_leetcode/p2100/__init__.py diff --git a/algorithms/leecode/p300/__init__.py b/algorithms/c14_leetcode/p2200/__init__.py similarity index 100% rename from algorithms/leecode/p300/__init__.py rename to algorithms/c14_leetcode/p2200/__init__.py diff --git a/algorithms/leecode/p400/__init__.py b/algorithms/c14_leetcode/p300/__init__.py similarity index 100% rename from algorithms/leecode/p400/__init__.py rename to algorithms/c14_leetcode/p300/__init__.py diff --git a/algorithms/leecode/p300/a392_is_subsequence.py b/algorithms/c14_leetcode/p300/a392_is_subsequence.py similarity index 100% rename from algorithms/leecode/p300/a392_is_subsequence.py rename to algorithms/c14_leetcode/p300/a392_is_subsequence.py diff --git a/algorithms/leecode/p500/__init__.py b/algorithms/c14_leetcode/p400/__init__.py similarity index 100% rename from algorithms/leecode/p500/__init__.py rename to algorithms/c14_leetcode/p400/__init__.py diff --git a/algorithms/leecode/p400/a496_next_greater_element.py b/algorithms/c14_leetcode/p400/a496_next_greater_element.py similarity index 100% rename from algorithms/leecode/p400/a496_next_greater_element.py rename to algorithms/c14_leetcode/p400/a496_next_greater_element.py diff --git a/algorithms/leecode/p600/__init__.py b/algorithms/c14_leetcode/p500/__init__.py similarity index 100% rename from algorithms/leecode/p600/__init__.py rename to algorithms/c14_leetcode/p500/__init__.py diff --git a/algorithms/leecode/p700/__init__.py b/algorithms/c14_leetcode/p600/__init__.py similarity index 100% rename from algorithms/leecode/p700/__init__.py rename to algorithms/c14_leetcode/p600/__init__.py diff --git a/algorithms/leecode/p600/a682_baseball_game.py b/algorithms/c14_leetcode/p600/a682_baseball_game.py similarity index 100% rename from algorithms/leecode/p600/a682_baseball_game.py rename to algorithms/c14_leetcode/p600/a682_baseball_game.py diff --git a/algorithms/leecode/p800/__init__.py b/algorithms/c14_leetcode/p700/__init__.py similarity index 100% rename from algorithms/leecode/p800/__init__.py rename to algorithms/c14_leetcode/p700/__init__.py diff --git a/algorithms/leecode/p900/__init__.py b/algorithms/c14_leetcode/p800/__init__.py similarity index 100% rename from algorithms/leecode/p900/__init__.py rename to algorithms/c14_leetcode/p800/__init__.py diff --git a/algorithms/leecode/p800/a844_backspace_string_compare.py b/algorithms/c14_leetcode/p800/a844_backspace_string_compare.py similarity index 100% rename from algorithms/leecode/p800/a844_backspace_string_compare.py rename to algorithms/c14_leetcode/p800/a844_backspace_string_compare.py diff --git a/algorithms/leecode/p800/a876_middle_of_the_linked_list.py b/algorithms/c14_leetcode/p800/a876_middle_of_the_linked_list.py similarity index 100% rename from algorithms/leecode/p800/a876_middle_of_the_linked_list.py rename to algorithms/c14_leetcode/p800/a876_middle_of_the_linked_list.py diff --git a/algorithms/c14_leetcode/p900/__init__.py b/algorithms/c14_leetcode/p900/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/c14_leetcode/p900/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" From bc3eff166464e1f28f9a5ced356f13daa005c35f Mon Sep 17 00:00:00 2001 From: xiongneng Date: Sun, 6 Aug 2023 05:23:06 +0800 Subject: [PATCH 41/54] update --- algorithms/c12_ai/basic/__init__.py | 9 +++++ algorithms/c12_ai/basic/a01_maze_bfs.py | 48 +++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 algorithms/c12_ai/basic/__init__.py create mode 100644 algorithms/c12_ai/basic/a01_maze_bfs.py diff --git a/algorithms/c12_ai/basic/__init__.py b/algorithms/c12_ai/basic/__init__.py new file mode 100644 index 0000000..001044c --- /dev/null +++ b/algorithms/c12_ai/basic/__init__.py @@ -0,0 +1,9 @@ +# -*- encoding: utf-8 -*- +""" +AI基础算法集合 +""" + + + + + diff --git a/algorithms/c12_ai/basic/a01_maze_bfs.py b/algorithms/c12_ai/basic/a01_maze_bfs.py new file mode 100644 index 0000000..a5a2b83 --- /dev/null +++ b/algorithms/c12_ai/basic/a01_maze_bfs.py @@ -0,0 +1,48 @@ +# -*- encoding: utf-8 -*- +""" +迷宫搜索:广度优先算法 +""" + +from algorithms.c01_linear.queue.linked_queue import LinkedQueue +from algorithms.c01_linear.stack.stack_linked_list import LinkedStack + + +class Point: + def __init__(self, row, column): + self.row = row + self.column = column + self.parent = None + + def __eq__(self, other): + return self.row == other.row and self.column == other.column + + def __str__(self): + return f'({self.row},{self.column})' + + def path(self): + point = self + stack = LinkedStack() + while point is not None: + stack.push(self) + point = point.parent + for point in stack: + print(point, sep=',') + + +def run_bfs(maze, current_point, visited_points): + q = LinkedQueue() + q.enqueue(current_point) + visited_points.add(current_point) + while not q.is_empty(): + current_point = q.dequeue() + # 当前节点的东南西北节点作为邻居节点 + neighbors = [] + for neighbor in neighbors: + if neighbor not in visited_points: + neighbor.parent = current_point + q.enqueue(neighbor) + visited_points.add(neighbor) + if neighbor == maze.goal: + neighbor.path() + return + print('find no path') From b4f35b6cbf05dc7ac1ef2ec36459436351e3084b Mon Sep 17 00:00:00 2001 From: xiongneng Date: Sun, 6 Aug 2023 05:25:01 +0800 Subject: [PATCH 42/54] update --- algorithms/c12_ai/basic/a01_maze_bfs.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/algorithms/c12_ai/basic/a01_maze_bfs.py b/algorithms/c12_ai/basic/a01_maze_bfs.py index a5a2b83..515c83e 100644 --- a/algorithms/c12_ai/basic/a01_maze_bfs.py +++ b/algorithms/c12_ai/basic/a01_maze_bfs.py @@ -19,14 +19,15 @@ def __eq__(self, other): def __str__(self): return f'({self.row},{self.column})' - def path(self): - point = self - stack = LinkedStack() - while point is not None: - stack.push(self) - point = point.parent - for point in stack: - print(point, sep=',') + +def print_path(point): + """打印路径""" + stack = LinkedStack() + while point is not None: + stack.push(stack) + point = point.parent + for point in stack: + print(point, sep=',') def run_bfs(maze, current_point, visited_points): @@ -43,6 +44,6 @@ def run_bfs(maze, current_point, visited_points): q.enqueue(neighbor) visited_points.add(neighbor) if neighbor == maze.goal: - neighbor.path() + print_path(neighbor) return print('find no path') From 322cb388295e7085a3772b2dcd7b83c34165c98e Mon Sep 17 00:00:00 2001 From: xiongneng Date: Sun, 6 Aug 2023 18:09:05 +0800 Subject: [PATCH 43/54] update --- algorithms/c12_ai/basic/a01_maze_bfs.py | 6 +-- algorithms/c12_ai/basic/a02_maze_dfs.py | 51 +++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 algorithms/c12_ai/basic/a02_maze_dfs.py diff --git a/algorithms/c12_ai/basic/a01_maze_bfs.py b/algorithms/c12_ai/basic/a01_maze_bfs.py index 515c83e..3a0e047 100644 --- a/algorithms/c12_ai/basic/a01_maze_bfs.py +++ b/algorithms/c12_ai/basic/a01_maze_bfs.py @@ -1,6 +1,6 @@ # -*- encoding: utf-8 -*- """ -迷宫搜索:广度优先算法 +迷宫搜索:广度优先算法,通过队列来实现 """ from algorithms.c01_linear.queue.linked_queue import LinkedQueue @@ -40,10 +40,10 @@ def run_bfs(maze, current_point, visited_points): neighbors = [] for neighbor in neighbors: if neighbor not in visited_points: + visited_points.add(neighbor) neighbor.parent = current_point q.enqueue(neighbor) - visited_points.add(neighbor) if neighbor == maze.goal: print_path(neighbor) - return + return neighbor print('find no path') diff --git a/algorithms/c12_ai/basic/a02_maze_dfs.py b/algorithms/c12_ai/basic/a02_maze_dfs.py new file mode 100644 index 0000000..a27c8ec --- /dev/null +++ b/algorithms/c12_ai/basic/a02_maze_dfs.py @@ -0,0 +1,51 @@ +# -*- encoding: utf-8 -*- +""" +迷宫搜索:深度优先算法,通过栈来实现 +""" + +from algorithms.c01_linear.stack.stack_linked_list import LinkedStack + + +class Point: + def __init__(self, row, column): + self.row = row + self.column = column + self.parent = None + + def __eq__(self, other): + return self.row == other.row and self.column == other.column + + def __str__(self): + return f'({self.row},{self.column})' + + +def print_path(point): + """打印路径""" + stack = LinkedStack() + while point is not None: + stack.push(stack) + point = point.parent + for point in stack: + print(point, sep=',') + + +def run_dfs(maze, root_point, visited_points): + s = LinkedStack() + s.push(root_point) + while not s.is_empty(): + current_point = s.pop() + if current_point not in visited_points: + visited_points.add(current_point) + if current_point == maze.goal: + print_path(current_point) + return current_point + # 构造当前节点的东南西北节点作为邻居节点 + neighbors = [] + for neighbor in neighbors: + neighbor.parent = current_point + s.push(neighbor) + print('find no path') + + + + From 21ef4375e0e65a6acc03383cf9b6233b152da263 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Thu, 5 Oct 2023 08:38:45 +0800 Subject: [PATCH 44/54] update --- algorithms/c01_linear/linkedlist/__init__.py | 6 ++ .../c14_leetcode/p000/a86_partition_list.py | 64 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 algorithms/c14_leetcode/p000/a86_partition_list.py diff --git a/algorithms/c01_linear/linkedlist/__init__.py b/algorithms/c01_linear/linkedlist/__init__.py index 902a5f2..894ec9e 100644 --- a/algorithms/c01_linear/linkedlist/__init__.py +++ b/algorithms/c01_linear/linkedlist/__init__.py @@ -10,3 +10,9 @@ * 删除链表倒数第 n 个结点 * 求链表的中间结点 """ + + +class ListNode: + def __init__(self, val=0, next=None): + self.val = val + self.next = next diff --git a/algorithms/c14_leetcode/p000/a86_partition_list.py b/algorithms/c14_leetcode/p000/a86_partition_list.py new file mode 100644 index 0000000..a34e1db --- /dev/null +++ b/algorithms/c14_leetcode/p000/a86_partition_list.py @@ -0,0 +1,64 @@ +# -*- encoding: utf-8 -*- +""" +给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 + +你应当 保留 两个分区中每个节点的初始相对位置。 + +输入:head = [1,4,3,2,5,2], x = 3 +输出:[1,2,2,4,3,5] + +输入:head = [2,1], x = 2 +输出:[1,2] +""" +from typing import Optional + + +# Definition for singly-linked list. +class ListNode: + def __init__(self, val=0, next=None): + self.val = val + self.next = next + + +class Solution: + def partition(self, head: Optional[ListNode], x: int) -> Optional[ListNode]: + p1 = None # 小于x的链表 + p1_head = None + p2 = None # 大于等于x的链表 + p2_head = None + p = head # 循环原链表 + while p: + if p.val < x: + if not p1: + p1 = p + p1_head = p + else: + p1.next = p + p1 = p1.next + else: + if not p2: + p2 = p + p2_head = p + else: + p2.next = p + p2 = p2.next + temp = p.next + p.next = None + p = temp + if p1: + p1.next = p2_head + return p1_head if p1_head else p2_head + + +if __name__ == '__main__': + # [1,4,3,2,5,2] + head = ListNode(2) + head = ListNode(5, head) + head = ListNode(2, head) + head = ListNode(3, head) + head = ListNode(4, head) + head = ListNode(1, head) + head = Solution().partition(head, 3) + while head: + print(head.val, end=' ') + head = head.next From 542f74dac647b5575f386a090a6ce43bd79d219f Mon Sep 17 00:00:00 2001 From: xiongneng Date: Thu, 5 Oct 2023 23:27:41 +0800 Subject: [PATCH 45/54] update --- .../p000/a23_merge_k_sorted_lists.py | 58 +++++++++++++++++++ .../c14_leetcode/p000/a86_partition_list.py | 7 +-- .../p100/a142_linked_list_cycle_ii.py | 29 ++++++++++ 3 files changed, 88 insertions(+), 6 deletions(-) create mode 100644 algorithms/c14_leetcode/p000/a23_merge_k_sorted_lists.py create mode 100644 algorithms/c14_leetcode/p100/a142_linked_list_cycle_ii.py diff --git a/algorithms/c14_leetcode/p000/a23_merge_k_sorted_lists.py b/algorithms/c14_leetcode/p000/a23_merge_k_sorted_lists.py new file mode 100644 index 0000000..f13d795 --- /dev/null +++ b/algorithms/c14_leetcode/p000/a23_merge_k_sorted_lists.py @@ -0,0 +1,58 @@ +# -*- encoding: utf-8 -*- +""" +23. 合并 K 个升序链表 + +给你一个链表数组,每个链表都已经按升序排列。 +请你将所有链表合并到一个升序链表中,返回合并后的链表。 + +输入:lists = [[1,4,5],[1,3,4],[2,6]] +输出:[1,1,2,3,4,4,5,6] +""" +from typing import List, Optional + +from algorithms.c01_linear.linkedlist import ListNode +from queue import PriorityQueue + + +class Solution: + def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]: + if not lists: + return None + p = None + p_head = None + pq = PriorityQueue() + for list_idx, each in enumerate(lists): + if each: + pq.put((each.val, list_idx, each)) + while not pq.empty(): + node = pq.get() + if p: + p.next = node[2] + p = p.next + else: + p = node[2] + p_head = node[2] + if node[2].next: + pq.put((node[2].next.val, node[1], node[2].next)) + return p_head + + +if __name__ == '__main__': + """ + 输入:lists = [[1,4,5],[1,3,4],[2,6]] + 输出:[1,1,2,3,4,4,5,6] + """ + node1 = ListNode(5) + node1 = ListNode(4, node1) + node1 = ListNode(1, node1) + node2 = ListNode(4) + node2 = ListNode(3, node2) + node2 = ListNode(1, node2) + node3 = ListNode(6) + node3 = ListNode(2, node3) + lists = [node1, node2, node3] + head = Solution().mergeKLists(lists) + while head: + print(head.val, end=' ') + head = head.next + ... diff --git a/algorithms/c14_leetcode/p000/a86_partition_list.py b/algorithms/c14_leetcode/p000/a86_partition_list.py index a34e1db..0db7a94 100644 --- a/algorithms/c14_leetcode/p000/a86_partition_list.py +++ b/algorithms/c14_leetcode/p000/a86_partition_list.py @@ -12,12 +12,7 @@ """ from typing import Optional - -# Definition for singly-linked list. -class ListNode: - def __init__(self, val=0, next=None): - self.val = val - self.next = next +from algorithms.c01_linear.linkedlist import ListNode class Solution: diff --git a/algorithms/c14_leetcode/p100/a142_linked_list_cycle_ii.py b/algorithms/c14_leetcode/p100/a142_linked_list_cycle_ii.py new file mode 100644 index 0000000..1dd23db --- /dev/null +++ b/algorithms/c14_leetcode/p100/a142_linked_list_cycle_ii.py @@ -0,0 +1,29 @@ +# -*- encoding: utf-8 -*- +""" +142. 环形链表 II +给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 + +如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环, +评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。 +注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。 +""" +from typing import Optional + +from algorithms.c01_linear.linkedlist import ListNode + + +class Solution: + def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]: + slow, fast = head, head + while fast and fast.next: + slow = slow.next + fast = fast.next.next + if fast == slow: + break + if not fast or not fast.next: + return None + slow = head + while slow != fast: + fast = fast.next + slow = slow.next + return slow From 9f4bb92b7141bae73613e615a5cc3f4d1752829c Mon Sep 17 00:00:00 2001 From: xiongneng Date: Fri, 6 Oct 2023 00:12:35 +0800 Subject: [PATCH 46/54] update --- .../p100/a142_linked_list_cycle_ii.py | 7 ++++ .../a160_intersection_of_two_linked_lists.py | 41 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 algorithms/c14_leetcode/p100/a160_intersection_of_two_linked_lists.py diff --git a/algorithms/c14_leetcode/p100/a142_linked_list_cycle_ii.py b/algorithms/c14_leetcode/p100/a142_linked_list_cycle_ii.py index 1dd23db..65151de 100644 --- a/algorithms/c14_leetcode/p100/a142_linked_list_cycle_ii.py +++ b/algorithms/c14_leetcode/p100/a142_linked_list_cycle_ii.py @@ -6,6 +6,13 @@ 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环, 评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。 注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。 + +解题思路: +判断链表是否包含环属于经典问题了,解决方案也是用快慢指针: +每当慢指针 slow 前进一步,快指针 fast 就前进两步。 +如果 fast 最终遇到空指针,说明链表中没有环;如果 fast 最终和 slow 相遇,那肯定是 fast 超过了 slow 一圈, +说明链表中含有环。 +当快慢指针相遇时,让其中任一个指针指向头节点,然后让它俩以相同速度前进,再次相遇时所在的节点位置就是环开始的位置。 """ from typing import Optional diff --git a/algorithms/c14_leetcode/p100/a160_intersection_of_two_linked_lists.py b/algorithms/c14_leetcode/p100/a160_intersection_of_two_linked_lists.py new file mode 100644 index 0000000..04188e5 --- /dev/null +++ b/algorithms/c14_leetcode/p100/a160_intersection_of_two_linked_lists.py @@ -0,0 +1,41 @@ +# -*- encoding: utf-8 -*- +""" +160. 相交链表 +给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。 +输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3 +输出:Intersected at '8' +输入:intersectVal = 2, listA = [1,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1 +输出:Intersected at '2' + +解题思路: +我们可以让 p1 遍历完链表 A 之后开始遍历链表 B,让 p2 遍历完链表 B 之后开始遍历链表 A, +这样相当于「逻辑上」两条链表接在了一起。 +如果这样进行拼接,就可以让 p1 和 p2 同时进入公共部分,也就是同时到达相交节点 c1 +""" +from typing import Optional + +from algorithms.c01_linear.linkedlist import ListNode + + +class Solution: + def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> Optional[ListNode]: + p1 = headA + p1_change = False + p2 = headB + p2_change = False + while p1 != p2: + if p1.next: + p1 = p1.next + elif not p1_change: + p1 = headB + p1_change = True + else: + p1 = None + if p2.next: + p2 = p2.next + elif not p2_change: + p2 = headA + p2_change = True + else: + p2 = None + return p1 From 1d28c17cd4c97be789f22463cee0e2cffe09e0fd Mon Sep 17 00:00:00 2001 From: xiongneng Date: Fri, 6 Oct 2023 00:19:37 +0800 Subject: [PATCH 47/54] update --- .../a160_intersection_of_two_linked_lists.py | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/algorithms/c14_leetcode/p100/a160_intersection_of_two_linked_lists.py b/algorithms/c14_leetcode/p100/a160_intersection_of_two_linked_lists.py index 04188e5..344c084 100644 --- a/algorithms/c14_leetcode/p100/a160_intersection_of_two_linked_lists.py +++ b/algorithms/c14_leetcode/p100/a160_intersection_of_two_linked_lists.py @@ -20,22 +20,8 @@ class Solution: def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> Optional[ListNode]: p1 = headA - p1_change = False p2 = headB - p2_change = False while p1 != p2: - if p1.next: - p1 = p1.next - elif not p1_change: - p1 = headB - p1_change = True - else: - p1 = None - if p2.next: - p2 = p2.next - elif not p2_change: - p2 = headA - p2_change = True - else: - p2 = None + p1 = p1.next if p1 else headB + p2 = p2.next if p2 else headA return p1 From b1c9c49b05d70b3edc53adf7157ea7fb811487f5 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Fri, 6 Oct 2023 22:21:29 +0800 Subject: [PATCH 48/54] update --- .../c14_leetcode/p200/a283_move_zeroes.py | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 algorithms/c14_leetcode/p200/a283_move_zeroes.py diff --git a/algorithms/c14_leetcode/p200/a283_move_zeroes.py b/algorithms/c14_leetcode/p200/a283_move_zeroes.py new file mode 100644 index 0000000..cb2cda1 --- /dev/null +++ b/algorithms/c14_leetcode/p200/a283_move_zeroes.py @@ -0,0 +1,30 @@ +# -*- encoding: utf-8 -*- +""" +283. 移动零 +给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 +请注意 ,必须在不复制数组的情况下原地对数组进行操作。 +输入: nums = [0,1,0,3,12] +输出: [1,3,12,0,0] +输入: nums = [0] +输出: [0] + +解题思路: +快慢指针,慢指针保留所有非0值,快指针遍历完数组。最后将慢指针后面的值全部赋值为0即可 +""" +from typing import List, NoReturn + + +class Solution: + def moveZeroes(self, nums: List[int]) -> NoReturn: + """ + Do not return anything, modify nums in-place instead. + """ + slow, fast = 0, 0 + while fast < len(nums): + if nums[fast] != 0: + nums[slow] = nums[fast] + slow += 1 + fast += 1 + while slow < len(nums): + nums[slow] = 0 + slow += 1 From 9889fa68c4fdb3740d61607c39739000d5317ad5 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Fri, 6 Oct 2023 22:36:53 +0800 Subject: [PATCH 49/54] update --- .../a167_two_sum_ii_input_array_is_sorted.py | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 algorithms/c14_leetcode/p100/a167_two_sum_ii_input_array_is_sorted.py diff --git a/algorithms/c14_leetcode/p100/a167_two_sum_ii_input_array_is_sorted.py b/algorithms/c14_leetcode/p100/a167_two_sum_ii_input_array_is_sorted.py new file mode 100644 index 0000000..fdf1de4 --- /dev/null +++ b/algorithms/c14_leetcode/p100/a167_two_sum_ii_input_array_is_sorted.py @@ -0,0 +1,30 @@ +# -*- encoding: utf-8 -*- +""" +167. 两数之和 II - 输入有序数组 +给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列 , +请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] , +则 1 <= index1 < index2 <= numbers.length 。 +以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1 和 index2。 +你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。 +你所设计的解决方案必须只使用常量级的额外空间。 + +示例 1: +输入:numbers = [2,7,11,15], target = 9 +输出:[1,2] +解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。 +""" +from typing import List, Optional + + +class Solution: + def twoSum(self, numbers: List[int], target: int) -> Optional[List[int]]: + left, right = 0, len(numbers) - 1 + while left < right: + sum_ = numbers[left] + numbers[right] + if sum_ == target: + return [left + 1, right + 1] + elif sum_ < target: + left += 1 + else: + right -= 1 + return [-1, -1] From b19ef195d14dc893464dcd27f6c191a989ff2bba Mon Sep 17 00:00:00 2001 From: xiongneng Date: Tue, 10 Oct 2023 20:40:27 +0800 Subject: [PATCH 50/54] update --- .../p000/a05_longest_palindromic_substring.py | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 algorithms/c14_leetcode/p000/a05_longest_palindromic_substring.py diff --git a/algorithms/c14_leetcode/p000/a05_longest_palindromic_substring.py b/algorithms/c14_leetcode/p000/a05_longest_palindromic_substring.py new file mode 100644 index 0000000..4a41354 --- /dev/null +++ b/algorithms/c14_leetcode/p000/a05_longest_palindromic_substring.py @@ -0,0 +1,39 @@ +# -*- encoding: utf-8 -*- +""" +5. 最长回文子串 +给你一个字符串 s,找到 s 中最长的回文子串。 +如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。 + +示例 1: +输入:s = "babad" +输出:"bab" +解释:"aba" 同样是符合题意的答案。 +""" + + +class Solution: + def longestPalindrome(self, s: str) -> str: + res = '' + for i in range(len(s)): + s1 = self._max_palindrome(s, i, i) + s2 = self._max_palindrome(s, i, i + 1) + res = res if len(res) > len(s1) else s1 + res = res if len(res) > len(s2) else s2 + return res + + def _max_palindrome(self, s: str, l: int, r: int) -> str: + step = 0 + max_index = len(s) - 1 + while True: + left = l - step + right = r + step + if left < 0 or right > max_index: + break + if s[left] != s[right]: + break + step += 1 + return s[left + 1:right] + + +if __name__ == '__main__': + print(Solution().longestPalindrome("babad")) From 9fb84def1b02c0d1e92f046bf16c04987ec0e4e9 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Sat, 11 Nov 2023 21:13:55 +0800 Subject: [PATCH 51/54] update --- algorithms/hello_algo/__init__.py | 4 + algorithms/hello_algo/build.py | 20 ++ .../iteration.py | 65 ++++++ .../recursion.py | 69 ++++++ .../space_complexity.py | 90 ++++++++ .../time_complexity.py | 151 +++++++++++++ .../worst_best_time_complexity.py | 36 ++++ .../chapter04_array_and_linkedlist/array.py | 99 +++++++++ .../linked_list.py | 84 ++++++++ .../chapter04_array_and_linkedlist/list.py | 59 +++++ .../chapter04_array_and_linkedlist/my_list.py | 118 ++++++++++ .../chapter05_stack_and_queue/array_deque.py | 129 +++++++++++ .../chapter05_stack_and_queue/array_queue.py | 98 +++++++++ .../chapter05_stack_and_queue/array_stack.py | 72 +++++++ .../chapter05_stack_and_queue/deque.py | 42 ++++ .../linkedlist_deque.py | 151 +++++++++++++ .../linkedlist_queue.py | 97 +++++++++ .../linkedlist_stack.py | 89 ++++++++ .../chapter05_stack_and_queue/queue.py | 39 ++++ .../chapter05_stack_and_queue/stack.py | 36 ++++ .../chapter06_hashing/array_hash_map.py | 117 ++++++++++ .../chapter06_hashing/built_in_hash.py | 37 ++++ .../hello_algo/chapter06_hashing/hash_map.py | 50 +++++ .../chapter06_hashing/hash_map_chaining.py | 118 ++++++++++ .../hash_map_open_addressing.py | 138 ++++++++++++ .../chapter06_hashing/simple_hash.py | 58 +++++ .../chapter07_tree/array_binary_tree.py | 119 +++++++++++ .../hello_algo/chapter07_tree/avl_tree.py | 202 ++++++++++++++++++ .../chapter07_tree/binary_search_tree.py | 146 +++++++++++++ .../hello_algo/chapter07_tree/binary_tree.py | 40 ++++ .../chapter07_tree/binary_tree_bfs.py | 42 ++++ .../chapter07_tree/binary_tree_dfs.py | 65 ++++++ algorithms/hello_algo/chapter08_heap/heap.py | 71 ++++++ .../hello_algo/chapter08_heap/my_heap.py | 137 ++++++++++++ algorithms/hello_algo/chapter08_heap/top_k.py | 39 ++++ .../chapter09_graph/graph_adjacency_list.py | 111 ++++++++++ .../chapter09_graph/graph_adjacency_matrix.py | 116 ++++++++++ .../hello_algo/chapter09_graph/graph_bfs.py | 64 ++++++ .../hello_algo/chapter09_graph/graph_dfs.py | 57 +++++ .../chapter10_searching/binary_search.py | 52 +++++ .../chapter10_searching/binary_search_edge.py | 49 +++++ .../binary_search_insertion.py | 54 +++++ .../chapter10_searching/hashing_search.py | 51 +++++ .../chapter10_searching/linear_search.py | 45 ++++ .../hello_algo/chapter10_searching/two_sum.py | 42 ++++ .../chapter11_sorting/bubble_sort.py | 44 ++++ .../chapter11_sorting/bucket_sort.py | 35 +++ .../chapter11_sorting/counting_sort.py | 64 ++++++ .../hello_algo/chapter11_sorting/heap_sort.py | 45 ++++ .../chapter11_sorting/insertion_sort.py | 25 +++ .../chapter11_sorting/merge_sort.py | 55 +++++ .../chapter11_sorting/quick_sort.py | 130 +++++++++++ .../chapter11_sorting/radix_sort.py | 69 ++++++ .../chapter11_sorting/selection_sort.py | 26 +++ .../binary_search_recur.py | 40 ++++ .../build_tree.py | 54 +++++ .../chapter12_divide_and_conquer/hanota.py | 53 +++++ .../chapter13_backtracking/n_queens.py | 62 ++++++ .../chapter13_backtracking/permutations_i.py | 44 ++++ .../chapter13_backtracking/permutations_ii.py | 44 ++++ .../preorder_traversal_i_compact.py | 36 ++++ .../preorder_traversal_ii_compact.py | 42 ++++ .../preorder_traversal_iii_compact.py | 43 ++++ .../preorder_traversal_iii_template.py | 71 ++++++ .../chapter13_backtracking/subset_sum_i.py | 48 +++++ .../subset_sum_i_naive.py | 50 +++++ .../chapter13_backtracking/subset_sum_ii.py | 52 +++++ .../climbing_stairs_backtrack.py | 37 ++++ .../climbing_stairs_constraint_dp.py | 29 +++ .../climbing_stairs_dfs.py | 28 +++ .../climbing_stairs_dfs_mem.py | 35 +++ .../climbing_stairs_dp.py | 40 ++++ .../coin_change.py | 60 ++++++ .../coin_change_ii.py | 59 +++++ .../edit_distance.py | 123 +++++++++++ .../chapter14_dynamic_programming/knapsack.py | 101 +++++++++ .../min_cost_climbing_stairs_dp.py | 43 ++++ .../min_path_sum.py | 104 +++++++++ .../unbounded_knapsack.py | 55 +++++ .../chapter15_greedy/coin_change_greedy.py | 48 +++++ .../chapter15_greedy/fractional_knapsack.py | 46 ++++ .../chapter15_greedy/max_capacity.py | 33 +++ .../chapter15_greedy/max_product_cutting.py | 33 +++ algorithms/hello_algo/modules/__init__.py | 20 ++ algorithms/hello_algo/modules/list_node.py | 39 ++++ algorithms/hello_algo/modules/print_util.py | 79 +++++++ algorithms/hello_algo/modules/tree_node.py | 69 ++++++ algorithms/hello_algo/modules/vertex.py | 20 ++ algorithms/hello_algo/test_all.py | 33 +++ 89 files changed, 5834 insertions(+) create mode 100644 algorithms/hello_algo/__init__.py create mode 100644 algorithms/hello_algo/build.py create mode 100644 algorithms/hello_algo/chapter02_computational_complexity/iteration.py create mode 100644 algorithms/hello_algo/chapter02_computational_complexity/recursion.py create mode 100644 algorithms/hello_algo/chapter02_computational_complexity/space_complexity.py create mode 100644 algorithms/hello_algo/chapter02_computational_complexity/time_complexity.py create mode 100644 algorithms/hello_algo/chapter02_computational_complexity/worst_best_time_complexity.py create mode 100644 algorithms/hello_algo/chapter04_array_and_linkedlist/array.py create mode 100644 algorithms/hello_algo/chapter04_array_and_linkedlist/linked_list.py create mode 100644 algorithms/hello_algo/chapter04_array_and_linkedlist/list.py create mode 100644 algorithms/hello_algo/chapter04_array_and_linkedlist/my_list.py create mode 100644 algorithms/hello_algo/chapter05_stack_and_queue/array_deque.py create mode 100644 algorithms/hello_algo/chapter05_stack_and_queue/array_queue.py create mode 100644 algorithms/hello_algo/chapter05_stack_and_queue/array_stack.py create mode 100644 algorithms/hello_algo/chapter05_stack_and_queue/deque.py create mode 100644 algorithms/hello_algo/chapter05_stack_and_queue/linkedlist_deque.py create mode 100644 algorithms/hello_algo/chapter05_stack_and_queue/linkedlist_queue.py create mode 100644 algorithms/hello_algo/chapter05_stack_and_queue/linkedlist_stack.py create mode 100644 algorithms/hello_algo/chapter05_stack_and_queue/queue.py create mode 100644 algorithms/hello_algo/chapter05_stack_and_queue/stack.py create mode 100644 algorithms/hello_algo/chapter06_hashing/array_hash_map.py create mode 100644 algorithms/hello_algo/chapter06_hashing/built_in_hash.py create mode 100644 algorithms/hello_algo/chapter06_hashing/hash_map.py create mode 100644 algorithms/hello_algo/chapter06_hashing/hash_map_chaining.py create mode 100644 algorithms/hello_algo/chapter06_hashing/hash_map_open_addressing.py create mode 100644 algorithms/hello_algo/chapter06_hashing/simple_hash.py create mode 100644 algorithms/hello_algo/chapter07_tree/array_binary_tree.py create mode 100644 algorithms/hello_algo/chapter07_tree/avl_tree.py create mode 100644 algorithms/hello_algo/chapter07_tree/binary_search_tree.py create mode 100644 algorithms/hello_algo/chapter07_tree/binary_tree.py create mode 100644 algorithms/hello_algo/chapter07_tree/binary_tree_bfs.py create mode 100644 algorithms/hello_algo/chapter07_tree/binary_tree_dfs.py create mode 100644 algorithms/hello_algo/chapter08_heap/heap.py create mode 100644 algorithms/hello_algo/chapter08_heap/my_heap.py create mode 100644 algorithms/hello_algo/chapter08_heap/top_k.py create mode 100644 algorithms/hello_algo/chapter09_graph/graph_adjacency_list.py create mode 100644 algorithms/hello_algo/chapter09_graph/graph_adjacency_matrix.py create mode 100644 algorithms/hello_algo/chapter09_graph/graph_bfs.py create mode 100644 algorithms/hello_algo/chapter09_graph/graph_dfs.py create mode 100644 algorithms/hello_algo/chapter10_searching/binary_search.py create mode 100644 algorithms/hello_algo/chapter10_searching/binary_search_edge.py create mode 100644 algorithms/hello_algo/chapter10_searching/binary_search_insertion.py create mode 100644 algorithms/hello_algo/chapter10_searching/hashing_search.py create mode 100644 algorithms/hello_algo/chapter10_searching/linear_search.py create mode 100644 algorithms/hello_algo/chapter10_searching/two_sum.py create mode 100644 algorithms/hello_algo/chapter11_sorting/bubble_sort.py create mode 100644 algorithms/hello_algo/chapter11_sorting/bucket_sort.py create mode 100644 algorithms/hello_algo/chapter11_sorting/counting_sort.py create mode 100644 algorithms/hello_algo/chapter11_sorting/heap_sort.py create mode 100644 algorithms/hello_algo/chapter11_sorting/insertion_sort.py create mode 100644 algorithms/hello_algo/chapter11_sorting/merge_sort.py create mode 100644 algorithms/hello_algo/chapter11_sorting/quick_sort.py create mode 100644 algorithms/hello_algo/chapter11_sorting/radix_sort.py create mode 100644 algorithms/hello_algo/chapter11_sorting/selection_sort.py create mode 100644 algorithms/hello_algo/chapter12_divide_and_conquer/binary_search_recur.py create mode 100644 algorithms/hello_algo/chapter12_divide_and_conquer/build_tree.py create mode 100644 algorithms/hello_algo/chapter12_divide_and_conquer/hanota.py create mode 100644 algorithms/hello_algo/chapter13_backtracking/n_queens.py create mode 100644 algorithms/hello_algo/chapter13_backtracking/permutations_i.py create mode 100644 algorithms/hello_algo/chapter13_backtracking/permutations_ii.py create mode 100644 algorithms/hello_algo/chapter13_backtracking/preorder_traversal_i_compact.py create mode 100644 algorithms/hello_algo/chapter13_backtracking/preorder_traversal_ii_compact.py create mode 100644 algorithms/hello_algo/chapter13_backtracking/preorder_traversal_iii_compact.py create mode 100644 algorithms/hello_algo/chapter13_backtracking/preorder_traversal_iii_template.py create mode 100644 algorithms/hello_algo/chapter13_backtracking/subset_sum_i.py create mode 100644 algorithms/hello_algo/chapter13_backtracking/subset_sum_i_naive.py create mode 100644 algorithms/hello_algo/chapter13_backtracking/subset_sum_ii.py create mode 100644 algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_backtrack.py create mode 100644 algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_constraint_dp.py create mode 100644 algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_dfs.py create mode 100644 algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_dfs_mem.py create mode 100644 algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_dp.py create mode 100644 algorithms/hello_algo/chapter14_dynamic_programming/coin_change.py create mode 100644 algorithms/hello_algo/chapter14_dynamic_programming/coin_change_ii.py create mode 100644 algorithms/hello_algo/chapter14_dynamic_programming/edit_distance.py create mode 100644 algorithms/hello_algo/chapter14_dynamic_programming/knapsack.py create mode 100644 algorithms/hello_algo/chapter14_dynamic_programming/min_cost_climbing_stairs_dp.py create mode 100644 algorithms/hello_algo/chapter14_dynamic_programming/min_path_sum.py create mode 100644 algorithms/hello_algo/chapter14_dynamic_programming/unbounded_knapsack.py create mode 100644 algorithms/hello_algo/chapter15_greedy/coin_change_greedy.py create mode 100644 algorithms/hello_algo/chapter15_greedy/fractional_knapsack.py create mode 100644 algorithms/hello_algo/chapter15_greedy/max_capacity.py create mode 100644 algorithms/hello_algo/chapter15_greedy/max_product_cutting.py create mode 100644 algorithms/hello_algo/modules/__init__.py create mode 100644 algorithms/hello_algo/modules/list_node.py create mode 100644 algorithms/hello_algo/modules/print_util.py create mode 100644 algorithms/hello_algo/modules/tree_node.py create mode 100644 algorithms/hello_algo/modules/vertex.py create mode 100644 algorithms/hello_algo/test_all.py diff --git a/algorithms/hello_algo/__init__.py b/algorithms/hello_algo/__init__.py new file mode 100644 index 0000000..5d50274 --- /dev/null +++ b/algorithms/hello_algo/__init__.py @@ -0,0 +1,4 @@ +# -*- encoding: utf-8 -*- +""" +description +""" diff --git a/algorithms/hello_algo/build.py b/algorithms/hello_algo/build.py new file mode 100644 index 0000000..98523f2 --- /dev/null +++ b/algorithms/hello_algo/build.py @@ -0,0 +1,20 @@ +import glob +import py_compile as pyc + +if __name__ == "__main__": + # find source code files + src_paths = sorted(glob.glob("codes/python/**/*.py")) + num_src = len(src_paths) + num_src_error = 0 + + # compile python code + for src_path in src_paths: + try: + pyc.compile(src_path, doraise=True) + except pyc.PyCompileError as e: + num_src_error += 1 + print(e) + + print(f"===== Build Complete =====") + print(f"Total: {num_src}") + print(f"Error: {num_src_error}") diff --git a/algorithms/hello_algo/chapter02_computational_complexity/iteration.py b/algorithms/hello_algo/chapter02_computational_complexity/iteration.py new file mode 100644 index 0000000..2f83398 --- /dev/null +++ b/algorithms/hello_algo/chapter02_computational_complexity/iteration.py @@ -0,0 +1,65 @@ +""" +File: iteration.py +Created Time: 2023-08-24 +Author: Krahets (krahets@163.com) +""" + + +def for_loop(n: int) -> int: + """for 循环""" + res = 0 + # 循环求和 1, 2, ..., n-1, n + for i in range(1, n + 1): + res += i + return res + + +def while_loop(n: int) -> int: + """while 循环""" + res = 0 + i = 1 # 初始化条件变量 + # 循环求和 1, 2, ..., n-1, n + while i <= n: + res += i + i += 1 # 更新条件变量 + return res + + +def while_loop_ii(n: int) -> int: + """while 循环(两次更新)""" + res = 0 + i = 1 # 初始化条件变量 + # 循环求和 1, 4, ... + while i <= n: + res += i + # 更新条件变量 + i += 1 + i *= 2 + return res + + +def nested_for_loop(n: int) -> str: + """双层 for 循环""" + res = "" + # 循环 i = 1, 2, ..., n-1, n + for i in range(1, n + 1): + # 循环 j = 1, 2, ..., n-1, n + for j in range(1, n + 1): + res += f"({i}, {j}), " + return res + + +"""Driver Code""" +if __name__ == "__main__": + n = 5 + res = for_loop(n) + print(f"\nfor 循环的求和结果 res = {res}") + + res = while_loop(n) + print(f"\nwhile 循环的求和结果 res = {res}") + + res = while_loop_ii(n) + print(f"\nwhile 循环(两次更新)求和结果 res = {res}") + + res = nested_for_loop(n) + print(f"\n双层 for 循环的遍历结果 {res}") diff --git a/algorithms/hello_algo/chapter02_computational_complexity/recursion.py b/algorithms/hello_algo/chapter02_computational_complexity/recursion.py new file mode 100644 index 0000000..c44064e --- /dev/null +++ b/algorithms/hello_algo/chapter02_computational_complexity/recursion.py @@ -0,0 +1,69 @@ +""" +File: recursion.py +Created Time: 2023-08-24 +Author: Krahets (krahets@163.com) +""" + + +def recur(n: int) -> int: + """递归""" + # 终止条件 + if n == 1: + return 1 + # 递:递归调用 + res = recur(n - 1) + # 归:返回结果 + return n + res + + +def for_loop_recur(n: int) -> int: + """使用迭代模拟递归""" + # 使用一个显式的栈来模拟系统调用栈 + stack = [] + res = 0 + # 递:递归调用 + for i in range(n, 0, -1): + # 通过“入栈操作”模拟“递” + stack.append(i) + # 归:返回结果 + while stack: + # 通过“出栈操作”模拟“归” + res += stack.pop() + # res = 1+2+3+...+n + return res + + +def tail_recur(n, res): + """尾递归""" + # 终止条件 + if n == 0: + return res + # 尾递归调用 + return tail_recur(n - 1, res + n) + + +def fib(n: int) -> int: + """斐波那契数列:递归""" + # 终止条件 f(1) = 0, f(2) = 1 + if n == 1 or n == 2: + return n - 1 + # 递归调用 f(n) = f(n-1) + f(n-2) + res = fib(n - 1) + fib(n - 2) + # 返回结果 f(n) + return res + + +"""Driver Code""" +if __name__ == "__main__": + n = 5 + res = recur(n) + print(f"\n递归函数的求和结果 res = {res}") + + res = for_loop_recur(n) + print(f"\n使用迭代模拟递归求和结果 res = {res}") + + res = tail_recur(n, 0) + print(f"\n尾递归函数的求和结果 res = {res}") + + res = fib(n) + print(f"\n斐波那契数列的第 {n} 项为 {res}") diff --git a/algorithms/hello_algo/chapter02_computational_complexity/space_complexity.py b/algorithms/hello_algo/chapter02_computational_complexity/space_complexity.py new file mode 100644 index 0000000..be91c2a --- /dev/null +++ b/algorithms/hello_algo/chapter02_computational_complexity/space_complexity.py @@ -0,0 +1,90 @@ +""" +File: space_complexity.py +Created Time: 2022-11-25 +Author: Krahets (krahets@163.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import ListNode, TreeNode, print_tree + + +def function() -> int: + """函数""" + # 执行某些操作 + return 0 + + +def constant(n: int): + """常数阶""" + # 常量、变量、对象占用 O(1) 空间 + a = 0 + nums = [0] * 10000 + node = ListNode(0) + # 循环中的变量占用 O(1) 空间 + for _ in range(n): + c = 0 + # 循环中的函数占用 O(1) 空间 + for _ in range(n): + function() + + +def linear(n: int): + """线性阶""" + # 长度为 n 的列表占用 O(n) 空间 + nums = [0] * n + # 长度为 n 的哈希表占用 O(n) 空间 + hmap = dict[int, str]() + for i in range(n): + hmap[i] = str(i) + + +def linear_recur(n: int): + """线性阶(递归实现)""" + print("递归 n =", n) + if n == 1: + return + linear_recur(n - 1) + + +def quadratic(n: int): + """平方阶""" + # 二维列表占用 O(n^2) 空间 + num_matrix = [[0] * n for _ in range(n)] + + +def quadratic_recur(n: int) -> int: + """平方阶(递归实现)""" + if n <= 0: + return 0 + # 数组 nums 长度为 n, n-1, ..., 2, 1 + nums = [0] * n + return quadratic_recur(n - 1) + + +def build_tree(n: int) -> TreeNode | None: + """指数阶(建立满二叉树)""" + if n == 0: + return None + root = TreeNode(0) + root.left = build_tree(n - 1) + root.right = build_tree(n - 1) + return root + + +"""Driver Code""" +if __name__ == "__main__": + n = 5 + # 常数阶 + constant(n) + # 线性阶 + linear(n) + linear_recur(n) + # 平方阶 + quadratic(n) + quadratic_recur(n) + # 指数阶 + root = build_tree(n) + print_tree(root) diff --git a/algorithms/hello_algo/chapter02_computational_complexity/time_complexity.py b/algorithms/hello_algo/chapter02_computational_complexity/time_complexity.py new file mode 100644 index 0000000..79240e0 --- /dev/null +++ b/algorithms/hello_algo/chapter02_computational_complexity/time_complexity.py @@ -0,0 +1,151 @@ +""" +File: time_complexity.py +Created Time: 2022-11-25 +Author: Krahets (krahets@163.com) +""" + + +def constant(n: int) -> int: + """常数阶""" + count = 0 + size = 100000 + for _ in range(size): + count += 1 + return count + + +def linear(n: int) -> int: + """线性阶""" + count = 0 + for _ in range(n): + count += 1 + return count + + +def array_traversal(nums: list[int]) -> int: + """线性阶(遍历数组)""" + count = 0 + # 循环次数与数组长度成正比 + for num in nums: + count += 1 + return count + + +def quadratic(n: int) -> int: + """平方阶""" + count = 0 + # 循环次数与数组长度成平方关系 + for i in range(n): + for j in range(n): + count += 1 + return count + + +def bubble_sort(nums: list[int]) -> int: + """平方阶(冒泡排序)""" + count = 0 # 计数器 + # 外循环:未排序区间为 [0, i] + for i in range(len(nums) - 1, 0, -1): + # 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端 + for j in range(i): + if nums[j] > nums[j + 1]: + # 交换 nums[j] 与 nums[j + 1] + tmp: int = nums[j] + nums[j] = nums[j + 1] + nums[j + 1] = tmp + count += 3 # 元素交换包含 3 个单元操作 + return count + + +def exponential(n: int) -> int: + """指数阶(循环实现)""" + count = 0 + base = 1 + # 细胞每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1) + for _ in range(n): + for _ in range(base): + count += 1 + base *= 2 + # count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1 + return count + + +def exp_recur(n: int) -> int: + """指数阶(递归实现)""" + if n == 1: + return 1 + return exp_recur(n - 1) + exp_recur(n - 1) + 1 + + +def logarithmic(n: float) -> int: + """对数阶(循环实现)""" + count = 0 + while n > 1: + n = n / 2 + count += 1 + return count + + +def log_recur(n: float) -> int: + """对数阶(递归实现)""" + if n <= 1: + return 0 + return log_recur(n / 2) + 1 + + +def linear_log_recur(n: float) -> int: + """线性对数阶""" + if n <= 1: + return 1 + count: int = linear_log_recur(n // 2) + linear_log_recur(n // 2) + for _ in range(n): + count += 1 + return count + + +def factorial_recur(n: int) -> int: + """阶乘阶(递归实现)""" + if n == 0: + return 1 + count = 0 + # 从 1 个分裂出 n 个 + for _ in range(n): + count += factorial_recur(n - 1) + return count + + +"""Driver Code""" +if __name__ == "__main__": + # 可以修改 n 运行,体会一下各种复杂度的操作数量变化趋势 + n = 8 + print("输入数据大小 n =", n) + + count: int = constant(n) + print("常数阶的操作数量 =", count) + + count: int = linear(n) + print("线性阶的操作数量 =", count) + count: int = array_traversal([0] * n) + print("线性阶(遍历数组)的操作数量 =", count) + + count: int = quadratic(n) + print("平方阶的操作数量 =", count) + nums = [i for i in range(n, 0, -1)] # [n, n-1, ..., 2, 1] + count: int = bubble_sort(nums) + print("平方阶(冒泡排序)的操作数量 =", count) + + count: int = exponential(n) + print("指数阶(循环实现)的操作数量 =", count) + count: int = exp_recur(n) + print("指数阶(递归实现)的操作数量 =", count) + + count: int = logarithmic(n) + print("对数阶(循环实现)的操作数量 =", count) + count: int = log_recur(n) + print("对数阶(递归实现)的操作数量 =", count) + + count: int = linear_log_recur(n) + print("线性对数阶(递归实现)的操作数量 =", count) + + count: int = factorial_recur(n) + print("阶乘阶(递归实现)的操作数量 =", count) diff --git a/algorithms/hello_algo/chapter02_computational_complexity/worst_best_time_complexity.py b/algorithms/hello_algo/chapter02_computational_complexity/worst_best_time_complexity.py new file mode 100644 index 0000000..6c2ebee --- /dev/null +++ b/algorithms/hello_algo/chapter02_computational_complexity/worst_best_time_complexity.py @@ -0,0 +1,36 @@ +""" +File: worst_best_time_complexity.py +Created Time: 2022-11-25 +Author: Krahets (krahets@163.com) +""" + +import random + + +def random_numbers(n: int) -> list[int]: + """生成一个数组,元素为: 1, 2, ..., n ,顺序被打乱""" + # 生成数组 nums =: 1, 2, 3, ..., n + nums = [i for i in range(1, n + 1)] + # 随机打乱数组元素 + random.shuffle(nums) + return nums + + +def find_one(nums: list[int]) -> int: + """查找数组 nums 中数字 1 所在索引""" + for i in range(len(nums)): + # 当元素 1 在数组头部时,达到最佳时间复杂度 O(1) + # 当元素 1 在数组尾部时,达到最差时间复杂度 O(n) + if nums[i] == 1: + return i + return -1 + + +"""Driver Code""" +if __name__ == "__main__": + for i in range(10): + n = 100 + nums: list[int] = random_numbers(n) + index: int = find_one(nums) + print("\n数组 [ 1, 2, ..., n ] 被打乱后 =", nums) + print("数字 1 的索引为", index) diff --git a/algorithms/hello_algo/chapter04_array_and_linkedlist/array.py b/algorithms/hello_algo/chapter04_array_and_linkedlist/array.py new file mode 100644 index 0000000..0b917e7 --- /dev/null +++ b/algorithms/hello_algo/chapter04_array_and_linkedlist/array.py @@ -0,0 +1,99 @@ +""" +File: array.py +Created Time: 2022-11-25 +Author: Krahets (krahets@163.com) +""" + +import random + + +def random_access(nums: list[int]) -> int: + """随机访问元素""" + # 在区间 [0, len(nums)-1] 中随机抽取一个数字 + random_index = random.randint(0, len(nums) - 1) + # 获取并返回随机元素 + random_num = nums[random_index] + return random_num + + +# 请注意,Python 的 list 是动态数组,可以直接扩展 +# 为了方便学习,本函数将 list 看作是长度不可变的数组 +def extend(nums: list[int], enlarge: int) -> list[int]: + """扩展数组长度""" + # 初始化一个扩展长度后的数组 + res = [0] * (len(nums) + enlarge) + # 将原数组中的所有元素复制到新数组 + for i in range(len(nums)): + res[i] = nums[i] + # 返回扩展后的新数组 + return res + + +def insert(nums: list[int], num: int, index: int): + """在数组的索引 index 处插入元素 num""" + # 把索引 index 以及之后的所有元素向后移动一位 + for i in range(len(nums) - 1, index, -1): + nums[i] = nums[i - 1] + # 将 num 赋给 index 处元素 + nums[index] = num + + +def remove(nums: list[int], index: int): + """删除索引 index 处元素""" + # 把索引 index 之后的所有元素向前移动一位 + for i in range(index, len(nums) - 1): + nums[i] = nums[i + 1] + + +def traverse(nums: list[int]): + """遍历数组""" + count = 0 + # 通过索引遍历数组 + for i in range(len(nums)): + count += 1 + # 直接遍历数组 + for num in nums: + count += 1 + # 同时遍历数据索引和元素 + for i, num in enumerate(nums): + count += 1 + + +def find(nums: list[int], target: int) -> int: + """在数组中查找指定元素""" + for i in range(len(nums)): + if nums[i] == target: + return i + return -1 + + +"""Driver Code""" +if __name__ == "__main__": + # 初始化数组 + arr = [0] * 5 + print("数组 arr =", arr) + nums = [1, 3, 2, 5, 4] + print("数组 nums =", nums) + + # 随机访问 + random_num: int = random_access(nums) + print("在 nums 中获取随机元素", random_num) + + # 长度扩展 + nums: list[int] = extend(nums, 3) + print("将数组长度扩展至 8 ,得到 nums =", nums) + + # 插入元素 + insert(nums, 6, 3) + print("在索引 3 处插入数字 6 ,得到 nums =", nums) + + # 删除元素 + remove(nums, 2) + print("删除索引 2 处的元素,得到 nums =", nums) + + # 遍历数组 + traverse(nums) + + # 查找元素 + index: int = find(nums, 3) + print("在 nums 中查找元素 3 ,得到索引 =", index) diff --git a/algorithms/hello_algo/chapter04_array_and_linkedlist/linked_list.py b/algorithms/hello_algo/chapter04_array_and_linkedlist/linked_list.py new file mode 100644 index 0000000..a513642 --- /dev/null +++ b/algorithms/hello_algo/chapter04_array_and_linkedlist/linked_list.py @@ -0,0 +1,84 @@ +""" +File: linked_list.py +Created Time: 2022-11-25 +Author: Krahets (krahets@163.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import ListNode, print_linked_list + + +def insert(n0: ListNode, P: ListNode): + """在链表的节点 n0 之后插入节点 P""" + n1 = n0.next + P.next = n1 + n0.next = P + + +def remove(n0: ListNode): + """删除链表的节点 n0 之后的首个节点""" + if not n0.next: + return + # n0 -> P -> n1 + P = n0.next + n1 = P.next + n0.next = n1 + + +def access(head: ListNode, index: int) -> ListNode | None: + """访问链表中索引为 index 的节点""" + for _ in range(index): + if not head: + return None + head = head.next + return head + + +def find(head: ListNode, target: int) -> int: + """在链表中查找值为 target 的首个节点""" + index = 0 + while head: + if head.val == target: + return index + head = head.next + index += 1 + return -1 + + +"""Driver Code""" +if __name__ == "__main__": + # 初始化链表 + # 初始化各个节点 + n0 = ListNode(1) + n1 = ListNode(3) + n2 = ListNode(2) + n3 = ListNode(5) + n4 = ListNode(4) + # 构建引用指向 + n0.next = n1 + n1.next = n2 + n2.next = n3 + n3.next = n4 + print("初始化的链表为") + print_linked_list(n0) + + # 插入节点 + insert(n0, ListNode(0)) + print("插入节点后的链表为") + print_linked_list(n0) + + # 删除节点 + remove(n0) + print("删除节点后的链表为") + print_linked_list(n0) + + # 访问节点 + node: ListNode = access(n0, 3) + print("链表中索引 3 处的节点的值 = {}".format(node.val)) + + # 查找节点 + index: int = find(n0, 2) + print("链表中值为 2 的节点的索引 = {}".format(index)) diff --git a/algorithms/hello_algo/chapter04_array_and_linkedlist/list.py b/algorithms/hello_algo/chapter04_array_and_linkedlist/list.py new file mode 100644 index 0000000..b9ad6d3 --- /dev/null +++ b/algorithms/hello_algo/chapter04_array_and_linkedlist/list.py @@ -0,0 +1,59 @@ +""" +File: list.py +Created Time: 2022-11-25 +Author: Krahets (krahets@163.com) +""" + +"""Driver Code""" +if __name__ == "__main__": + # 初始化列表 + nums: list[int] = [1, 3, 2, 5, 4] + print("\n列表 nums =", nums) + + # 访问元素 + x: int = nums[1] + print("\n访问索引 1 处的元素,得到 x =", x) + + # 更新元素 + nums[1] = 0 + print("\n将索引 1 处的元素更新为 0 ,得到 nums =", nums) + + # 清空列表 + nums.clear() + print("\n清空列表后 nums =", nums) + + # 尾部添加元素 + nums.append(1) + nums.append(3) + nums.append(2) + nums.append(5) + nums.append(4) + print("\n添加元素后 nums =", nums) + + # 中间插入元素 + nums.insert(3, 6) + print("\n在索引 3 处插入数字 6 ,得到 nums =", nums) + + # 删除元素 + nums.pop(3) + print("\n删除索引 3 处的元素,得到 nums =", nums) + + # 遍历列表 + tmp = [] + for i in range(len(nums)): + tmp.append(nums[i]) + print(f"\n通过索引遍历列表得到 tmp = {tmp}") + + tmp.clear() + for num in nums: + tmp.append(num) + print(f"\n直接遍历列表元素得到 tmp = {tmp}") + + # 拼接两个列表 + nums1 = [6, 8, 7, 10, 9] + nums += nums1 + print("\n将列表 nums1 拼接到 nums 之后,得到 nums =", nums) + + # 排序列表 + nums.sort() + print("\n排序列表后 nums =", nums) diff --git a/algorithms/hello_algo/chapter04_array_and_linkedlist/my_list.py b/algorithms/hello_algo/chapter04_array_and_linkedlist/my_list.py new file mode 100644 index 0000000..c78ac43 --- /dev/null +++ b/algorithms/hello_algo/chapter04_array_and_linkedlist/my_list.py @@ -0,0 +1,118 @@ +""" +File: my_list.py +Created Time: 2022-11-25 +Author: Krahets (krahets@163.com) +""" + + +class MyList: + """列表类简易实现""" + + def __init__(self): + """构造方法""" + self._capacity: int = 10 # 列表容量 + self._arr: list[int] = [0] * self._capacity # 数组(存储列表元素) + self._size: int = 0 # 列表长度(即当前元素数量) + self._extend_ratio: int = 2 # 每次列表扩容的倍数 + + def size(self) -> int: + """获取列表长度(即当前元素数量)""" + return self._size + + def capacity(self) -> int: + """获取列表容量""" + return self._capacity + + def get(self, index: int) -> int: + """访问元素""" + # 索引如果越界则抛出异常,下同 + if index < 0 or index >= self._size: + raise IndexError("索引越界") + return self._arr[index] + + def set(self, num: int, index: int): + """更新元素""" + if index < 0 or index >= self._size: + raise IndexError("索引越界") + self._arr[index] = num + + def add(self, num: int): + """尾部添加元素""" + # 元素数量超出容量时,触发扩容机制 + if self.size() == self.capacity(): + self.extend_capacity() + self._arr[self._size] = num + self._size += 1 + + def insert(self, num: int, index: int): + """中间插入元素""" + if index < 0 or index >= self._size: + raise IndexError("索引越界") + # 元素数量超出容量时,触发扩容机制 + if self._size == self.capacity(): + self.extend_capacity() + # 将索引 index 以及之后的元素都向后移动一位 + for j in range(self._size - 1, index - 1, -1): + self._arr[j + 1] = self._arr[j] + self._arr[index] = num + # 更新元素数量 + self._size += 1 + + def remove(self, index: int) -> int: + """删除元素""" + if index < 0 or index >= self._size: + raise IndexError("索引越界") + num = self._arr[index] + # 索引 i 之后的元素都向前移动一位 + for j in range(index, self._size - 1): + self._arr[j] = self._arr[j + 1] + # 更新元素数量 + self._size -= 1 + # 返回被删除元素 + return num + + def extend_capacity(self): + """列表扩容""" + # 新建一个长度为原数组 __extend_ratio 倍的新数组,并将原数组拷贝到新数组 + self._arr = self._arr + [0] * self.capacity() * (self._extend_ratio - 1) + # 更新列表容量 + self._capacity = len(self._arr) + + def to_array(self) -> list[int]: + """返回有效长度的列表""" + return self._arr[: self._size] + + +"""Driver Code""" +if __name__ == "__main__": + # 初始化列表 + nums = MyList() + # 尾部添加元素 + nums.add(1) + nums.add(3) + nums.add(2) + nums.add(5) + nums.add(4) + print(f"列表 nums = {nums.to_array()} ,容量 = {nums.capacity()} ,长度 = {nums.size()}") + + # 中间插入元素 + nums.insert(6, index=3) + print("在索引 3 处插入数字 6 ,得到 nums =", nums.to_array()) + + # 删除元素 + nums.remove(3) + print("删除索引 3 处的元素,得到 nums =", nums.to_array()) + + # 访问元素 + num = nums.get(1) + print("访问索引 1 处的元素,得到 num =", num) + + # 更新元素 + nums.set(0, 1) + print("将索引 1 处的元素更新为 0 ,得到 nums =", nums.to_array()) + + # 测试扩容机制 + for i in range(10): + # 在 i = 5 时,列表长度将超出列表容量,此时触发扩容机制 + nums.add(i) + print(f"扩容后的列表 {nums.to_array()} ,容量 = {nums.capacity()} ,长度 = {nums.size()}") diff --git a/algorithms/hello_algo/chapter05_stack_and_queue/array_deque.py b/algorithms/hello_algo/chapter05_stack_and_queue/array_deque.py new file mode 100644 index 0000000..308f8e7 --- /dev/null +++ b/algorithms/hello_algo/chapter05_stack_and_queue/array_deque.py @@ -0,0 +1,129 @@ +""" +File: array_deque.py +Created Time: 2023-03-01 +Author: Krahets (krahets@163.com) +""" + + +class ArrayDeque: + """基于环形数组实现的双向队列""" + + def __init__(self, capacity: int): + """构造方法""" + self._nums: list[int] = [0] * capacity + self._front: int = 0 + self._size: int = 0 + + def capacity(self) -> int: + """获取双向队列的容量""" + return len(self._nums) + + def size(self) -> int: + """获取双向队列的长度""" + return self._size + + def is_empty(self) -> bool: + """判断双向队列是否为空""" + return self._size == 0 + + def index(self, i: int) -> int: + """计算环形数组索引""" + # 通过取余操作实现数组首尾相连 + # 当 i 越过数组尾部后,回到头部 + # 当 i 越过数组头部后,回到尾部 + return (i + self.capacity()) % self.capacity() + + def push_first(self, num: int): + """队首入队""" + if self._size == self.capacity(): + print("双向队列已满") + return + # 队首指针向左移动一位 + # 通过取余操作,实现 front 越过数组头部后回到尾部 + self._front = self.index(self._front - 1) + # 将 num 添加至队首 + self._nums[self._front] = num + self._size += 1 + + def push_last(self, num: int): + """队尾入队""" + if self._size == self.capacity(): + print("双向队列已满") + return + # 计算尾指针,指向队尾索引 + 1 + rear = self.index(self._front + self._size) + # 将 num 添加至队尾 + self._nums[rear] = num + self._size += 1 + + def pop_first(self) -> int: + """队首出队""" + num = self.peek_first() + # 队首指针向后移动一位 + self._front = self.index(self._front + 1) + self._size -= 1 + return num + + def pop_last(self) -> int: + """队尾出队""" + num = self.peek_last() + self._size -= 1 + return num + + def peek_first(self) -> int: + """访问队首元素""" + if self.is_empty(): + raise IndexError("双向队列为空") + return self._nums[self._front] + + def peek_last(self) -> int: + """访问队尾元素""" + if self.is_empty(): + raise IndexError("双向队列为空") + # 计算尾元素索引 + last = self.index(self._front + self._size - 1) + return self._nums[last] + + def to_array(self) -> list[int]: + """返回数组用于打印""" + # 仅转换有效长度范围内的列表元素 + res = [] + for i in range(self._size): + res.append(self._nums[self.index(self._front + i)]) + return res + + +"""Driver Code""" +if __name__ == "__main__": + # 初始化双向队列 + deque = ArrayDeque(10) + deque.push_last(3) + deque.push_last(2) + deque.push_last(5) + print("双向队列 deque =", deque.to_array()) + + # 访问元素 + peek_first: int = deque.peek_first() + print("队首元素 peek_first =", peek_first) + peek_last: int = deque.peek_last() + print("队尾元素 peek_last =", peek_last) + + # 元素入队 + deque.push_last(4) + print("元素 4 队尾入队后 deque =", deque.to_array()) + deque.push_first(1) + print("元素 1 队首入队后 deque =", deque.to_array()) + + # 元素出队 + pop_last: int = deque.pop_last() + print("队尾出队元素 =", pop_last, ",队尾出队后 deque =", deque.to_array()) + pop_first: int = deque.pop_first() + print("队首出队元素 =", pop_first, ",队首出队后 deque =", deque.to_array()) + + # 获取双向队列的长度 + size: int = deque.size() + print("双向队列长度 size =", size) + + # 判断双向队列是否为空 + is_empty: bool = deque.is_empty() + print("双向队列是否为空 =", is_empty) diff --git a/algorithms/hello_algo/chapter05_stack_and_queue/array_queue.py b/algorithms/hello_algo/chapter05_stack_and_queue/array_queue.py new file mode 100644 index 0000000..73b773b --- /dev/null +++ b/algorithms/hello_algo/chapter05_stack_and_queue/array_queue.py @@ -0,0 +1,98 @@ +""" +File: array_queue.py +Created Time: 2022-12-01 +Author: Peng Chen (pengchzn@gmail.com) +""" + + +class ArrayQueue: + """基于环形数组实现的队列""" + + def __init__(self, size: int): + """构造方法""" + self._nums: list[int] = [0] * size # 用于存储队列元素的数组 + self._front: int = 0 # 队首指针,指向队首元素 + self._size: int = 0 # 队列长度 + + def capacity(self) -> int: + """获取队列的容量""" + return len(self._nums) + + def size(self) -> int: + """获取队列的长度""" + return self._size + + def is_empty(self) -> bool: + """判断队列是否为空""" + return self._size == 0 + + def push(self, num: int): + """入队""" + if self._size == self.capacity(): + raise IndexError("队列已满") + # 计算尾指针,指向队尾索引 + 1 + # 通过取余操作,实现 rear 越过数组尾部后回到头部 + rear: int = (self._front + self._size) % self.capacity() + # 将 num 添加至队尾 + self._nums[rear] = num + self._size += 1 + + def pop(self) -> int: + """出队""" + num: int = self.peek() + # 队首指针向后移动一位,若越过尾部则返回到数组头部 + self._front = (self._front + 1) % self.capacity() + self._size -= 1 + return num + + def peek(self) -> int: + """访问队首元素""" + if self.is_empty(): + raise IndexError("队列为空") + return self._nums[self._front] + + def to_list(self) -> list[int]: + """返回列表用于打印""" + res = [0] * self.size() + j: int = self._front + for i in range(self.size()): + res[i] = self._nums[(j % self.capacity())] + j += 1 + return res + + +"""Driver Code""" +if __name__ == "__main__": + # 初始化队列 + queue = ArrayQueue(10) + + # 元素入队 + queue.push(1) + queue.push(3) + queue.push(2) + queue.push(5) + queue.push(4) + print("队列 queue =", queue.to_list()) + + # 访问队首元素 + peek: int = queue.peek() + print("队首元素 peek =", peek) + + # 元素出队 + pop: int = queue.pop() + print("出队元素 pop =", pop) + print("出队后 queue =", queue.to_list()) + + # 获取队列的长度 + size: int = queue.size() + print("队列长度 size =", size) + + # 判断队列是否为空 + is_empty: bool = queue.is_empty() + print("队列是否为空 =", is_empty) + + # 测试环形数组 + for i in range(10): + queue.push(i) + queue.pop() + print("第", i, "轮入队 + 出队后 queue = ", queue.to_list()) diff --git a/algorithms/hello_algo/chapter05_stack_and_queue/array_stack.py b/algorithms/hello_algo/chapter05_stack_and_queue/array_stack.py new file mode 100644 index 0000000..6f270e9 --- /dev/null +++ b/algorithms/hello_algo/chapter05_stack_and_queue/array_stack.py @@ -0,0 +1,72 @@ +""" +File: array_stack.py +Created Time: 2022-11-29 +Author: Peng Chen (pengchzn@gmail.com) +""" + + +class ArrayStack: + """基于数组实现的栈""" + + def __init__(self): + """构造方法""" + self._stack: list[int] = [] + + def size(self) -> int: + """获取栈的长度""" + return len(self._stack) + + def is_empty(self) -> bool: + """判断栈是否为空""" + return self._stack == [] + + def push(self, item: int): + """入栈""" + self._stack.append(item) + + def pop(self) -> int: + """出栈""" + if self.is_empty(): + raise IndexError("栈为空") + return self._stack.pop() + + def peek(self) -> int: + """访问栈顶元素""" + if self.is_empty(): + raise IndexError("栈为空") + return self._stack[-1] + + def to_list(self) -> list[int]: + """返回列表用于打印""" + return self._stack + + +"""Driver Code""" +if __name__ == "__main__": + # 初始化栈 + stack = ArrayStack() + + # 元素入栈 + stack.push(1) + stack.push(3) + stack.push(2) + stack.push(5) + stack.push(4) + print("栈 stack =", stack.to_list()) + + # 访问栈顶元素 + peek: int = stack.peek() + print("栈顶元素 peek =", peek) + + # 元素出栈 + pop: int = stack.pop() + print("出栈元素 pop =", pop) + print("出栈后 stack =", stack.to_list()) + + # 获取栈的长度 + size: int = stack.size() + print("栈的长度 size =", size) + + # 判断是否为空 + is_empty: bool = stack.is_empty() + print("栈是否为空 =", is_empty) diff --git a/algorithms/hello_algo/chapter05_stack_and_queue/deque.py b/algorithms/hello_algo/chapter05_stack_and_queue/deque.py new file mode 100644 index 0000000..2717165 --- /dev/null +++ b/algorithms/hello_algo/chapter05_stack_and_queue/deque.py @@ -0,0 +1,42 @@ +""" +File: deque.py +Created Time: 2022-11-29 +Author: Peng Chen (pengchzn@gmail.com) +""" + +from collections import deque + +"""Driver Code""" +if __name__ == "__main__": + # 初始化双向队列 + deq: deque[int] = deque() + + # 元素入队 + deq.append(2) # 添加至队尾 + deq.append(5) + deq.append(4) + deq.appendleft(3) # 添加至队首 + deq.appendleft(1) + print("双向队列 deque =", deq) + + # 访问元素 + front: int = deq[0] # 队首元素 + print("队首元素 front =", front) + rear: int = deq[-1] # 队尾元素 + print("队尾元素 rear =", rear) + + # 元素出队 + pop_front: int = deq.popleft() # 队首元素出队 + print("队首出队元素 pop_front =", pop_front) + print("队首出队后 deque =", deq) + pop_rear: int = deq.pop() # 队尾元素出队 + print("队尾出队元素 pop_rear =", pop_rear) + print("队尾出队后 deque =", deq) + + # 获取双向队列的长度 + size: int = len(deq) + print("双向队列长度 size =", size) + + # 判断双向队列是否为空 + is_empty: bool = len(deq) == 0 + print("双向队列是否为空 =", is_empty) diff --git a/algorithms/hello_algo/chapter05_stack_and_queue/linkedlist_deque.py b/algorithms/hello_algo/chapter05_stack_and_queue/linkedlist_deque.py new file mode 100644 index 0000000..e4e42fc --- /dev/null +++ b/algorithms/hello_algo/chapter05_stack_and_queue/linkedlist_deque.py @@ -0,0 +1,151 @@ +""" +File: linkedlist_deque.py +Created Time: 2023-03-01 +Author: Krahets (krahets@163.com) +""" + + +class ListNode: + """双向链表节点""" + + def __init__(self, val: int): + """构造方法""" + self.val: int = val + self.next: ListNode | None = None # 后继节点引用 + self.prev: ListNode | None = None # 前驱节点引用 + + +class LinkedListDeque: + """基于双向链表实现的双向队列""" + + def __init__(self): + """构造方法""" + self._front: ListNode | None = None # 头节点 front + self._rear: ListNode | None = None # 尾节点 rear + self._size: int = 0 # 双向队列的长度 + + def size(self) -> int: + """获取双向队列的长度""" + return self._size + + def is_empty(self) -> bool: + """判断双向队列是否为空""" + return self.size() == 0 + + def push(self, num: int, is_front: bool): + """入队操作""" + node = ListNode(num) + # 若链表为空,则令 front, rear 都指向 node + if self.is_empty(): + self._front = self._rear = node + # 队首入队操作 + elif is_front: + # 将 node 添加至链表头部 + self._front.prev = node + node.next = self._front + self._front = node # 更新头节点 + # 队尾入队操作 + else: + # 将 node 添加至链表尾部 + self._rear.next = node + node.prev = self._rear + self._rear = node # 更新尾节点 + self._size += 1 # 更新队列长度 + + def push_first(self, num: int): + """队首入队""" + self.push(num, True) + + def push_last(self, num: int): + """队尾入队""" + self.push(num, False) + + def pop(self, is_front: bool) -> int: + """出队操作""" + if self.is_empty(): + raise IndexError("双向队列为空") + # 队首出队操作 + if is_front: + val: int = self._front.val # 暂存头节点值 + # 删除头节点 + fnext: ListNode | None = self._front.next + if fnext != None: + fnext.prev = None + self._front.next = None + self._front = fnext # 更新头节点 + # 队尾出队操作 + else: + val: int = self._rear.val # 暂存尾节点值 + # 删除尾节点 + rprev: ListNode | None = self._rear.prev + if rprev != None: + rprev.next = None + self._rear.prev = None + self._rear = rprev # 更新尾节点 + self._size -= 1 # 更新队列长度 + return val + + def pop_first(self) -> int: + """队首出队""" + return self.pop(True) + + def pop_last(self) -> int: + """队尾出队""" + return self.pop(False) + + def peek_first(self) -> int: + """访问队首元素""" + if self.is_empty(): + raise IndexError("双向队列为空") + return self._front.val + + def peek_last(self) -> int: + """访问队尾元素""" + if self.is_empty(): + raise IndexError("双向队列为空") + return self._rear.val + + def to_array(self) -> list[int]: + """返回数组用于打印""" + node = self._front + res = [0] * self.size() + for i in range(self.size()): + res[i] = node.val + node = node.next + return res + + +"""Driver Code""" +if __name__ == "__main__": + # 初始化双向队列 + deque = LinkedListDeque() + deque.push_last(3) + deque.push_last(2) + deque.push_last(5) + print("双向队列 deque =", deque.to_array()) + + # 访问元素 + peek_first: int = deque.peek_first() + print("队首元素 peek_first =", peek_first) + peek_last: int = deque.peek_last() + print("队尾元素 peek_last =", peek_last) + + # 元素入队 + deque.push_last(4) + print("元素 4 队尾入队后 deque =", deque.to_array()) + deque.push_first(1) + print("元素 1 队首入队后 deque =", deque.to_array()) + + # 元素出队 + pop_last: int = deque.pop_last() + print("队尾出队元素 =", pop_last, ",队尾出队后 deque =", deque.to_array()) + pop_first: int = deque.pop_first() + print("队首出队元素 =", pop_first, ",队首出队后 deque =", deque.to_array()) + + # 获取双向队列的长度 + size: int = deque.size() + print("双向队列长度 size =", size) + + # 判断双向队列是否为空 + is_empty: bool = deque.is_empty() + print("双向队列是否为空 =", is_empty) diff --git a/algorithms/hello_algo/chapter05_stack_and_queue/linkedlist_queue.py b/algorithms/hello_algo/chapter05_stack_and_queue/linkedlist_queue.py new file mode 100644 index 0000000..16b6a67 --- /dev/null +++ b/algorithms/hello_algo/chapter05_stack_and_queue/linkedlist_queue.py @@ -0,0 +1,97 @@ +""" +File: linkedlist_queue.py +Created Time: 2022-12-01 +Author: Peng Chen (pengchzn@gmail.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import ListNode + + +class LinkedListQueue: + """基于链表实现的队列""" + + def __init__(self): + """构造方法""" + self._front: ListNode | None = None # 头节点 front + self._rear: ListNode | None = None # 尾节点 rear + self._size: int = 0 + + def size(self) -> int: + """获取队列的长度""" + return self._size + + def is_empty(self) -> bool: + """判断队列是否为空""" + return not self._front + + def push(self, num: int): + """入队""" + # 尾节点后添加 num + node = ListNode(num) + # 如果队列为空,则令头、尾节点都指向该节点 + if self._front is None: + self._front = node + self._rear = node + # 如果队列不为空,则将该节点添加到尾节点后 + else: + self._rear.next = node + self._rear = node + self._size += 1 + + def pop(self) -> int: + """出队""" + num = self.peek() + # 删除头节点 + self._front = self._front.next + self._size -= 1 + return num + + def peek(self) -> int: + """访问队首元素""" + if self.is_empty(): + raise IndexError("队列为空") + return self._front.val + + def to_list(self) -> list[int]: + """转化为列表用于打印""" + queue = [] + temp = self._front + while temp: + queue.append(temp.val) + temp = temp.next + return queue + + +"""Driver Code""" +if __name__ == "__main__": + # 初始化队列 + queue = LinkedListQueue() + + # 元素入队 + queue.push(1) + queue.push(3) + queue.push(2) + queue.push(5) + queue.push(4) + print("队列 queue =", queue.to_list()) + + # 访问队首元素 + peek: int = queue.peek() + print("队首元素 front =", peek) + + # 元素出队 + pop_front: int = queue.pop() + print("出队元素 pop =", pop_front) + print("出队后 queue =", queue.to_list()) + + # 获取队列的长度 + size: int = queue.size() + print("队列长度 size =", size) + + # 判断队列是否为空 + is_empty: bool = queue.is_empty() + print("队列是否为空 =", is_empty) diff --git a/algorithms/hello_algo/chapter05_stack_and_queue/linkedlist_stack.py b/algorithms/hello_algo/chapter05_stack_and_queue/linkedlist_stack.py new file mode 100644 index 0000000..5ecd9c5 --- /dev/null +++ b/algorithms/hello_algo/chapter05_stack_and_queue/linkedlist_stack.py @@ -0,0 +1,89 @@ +""" +File: linkedlist_stack.py +Created Time: 2022-11-29 +Author: Peng Chen (pengchzn@gmail.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import ListNode + + +class LinkedListStack: + """基于链表实现的栈""" + + def __init__(self): + """构造方法""" + self._peek: ListNode | None = None + self._size: int = 0 + + def size(self) -> int: + """获取栈的长度""" + return self._size + + def is_empty(self) -> bool: + """判断栈是否为空""" + return not self._peek + + def push(self, val: int): + """入栈""" + node = ListNode(val) + node.next = self._peek + self._peek = node + self._size += 1 + + def pop(self) -> int: + """出栈""" + num = self.peek() + self._peek = self._peek.next + self._size -= 1 + return num + + def peek(self) -> int: + """访问栈顶元素""" + if self.is_empty(): + raise IndexError("栈为空") + return self._peek.val + + def to_list(self) -> list[int]: + """转化为列表用于打印""" + arr = [] + node = self._peek + while node: + arr.append(node.val) + node = node.next + arr.reverse() + return arr + + +"""Driver Code""" +if __name__ == "__main__": + # 初始化栈 + stack = LinkedListStack() + + # 元素入栈 + stack.push(1) + stack.push(3) + stack.push(2) + stack.push(5) + stack.push(4) + print("栈 stack =", stack.to_list()) + + # 访问栈顶元素 + peek: int = stack.peek() + print("栈顶元素 peek =", peek) + + # 元素出栈 + pop: int = stack.pop() + print("出栈元素 pop =", pop) + print("出栈后 stack =", stack.to_list()) + + # 获取栈的长度 + size: int = stack.size() + print("栈的长度 size =", size) + + # 判断是否为空 + is_empty: bool = stack.is_empty() + print("栈是否为空 =", is_empty) diff --git a/algorithms/hello_algo/chapter05_stack_and_queue/queue.py b/algorithms/hello_algo/chapter05_stack_and_queue/queue.py new file mode 100644 index 0000000..923070f --- /dev/null +++ b/algorithms/hello_algo/chapter05_stack_and_queue/queue.py @@ -0,0 +1,39 @@ +""" +File: queue.py +Created Time: 2022-11-29 +Author: Peng Chen (pengchzn@gmail.com) +""" + +from collections import deque + +"""Driver Code""" +if __name__ == "__main__": + # 初始化队列 + # 在 Python 中,我们一般将双向队列类 deque 看作队列使用 + # 虽然 queue.Queue() 是纯正的队列类,但不太好用 + que: deque[int] = deque() + + # 元素入队 + que.append(1) + que.append(3) + que.append(2) + que.append(5) + que.append(4) + print("队列 que =", que) + + # 访问队首元素 + front: int = que[0] + print("队首元素 front =", front) + + # 元素出队 + pop: int = que.popleft() + print("出队元素 pop =", pop) + print("出队后 que =", que) + + # 获取队列的长度 + size: int = len(que) + print("队列长度 size =", size) + + # 判断队列是否为空 + is_empty: bool = len(que) == 0 + print("队列是否为空 =", is_empty) diff --git a/algorithms/hello_algo/chapter05_stack_and_queue/stack.py b/algorithms/hello_algo/chapter05_stack_and_queue/stack.py new file mode 100644 index 0000000..1276271 --- /dev/null +++ b/algorithms/hello_algo/chapter05_stack_and_queue/stack.py @@ -0,0 +1,36 @@ +""" +File: stack.py +Created Time: 2022-11-29 +Author: Peng Chen (pengchzn@gmail.com) +""" + +"""Driver Code""" +if __name__ == "__main__": + # 初始化栈 + # Python 没有内置的栈类,可以把 list 当作栈来使用 + stack: list[int] = [] + + # 元素入栈 + stack.append(1) + stack.append(3) + stack.append(2) + stack.append(5) + stack.append(4) + print("栈 stack =", stack) + + # 访问栈顶元素 + peek: int = stack[-1] + print("栈顶元素 peek =", peek) + + # 元素出栈 + pop: int = stack.pop() + print("出栈元素 pop =", pop) + print("出栈后 stack =", stack) + + # 获取栈的长度 + size: int = len(stack) + print("栈的长度 size =", size) + + # 判断是否为空 + is_empty: bool = len(stack) == 0 + print("栈是否为空 =", is_empty) diff --git a/algorithms/hello_algo/chapter06_hashing/array_hash_map.py b/algorithms/hello_algo/chapter06_hashing/array_hash_map.py new file mode 100644 index 0000000..f71f95c --- /dev/null +++ b/algorithms/hello_algo/chapter06_hashing/array_hash_map.py @@ -0,0 +1,117 @@ +""" +File: array_hash_map.py +Created Time: 2022-12-14 +Author: msk397 (machangxinq@gmail.com) +""" + + +class Pair: + """键值对""" + + def __init__(self, key: int, val: str): + self.key = key + self.val = val + + +class ArrayHashMap: + """基于数组简易实现的哈希表""" + + def __init__(self): + """构造方法""" + # 初始化数组,包含 100 个桶 + self.buckets: list[Pair | None] = [None] * 100 + + def hash_func(self, key: int) -> int: + """哈希函数""" + index = key % 100 + return index + + def get(self, key: int) -> str: + """查询操作""" + index: int = self.hash_func(key) + pair: Pair = self.buckets[index] + if pair is None: + return None + return pair.val + + def put(self, key: int, val: str): + """添加操作""" + pair = Pair(key, val) + index: int = self.hash_func(key) + self.buckets[index] = pair + + def remove(self, key: int): + """删除操作""" + index: int = self.hash_func(key) + # 置为 None ,代表删除 + self.buckets[index] = None + + def entry_set(self) -> list[Pair]: + """获取所有键值对""" + result: list[Pair] = [] + for pair in self.buckets: + if pair is not None: + result.append(pair) + return result + + def key_set(self) -> list[int]: + """获取所有键""" + result = [] + for pair in self.buckets: + if pair is not None: + result.append(pair.key) + return result + + def value_set(self) -> list[str]: + """获取所有值""" + result = [] + for pair in self.buckets: + if pair is not None: + result.append(pair.val) + return result + + def print(self): + """打印哈希表""" + for pair in self.buckets: + if pair is not None: + print(pair.key, "->", pair.val) + + +"""Driver Code""" +if __name__ == "__main__": + # 初始化哈希表 + hmap = ArrayHashMap() + + # 添加操作 + # 在哈希表中添加键值对 (key, value) + hmap.put(12836, "小哈") + hmap.put(15937, "小啰") + hmap.put(16750, "小算") + hmap.put(13276, "小法") + hmap.put(10583, "小鸭") + print("\n添加完成后,哈希表为\nKey -> Value") + hmap.print() + + # 查询操作 + # 向哈希表输入键 key ,得到值 value + name = hmap.get(15937) + print("\n输入学号 15937 ,查询到姓名 " + name) + + # 删除操作 + # 在哈希表中删除键值对 (key, value) + hmap.remove(10583) + print("\n删除 10583 后,哈希表为\nKey -> Value") + hmap.print() + + # 遍历哈希表 + print("\n遍历键值对 Key->Value") + for pair in hmap.entry_set(): + print(pair.key, "->", pair.val) + + print("\n单独遍历键 Key") + for key in hmap.key_set(): + print(key) + + print("\n单独遍历值 Value") + for val in hmap.value_set(): + print(val) diff --git a/algorithms/hello_algo/chapter06_hashing/built_in_hash.py b/algorithms/hello_algo/chapter06_hashing/built_in_hash.py new file mode 100644 index 0000000..3070bfa --- /dev/null +++ b/algorithms/hello_algo/chapter06_hashing/built_in_hash.py @@ -0,0 +1,37 @@ +""" +File: built_in_hash.py +Created Time: 2023-06-15 +Author: Krahets (krahets@163.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import ListNode + +"""Driver Code""" +if __name__ == "__main__": + num = 3 + hash_num = hash(num) + print(f"整数 {num} 的哈希值为 {hash_num}") + + bol = True + hash_bol = hash(bol) + print(f"布尔量 {bol} 的哈希值为 {hash_bol}") + + dec = 3.14159 + hash_dec = hash(dec) + print(f"小数 {dec} 的哈希值为 {hash_dec}") + + str = "Hello 算法" + hash_str = hash(str) + print(f"字符串 {str} 的哈希值为 {hash_str}") + + tup = (12836, "小哈") + hash_tup = hash(tup) + print(f"元组 {tup} 的哈希值为 {hash(hash_tup)}") + + obj = ListNode(0) + hash_obj = hash(obj) + print(f"节点对象 {obj} 的哈希值为 {hash_obj}") diff --git a/algorithms/hello_algo/chapter06_hashing/hash_map.py b/algorithms/hello_algo/chapter06_hashing/hash_map.py new file mode 100644 index 0000000..b2ca690 --- /dev/null +++ b/algorithms/hello_algo/chapter06_hashing/hash_map.py @@ -0,0 +1,50 @@ +""" +File: hash_map.py +Created Time: 2022-12-14 +Author: msk397 (machangxinq@gmail.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import print_dict + +"""Driver Code""" +if __name__ == "__main__": + # 初始化哈希表 + hmap = dict[int, str]() + + # 添加操作 + # 在哈希表中添加键值对 (key, value) + hmap[12836] = "小哈" + hmap[15937] = "小啰" + hmap[16750] = "小算" + hmap[13276] = "小法" + hmap[10583] = "小鸭" + print("\n添加完成后,哈希表为\nKey -> Value") + print_dict(hmap) + + # 查询操作 + # 向哈希表输入键 key ,得到值 value + name: str = hmap[15937] + print("\n输入学号 15937 ,查询到姓名 " + name) + + # 删除操作 + # 在哈希表中删除键值对 (key, value) + hmap.pop(10583) + print("\n删除 10583 后,哈希表为\nKey -> Value") + print_dict(hmap) + + # 遍历哈希表 + print("\n遍历键值对 Key->Value") + for key, value in hmap.items(): + print(key, "->", value) + + print("\n单独遍历键 Key") + for key in hmap.keys(): + print(key) + + print("\n单独遍历值 Value") + for val in hmap.values(): + print(val) diff --git a/algorithms/hello_algo/chapter06_hashing/hash_map_chaining.py b/algorithms/hello_algo/chapter06_hashing/hash_map_chaining.py new file mode 100644 index 0000000..733b867 --- /dev/null +++ b/algorithms/hello_algo/chapter06_hashing/hash_map_chaining.py @@ -0,0 +1,118 @@ +""" +File: hash_map_chaining.py +Created Time: 2023-06-13 +Author: Krahets (krahets@163.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.chapter06_hashing.array_hash_map import Pair + + +class HashMapChaining: + """链式地址哈希表""" + + def __init__(self): + """构造方法""" + self.size = 0 # 键值对数量 + self.capacity = 4 # 哈希表容量 + self.load_thres = 2.0 / 3.0 # 触发扩容的负载因子阈值 + self.extend_ratio = 2 # 扩容倍数 + self.buckets = [[] for _ in range(self.capacity)] # 桶数组 + + def hash_func(self, key: int) -> int: + """哈希函数""" + return key % self.capacity + + def load_factor(self) -> float: + """负载因子""" + return self.size / self.capacity + + def get(self, key: int) -> str | None: + """查询操作""" + index = self.hash_func(key) + bucket = self.buckets[index] + # 遍历桶,若找到 key 则返回对应 val + for pair in bucket: + if pair.key == key: + return pair.val + # 若未找到 key 则返回 None + return None + + def put(self, key: int, val: str): + """添加操作""" + # 当负载因子超过阈值时,执行扩容 + if self.load_factor() > self.load_thres: + self.extend() + index = self.hash_func(key) + bucket = self.buckets[index] + # 遍历桶,若遇到指定 key ,则更新对应 val 并返回 + for pair in bucket: + if pair.key == key: + pair.val = val + return + # 若无该 key ,则将键值对添加至尾部 + pair = Pair(key, val) + bucket.append(pair) + self.size += 1 + + def remove(self, key: int): + """删除操作""" + index = self.hash_func(key) + bucket = self.buckets[index] + # 遍历桶,从中删除键值对 + for pair in bucket: + if pair.key == key: + bucket.remove(pair) + self.size -= 1 + break + + def extend(self): + """扩容哈希表""" + # 暂存原哈希表 + buckets = self.buckets + # 初始化扩容后的新哈希表 + self.capacity *= self.extend_ratio + self.buckets = [[] for _ in range(self.capacity)] + self.size = 0 + # 将键值对从原哈希表搬运至新哈希表 + for bucket in buckets: + for pair in bucket: + self.put(pair.key, pair.val) + + def print(self): + """打印哈希表""" + for bucket in self.buckets: + res = [] + for pair in bucket: + res.append(str(pair.key) + " -> " + pair.val) + print(res) + + +"""Driver Code""" +if __name__ == "__main__": + # 初始化哈希表 + hashmap = HashMapChaining() + + # 添加操作 + # 在哈希表中添加键值对 (key, value) + hashmap.put(12836, "小哈") + hashmap.put(15937, "小啰") + hashmap.put(16750, "小算") + hashmap.put(13276, "小法") + hashmap.put(10583, "小鸭") + print("\n添加完成后,哈希表为\n[Key1 -> Value1, Key2 -> Value2, ...]") + hashmap.print() + + # 查询操作 + # 向哈希表输入键 key ,得到值 value + name = hashmap.get(13276) + print("\n输入学号 13276 ,查询到姓名 " + name) + + # 删除操作 + # 在哈希表中删除键值对 (key, value) + hashmap.remove(12836) + print("\n删除 12836 后,哈希表为\n[Key1 -> Value1, Key2 -> Value2, ...]") + hashmap.print() diff --git a/algorithms/hello_algo/chapter06_hashing/hash_map_open_addressing.py b/algorithms/hello_algo/chapter06_hashing/hash_map_open_addressing.py new file mode 100644 index 0000000..a08fdbe --- /dev/null +++ b/algorithms/hello_algo/chapter06_hashing/hash_map_open_addressing.py @@ -0,0 +1,138 @@ +""" +File: hash_map_open_addressing.py +Created Time: 2023-06-13 +Author: Krahets (krahets@163.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.chapter06_hashing.array_hash_map import Pair + + +class HashMapOpenAddressing: + """开放寻址哈希表""" + + def __init__(self): + """构造方法""" + self.size = 0 # 键值对数量 + self.capacity = 4 # 哈希表容量 + self.load_thres = 2.0 / 3.0 # 触发扩容的负载因子阈值 + self.extend_ratio = 2 # 扩容倍数 + self.buckets: list[Pair | None] = [None] * self.capacity # 桶数组 + self.TOMBSTONE = Pair(-1, "-1") # 删除标记 + + def hash_func(self, key: int) -> int: + """哈希函数""" + return key % self.capacity + + def load_factor(self) -> float: + """负载因子""" + return self.size / self.capacity + + def find_bucket(self, key: int) -> int: + """搜索 key 对应的桶索引""" + index = self.hash_func(key) + first_tombstone = -1 + # 线性探测,当遇到空桶时跳出 + while self.buckets[index] is not None: + # 若遇到 key ,返回对应桶索引 + if self.buckets[index].key == key: + # 若之前遇到了删除标记,则将键值对移动至该索引 + if first_tombstone != -1: + self.buckets[first_tombstone] = self.buckets[index] + self.buckets[index] = self.TOMBSTONE + return first_tombstone # 返回移动后的桶索引 + return index # 返回桶索引 + # 记录遇到的首个删除标记 + if first_tombstone == -1 and self.buckets[index] is self.TOMBSTONE: + first_tombstone = index + # 计算桶索引,越过尾部返回头部 + index = (index + 1) % self.capacity + # 若 key 不存在,则返回添加点的索引 + return index if first_tombstone == -1 else first_tombstone + + def get(self, key: int) -> str: + """查询操作""" + # 搜索 key 对应的桶索引 + index = self.find_bucket(key) + # 若找到键值对,则返回对应 val + if self.buckets[index] not in [None, self.TOMBSTONE]: + return self.buckets[index].val + # 若键值对不存在,则返回 None + return None + + def put(self, key: int, val: str): + """添加操作""" + # 当负载因子超过阈值时,执行扩容 + if self.load_factor() > self.load_thres: + self.extend() + # 搜索 key 对应的桶索引 + index = self.find_bucket(key) + # 若找到键值对,则覆盖 val 并返回 + if self.buckets[index] not in [None, self.TOMBSTONE]: + self.buckets[index].val = val + return + # 若键值对不存在,则添加该键值对 + self.buckets[index] = Pair(key, val) + self.size += 1 + + def remove(self, key: int): + """删除操作""" + # 搜索 key 对应的桶索引 + index = self.find_bucket(key) + # 若找到键值对,则用删除标记覆盖它 + if self.buckets[index] not in [None, self.TOMBSTONE]: + self.buckets[index] = self.TOMBSTONE + self.size -= 1 + + def extend(self): + """扩容哈希表""" + # 暂存原哈希表 + buckets_tmp = self.buckets + # 初始化扩容后的新哈希表 + self.capacity *= self.extend_ratio + self.buckets = [None] * self.capacity + self.size = 0 + # 将键值对从原哈希表搬运至新哈希表 + for pair in buckets_tmp: + if pair not in [None, self.TOMBSTONE]: + self.put(pair.key, pair.val) + + def print(self): + """打印哈希表""" + for pair in self.buckets: + if pair is None: + print("None") + elif pair is self.TOMBSTONE: + print("TOMBSTONE") + else: + print(pair.key, "->", pair.val) + + +"""Driver Code""" +if __name__ == "__main__": + # 初始化哈希表 + hashmap = HashMapOpenAddressing() + + # 添加操作 + # 在哈希表中添加键值对 (key, val) + hashmap.put(12836, "小哈") + hashmap.put(15937, "小啰") + hashmap.put(16750, "小算") + hashmap.put(13276, "小法") + hashmap.put(10583, "小鸭") + print("\n添加完成后,哈希表为\nKey -> Value") + hashmap.print() + + # 查询操作 + # 向哈希表输入键 key ,得到值 val + name = hashmap.get(13276) + print("\n输入学号 13276 ,查询到姓名 " + name) + + # 删除操作 + # 在哈希表中删除键值对 (key, val) + hashmap.remove(16750) + print("\n删除 16750 后,哈希表为\nKey -> Value") + hashmap.print() diff --git a/algorithms/hello_algo/chapter06_hashing/simple_hash.py b/algorithms/hello_algo/chapter06_hashing/simple_hash.py new file mode 100644 index 0000000..e63c182 --- /dev/null +++ b/algorithms/hello_algo/chapter06_hashing/simple_hash.py @@ -0,0 +1,58 @@ +""" +File: simple_hash.py +Created Time: 2023-06-15 +Author: Krahets (krahets@163.com) +""" + + +def add_hash(key: str) -> int: + """加法哈希""" + hash = 0 + modulus = 1000000007 + for c in key: + hash += ord(c) + return hash % modulus + + +def mul_hash(key: str) -> int: + """乘法哈希""" + hash = 0 + modulus = 1000000007 + for c in key: + hash = 31 * hash + ord(c) + return hash % modulus + + +def xor_hash(key: str) -> int: + """异或哈希""" + hash = 0 + modulus = 1000000007 + for c in key: + hash ^= ord(c) + return hash % modulus + + +def rot_hash(key: str) -> int: + """旋转哈希""" + hash = 0 + modulus = 1000000007 + for c in key: + hash = (hash << 4) ^ (hash >> 28) ^ ord(c) + return hash % modulus + + +"""Driver Code""" +if __name__ == "__main__": + key = "Hello 算法" + + hash = add_hash(key) + print(f"加法哈希值为 {hash}") + + hash = mul_hash(key) + print(f"乘法哈希值为 {hash}") + + hash = xor_hash(key) + print(f"异或哈希值为 {hash}") + + hash = rot_hash(key) + print(f"旋转哈希值为 {hash}") diff --git a/algorithms/hello_algo/chapter07_tree/array_binary_tree.py b/algorithms/hello_algo/chapter07_tree/array_binary_tree.py new file mode 100644 index 0000000..f20c655 --- /dev/null +++ b/algorithms/hello_algo/chapter07_tree/array_binary_tree.py @@ -0,0 +1,119 @@ +""" +File: array_binary_tree.py +Created Time: 2023-07-19 +Author: Krahets (krahets@163.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import TreeNode, list_to_tree, print_tree + + +class ArrayBinaryTree: + """数组表示下的二叉树类""" + + def __init__(self, arr: list[int | None]): + """构造方法""" + self._tree = list(arr) + + def size(self): + """节点数量""" + return len(self._tree) + + def val(self, i: int) -> int: + """获取索引为 i 节点的值""" + # 若索引越界,则返回 None ,代表空位 + if i < 0 or i >= self.size(): + return None + return self._tree[i] + + def left(self, i: int) -> int | None: + """获取索引为 i 节点的左子节点的索引""" + return 2 * i + 1 + + def right(self, i: int) -> int | None: + """获取索引为 i 节点的右子节点的索引""" + return 2 * i + 2 + + def parent(self, i: int) -> int | None: + """获取索引为 i 节点的父节点的索引""" + return (i - 1) // 2 + + def level_order(self) -> list[int]: + """层序遍历""" + self.res = [] + # 直接遍历数组 + for i in range(self.size()): + if self.val(i) is not None: + self.res.append(self.val(i)) + return self.res + + def dfs(self, i: int, order: str): + """深度优先遍历""" + if self.val(i) is None: + return + # 前序遍历 + if order == "pre": + self.res.append(self.val(i)) + self.dfs(self.left(i), order) + # 中序遍历 + if order == "in": + self.res.append(self.val(i)) + self.dfs(self.right(i), order) + # 后序遍历 + if order == "post": + self.res.append(self.val(i)) + + def pre_order(self) -> list[int]: + """前序遍历""" + self.res = [] + self.dfs(0, order="pre") + return self.res + + def in_order(self) -> list[int]: + """中序遍历""" + self.res = [] + self.dfs(0, order="in") + return self.res + + def post_order(self) -> list[int]: + """后序遍历""" + self.res = [] + self.dfs(0, order="post") + return self.res + + +"""Driver Code""" +if __name__ == "__main__": + # 初始化二叉树 + # 这里借助了一个从数组直接生成二叉树的函数 + arr = [1, 2, 3, 4, None, 6, 7, 8, 9, None, None, 12, None, None, 15] + root = list_to_tree(arr) + print("\n初始化二叉树\n") + print("二叉树的数组表示:") + print(arr) + print("二叉树的链表表示:") + print_tree(root) + + # 数组表示下的二叉树类 + abt = ArrayBinaryTree(arr) + + # 访问节点 + i = 1 + l, r, p = abt.left(i), abt.right(i), abt.parent(i) + print(f"\n当前节点的索引为 {i} ,值为 {abt.val(i)}") + print(f"其左子节点的索引为 {l} ,值为 {abt.val(l)}") + print(f"其右子节点的索引为 {r} ,值为 {abt.val(r)}") + print(f"其父节点的索引为 {p} ,值为 {abt.val(p)}") + + # 遍历树 + res = abt.level_order() + print("\n层序遍历为:", res) + res = abt.pre_order() + print("前序遍历为:", res) + res = abt.in_order() + print("中序遍历为:", res) + res = abt.post_order() + print("后序遍历为:", res) diff --git a/algorithms/hello_algo/chapter07_tree/avl_tree.py b/algorithms/hello_algo/chapter07_tree/avl_tree.py new file mode 100644 index 0000000..e1216c4 --- /dev/null +++ b/algorithms/hello_algo/chapter07_tree/avl_tree.py @@ -0,0 +1,202 @@ +""" +File: avl_tree.py +Created Time: 2022-12-20 +Author: a16su (lpluls001@gmail.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import TreeNode, print_tree + + +class AVLTree: + """AVL 树""" + + def __init__(self): + """构造方法""" + self._root = None + + def get_root(self) -> TreeNode | None: + """获取二叉树根节点""" + return self._root + + def height(self, node: TreeNode | None) -> int: + """获取节点高度""" + # 空节点高度为 -1 ,叶节点高度为 0 + if node is not None: + return node.height + return -1 + + def update_height(self, node: TreeNode | None): + """更新节点高度""" + # 节点高度等于最高子树高度 + 1 + node.height = max([self.height(node.left), self.height(node.right)]) + 1 + + def balance_factor(self, node: TreeNode | None) -> int: + """获取平衡因子""" + # 空节点平衡因子为 0 + if node is None: + return 0 + # 节点平衡因子 = 左子树高度 - 右子树高度 + return self.height(node.left) - self.height(node.right) + + def right_rotate(self, node: TreeNode | None) -> TreeNode | None: + """右旋操作""" + child = node.left + grand_child = child.right + # 以 child 为原点,将 node 向右旋转 + child.right = node + node.left = grand_child + # 更新节点高度 + self.update_height(node) + self.update_height(child) + # 返回旋转后子树的根节点 + return child + + def left_rotate(self, node: TreeNode | None) -> TreeNode | None: + """左旋操作""" + child = node.right + grand_child = child.left + # 以 child 为原点,将 node 向左旋转 + child.left = node + node.right = grand_child + # 更新节点高度 + self.update_height(node) + self.update_height(child) + # 返回旋转后子树的根节点 + return child + + def rotate(self, node: TreeNode | None) -> TreeNode | None: + """执行旋转操作,使该子树重新恢复平衡""" + # 获取节点 node 的平衡因子 + balance_factor = self.balance_factor(node) + # 左偏树 + if balance_factor > 1: + if self.balance_factor(node.left) >= 0: + # 右旋 + return self.right_rotate(node) + else: + # 先左旋后右旋 + node.left = self.left_rotate(node.left) + return self.right_rotate(node) + # 右偏树 + elif balance_factor < -1: + if self.balance_factor(node.right) <= 0: + # 左旋 + return self.left_rotate(node) + else: + # 先右旋后左旋 + node.right = self.right_rotate(node.right) + return self.left_rotate(node) + # 平衡树,无须旋转,直接返回 + return node + + def insert(self, val): + """插入节点""" + self._root = self.insert_helper(self._root, val) + + def insert_helper(self, node: TreeNode | None, val: int) -> TreeNode: + """递归插入节点(辅助方法)""" + if node is None: + return TreeNode(val) + # 1. 查找插入位置,并插入节点 + if val < node.val: + node.left = self.insert_helper(node.left, val) + elif val > node.val: + node.right = self.insert_helper(node.right, val) + else: + # 重复节点不插入,直接返回 + return node + # 更新节点高度 + self.update_height(node) + # 2. 执行旋转操作,使该子树重新恢复平衡 + return self.rotate(node) + + def remove(self, val: int): + """删除节点""" + self._root = self.remove_helper(self._root, val) + + def remove_helper(self, node: TreeNode | None, val: int) -> TreeNode | None: + """递归删除节点(辅助方法)""" + if node is None: + return None + # 1. 查找节点,并删除之 + if val < node.val: + node.left = self.remove_helper(node.left, val) + elif val > node.val: + node.right = self.remove_helper(node.right, val) + else: + if node.left is None or node.right is None: + child = node.left or node.right + # 子节点数量 = 0 ,直接删除 node 并返回 + if child is None: + return None + # 子节点数量 = 1 ,直接删除 node + else: + node = child + else: + # 子节点数量 = 2 ,则将中序遍历的下个节点删除,并用该节点替换当前节点 + temp = node.right + while temp.left is not None: + temp = temp.left + node.right = self.remove_helper(node.right, temp.val) + node.val = temp.val + # 更新节点高度 + self.update_height(node) + # 2. 执行旋转操作,使该子树重新恢复平衡 + return self.rotate(node) + + def search(self, val: int) -> TreeNode | None: + """查找节点""" + cur = self._root + # 循环查找,越过叶节点后跳出 + while cur is not None: + # 目标节点在 cur 的右子树中 + if cur.val < val: + cur = cur.right + # 目标节点在 cur 的左子树中 + elif cur.val > val: + cur = cur.left + # 找到目标节点,跳出循环 + else: + break + # 返回目标节点 + return cur + + +"""Driver Code""" +if __name__ == "__main__": + + def test_insert(tree: AVLTree, val: int): + tree.insert(val) + print("\n插入节点 {} 后,AVL 树为".format(val)) + print_tree(tree.get_root()) + + + def test_remove(tree: AVLTree, val: int): + tree.remove(val) + print("\n删除节点 {} 后,AVL 树为".format(val)) + print_tree(tree.get_root()) + + + # 初始化空 AVL 树 + avl_tree = AVLTree() + + # 插入节点 + # 请关注插入节点后,AVL 树是如何保持平衡的 + for val in [1, 2, 3, 4, 5, 8, 7, 9, 10, 6]: + test_insert(avl_tree, val) + + # 插入重复节点 + test_insert(avl_tree, 7) + + # 删除节点 + # 请关注删除节点后,AVL 树是如何保持平衡的 + test_remove(avl_tree, 8) # 删除度为 0 的节点 + test_remove(avl_tree, 5) # 删除度为 1 的节点 + test_remove(avl_tree, 4) # 删除度为 2 的节点 + + result_node = avl_tree.search(7) + print("\n查找到的节点对象为 {},节点值 = {}".format(result_node, result_node.val)) diff --git a/algorithms/hello_algo/chapter07_tree/binary_search_tree.py b/algorithms/hello_algo/chapter07_tree/binary_search_tree.py new file mode 100644 index 0000000..f6c489d --- /dev/null +++ b/algorithms/hello_algo/chapter07_tree/binary_search_tree.py @@ -0,0 +1,146 @@ +""" +File: binary_search_tree.py +Created Time: 2022-12-20 +Author: a16su (lpluls001@gmail.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import TreeNode, print_tree + + +class BinarySearchTree: + """二叉搜索树""" + + def __init__(self): + """构造方法""" + # 初始化空树 + self._root = None + + def get_root(self) -> TreeNode | None: + """获取二叉树根节点""" + return self._root + + def search(self, num: int) -> TreeNode | None: + """查找节点""" + cur = self._root + # 循环查找,越过叶节点后跳出 + while cur is not None: + # 目标节点在 cur 的右子树中 + if cur.val < num: + cur = cur.right + # 目标节点在 cur 的左子树中 + elif cur.val > num: + cur = cur.left + # 找到目标节点,跳出循环 + else: + break + return cur + + def insert(self, num: int): + """插入节点""" + # 若树为空,则初始化根节点 + if self._root is None: + self._root = TreeNode(num) + return + # 循环查找,越过叶节点后跳出 + cur, pre = self._root, None + while cur is not None: + # 找到重复节点,直接返回 + if cur.val == num: + return + pre = cur + # 插入位置在 cur 的右子树中 + if cur.val < num: + cur = cur.right + # 插入位置在 cur 的左子树中 + else: + cur = cur.left + # 插入节点 + node = TreeNode(num) + if pre.val < num: + pre.right = node + else: + pre.left = node + + def remove(self, num: int): + """删除节点""" + # 若树为空,直接提前返回 + if self._root is None: + return + # 循环查找,越过叶节点后跳出 + cur, pre = self._root, None + while cur is not None: + # 找到待删除节点,跳出循环 + if cur.val == num: + break + pre = cur + # 待删除节点在 cur 的右子树中 + if cur.val < num: + cur = cur.right + # 待删除节点在 cur 的左子树中 + else: + cur = cur.left + # 若无待删除节点,则直接返回 + if cur is None: + return + + # 子节点数量 = 0 or 1 + if cur.left is None or cur.right is None: + # 当子节点数量 = 0 / 1 时, child = null / 该子节点 + child = cur.left or cur.right + # 删除节点 cur + if cur != self._root: + if pre.left == cur: + pre.left = child + else: + pre.right = child + else: + # 若删除节点为根节点,则重新指定根节点 + self._root = child + # 子节点数量 = 2 + else: + # 获取中序遍历中 cur 的下一个节点 + tmp: TreeNode = cur.right + while tmp.left is not None: + tmp = tmp.left + # 递归删除节点 tmp + self.remove(tmp.val) + # 用 tmp 覆盖 cur + cur.val = tmp.val + + +"""Driver Code""" +if __name__ == "__main__": + # 初始化二叉搜索树 + bst = BinarySearchTree() + nums = [8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13, 15] + # 请注意,不同的插入顺序会生成不同的二叉树,该序列可以生成一个完美二叉树 + for num in nums: + bst.insert(num) + print("\n初始化的二叉树为\n") + print_tree(bst.get_root()) + + # 查找节点 + node = bst.search(7) + print("\n查找到的节点对象为: {},节点值 = {}".format(node, node.val)) + + # 插入节点 + bst.insert(16) + print("\n插入节点 16 后,二叉树为\n") + print_tree(bst.get_root()) + + # 删除节点 + bst.remove(1) + print("\n删除节点 1 后,二叉树为\n") + print_tree(bst.get_root()) + + bst.remove(2) + print("\n删除节点 2 后,二叉树为\n") + print_tree(bst.get_root()) + + bst.remove(4) + print("\n删除节点 4 后,二叉树为\n") + print_tree(bst.get_root()) diff --git a/algorithms/hello_algo/chapter07_tree/binary_tree.py b/algorithms/hello_algo/chapter07_tree/binary_tree.py new file mode 100644 index 0000000..e115fd0 --- /dev/null +++ b/algorithms/hello_algo/chapter07_tree/binary_tree.py @@ -0,0 +1,40 @@ +""" +File: binary_tree.py +Created Time: 2022-12-20 +Author: a16su (lpluls001@gmail.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import TreeNode, print_tree + +"""Driver Code""" +if __name__ == "__main__": + # 初始化二叉树 + # 初始化节点 + n1 = TreeNode(val=1) + n2 = TreeNode(val=2) + n3 = TreeNode(val=3) + n4 = TreeNode(val=4) + n5 = TreeNode(val=5) + # 构建引用指向(即指针) + n1.left = n2 + n1.right = n3 + n2.left = n4 + n2.right = n5 + print("\n初始化二叉树\n") + print_tree(n1) + + # 插入与删除节点 + P = TreeNode(0) + # 在 n1 -> n2 中间插入节点 P + n1.left = P + P.left = n2 + print("\n插入节点 P 后\n") + print_tree(n1) + # 删除节点 + n1.left = n2 + print("\n删除节点 P 后\n") + print_tree(n1) diff --git a/algorithms/hello_algo/chapter07_tree/binary_tree_bfs.py b/algorithms/hello_algo/chapter07_tree/binary_tree_bfs.py new file mode 100644 index 0000000..db4fda0 --- /dev/null +++ b/algorithms/hello_algo/chapter07_tree/binary_tree_bfs.py @@ -0,0 +1,42 @@ +""" +File: binary_tree_bfs.py +Created Time: 2022-12-20 +Author: a16su (lpluls001@gmail.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import TreeNode, list_to_tree, print_tree +from collections import deque + + +def level_order(root: TreeNode | None) -> list[int]: + """层序遍历""" + # 初始化队列,加入根节点 + queue: deque[TreeNode] = deque() + queue.append(root) + # 初始化一个列表,用于保存遍历序列 + res = [] + while queue: + node: TreeNode = queue.popleft() # 队列出队 + res.append(node.val) # 保存节点值 + if node.left is not None: + queue.append(node.left) # 左子节点入队 + if node.right is not None: + queue.append(node.right) # 右子节点入队 + return res + + +"""Driver Code""" +if __name__ == "__main__": + # 初始化二叉树 + # 这里借助了一个从数组直接生成二叉树的函数 + root: TreeNode = list_to_tree(arr=[1, 2, 3, 4, 5, 6, 7]) + print("\n初始化二叉树\n") + print_tree(root) + + # 层序遍历 + res: list[int] = level_order(root) + print("\n层序遍历的节点打印序列 = ", res) diff --git a/algorithms/hello_algo/chapter07_tree/binary_tree_dfs.py b/algorithms/hello_algo/chapter07_tree/binary_tree_dfs.py new file mode 100644 index 0000000..c2df87a --- /dev/null +++ b/algorithms/hello_algo/chapter07_tree/binary_tree_dfs.py @@ -0,0 +1,65 @@ +""" +File: binary_tree_dfs.py +Created Time: 2022-12-20 +Author: a16su (lpluls001@gmail.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import TreeNode, list_to_tree, print_tree + + +def pre_order(root: TreeNode | None): + """前序遍历""" + if root is None: + return + # 访问优先级:根节点 -> 左子树 -> 右子树 + res.append(root.val) + pre_order(root=root.left) + pre_order(root=root.right) + + +def in_order(root: TreeNode | None): + """中序遍历""" + if root is None: + return + # 访问优先级:左子树 -> 根节点 -> 右子树 + in_order(root=root.left) + res.append(root.val) + in_order(root=root.right) + + +def post_order(root: TreeNode | None): + """后序遍历""" + if root is None: + return + # 访问优先级:左子树 -> 右子树 -> 根节点 + post_order(root=root.left) + post_order(root=root.right) + res.append(root.val) + + +"""Driver Code""" +if __name__ == "__main__": + # 初始化二叉树 + # 这里借助了一个从数组直接生成二叉树的函数 + root = list_to_tree(arr=[1, 2, 3, 4, 5, 6, 7]) + print("\n初始化二叉树\n") + print_tree(root) + + # 前序遍历 + res = [] + pre_order(root) + print("\n前序遍历的节点打印序列 = ", res) + + # 中序遍历 + res.clear() + in_order(root) + print("\n中序遍历的节点打印序列 = ", res) + + # 后序遍历 + res.clear() + post_order(root) + print("\n后序遍历的节点打印序列 = ", res) diff --git a/algorithms/hello_algo/chapter08_heap/heap.py b/algorithms/hello_algo/chapter08_heap/heap.py new file mode 100644 index 0000000..1d1a5e6 --- /dev/null +++ b/algorithms/hello_algo/chapter08_heap/heap.py @@ -0,0 +1,71 @@ +""" +File: heap.py +Created Time: 2023-02-23 +Author: Krahets (krahets@163.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import print_heap + +import heapq + + +def test_push(heap: list, val: int, flag: int = 1): + heapq.heappush(heap, flag * val) # 元素入堆 + print(f"\n元素 {val} 入堆后") + print_heap([flag * val for val in heap]) + + +def test_pop(heap: list, flag: int = 1): + val = flag * heapq.heappop(heap) # 堆顶元素出堆 + print(f"\n堆顶元素 {val} 出堆后") + print_heap([flag * val for val in heap]) + + +"""Driver Code""" +if __name__ == "__main__": + # 初始化小顶堆 + min_heap, flag = [], 1 + # 初始化大顶堆 + max_heap, flag = [], -1 + + print("\n以下测试样例为大顶堆") + # Python 的 heapq 模块默认实现小顶堆 + # 考虑将“元素取负”后再入堆,这样就可以将大小关系颠倒,从而实现大顶堆 + # 在本示例中,flag = 1 时对应小顶堆,flag = -1 时对应大顶堆 + + # 元素入堆 + test_push(max_heap, 1, flag) + test_push(max_heap, 3, flag) + test_push(max_heap, 2, flag) + test_push(max_heap, 5, flag) + test_push(max_heap, 4, flag) + + # 获取堆顶元素 + peek: int = flag * max_heap[0] + print(f"\n堆顶元素为 {peek}") + + # 堆顶元素出堆 + test_pop(max_heap, flag) + test_pop(max_heap, flag) + test_pop(max_heap, flag) + test_pop(max_heap, flag) + test_pop(max_heap, flag) + + # 获取堆大小 + size: int = len(max_heap) + print(f"\n堆元素数量为 {size}") + + # 判断堆是否为空 + is_empty: bool = not max_heap + print(f"\n堆是否为空 {is_empty}") + + # 输入列表并建堆 + # 时间复杂度为 O(n) ,而非 O(nlogn) + min_heap = [1, 3, 2, 5, 4] + heapq.heapify(min_heap) + print("\n输入列表并建立小顶堆后") + print_heap(min_heap) diff --git a/algorithms/hello_algo/chapter08_heap/my_heap.py b/algorithms/hello_algo/chapter08_heap/my_heap.py new file mode 100644 index 0000000..97a79f4 --- /dev/null +++ b/algorithms/hello_algo/chapter08_heap/my_heap.py @@ -0,0 +1,137 @@ +""" +File: my_heap.py +Created Time: 2023-02-23 +Author: Krahets (krahets@163.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import print_heap + + +class MaxHeap: + """大顶堆""" + + def __init__(self, nums: list[int]): + """构造方法,根据输入列表建堆""" + # 将列表元素原封不动添加进堆 + self.max_heap = nums + # 堆化除叶节点以外的其他所有节点 + for i in range(self.parent(self.size() - 1), -1, -1): + self.sift_down(i) + + def left(self, i: int) -> int: + """获取左子节点索引""" + return 2 * i + 1 + + def right(self, i: int) -> int: + """获取右子节点索引""" + return 2 * i + 2 + + def parent(self, i: int) -> int: + """获取父节点索引""" + return (i - 1) // 2 # 向下整除 + + def swap(self, i: int, j: int): + """交换元素""" + self.max_heap[i], self.max_heap[j] = self.max_heap[j], self.max_heap[i] + + def size(self) -> int: + """获取堆大小""" + return len(self.max_heap) + + def is_empty(self) -> bool: + """判断堆是否为空""" + return self.size() == 0 + + def peek(self) -> int: + """访问堆顶元素""" + return self.max_heap[0] + + def push(self, val: int): + """元素入堆""" + # 添加节点 + self.max_heap.append(val) + # 从底至顶堆化 + self.sift_up(self.size() - 1) + + def sift_up(self, i: int): + """从节点 i 开始,从底至顶堆化""" + while True: + # 获取节点 i 的父节点 + p = self.parent(i) + # 当“越过根节点”或“节点无须修复”时,结束堆化 + if p < 0 or self.max_heap[i] <= self.max_heap[p]: + break + # 交换两节点 + self.swap(i, p) + # 循环向上堆化 + i = p + + def pop(self) -> int: + """元素出堆""" + # 判空处理 + if self.is_empty(): + raise IndexError("堆为空") + # 交换根节点与最右叶节点(即交换首元素与尾元素) + self.swap(0, self.size() - 1) + # 删除节点 + val = self.max_heap.pop() + # 从顶至底堆化 + self.sift_down(0) + # 返回堆顶元素 + return val + + def sift_down(self, i: int): + """从节点 i 开始,从顶至底堆化""" + while True: + # 判断节点 i, l, r 中值最大的节点,记为 ma + l, r, ma = self.left(i), self.right(i), i + if l < self.size() and self.max_heap[l] > self.max_heap[ma]: + ma = l + if r < self.size() and self.max_heap[r] > self.max_heap[ma]: + ma = r + # 若节点 i 最大或索引 l, r 越界,则无须继续堆化,跳出 + if ma == i: + break + # 交换两节点 + self.swap(i, ma) + # 循环向下堆化 + i = ma + + def print(self): + """打印堆(二叉树)""" + print_heap(self.max_heap) + + +"""Driver Code""" +if __name__ == "__main__": + # 初始化大顶堆 + max_heap = MaxHeap([9, 8, 6, 6, 7, 5, 2, 1, 4, 3, 6, 2]) + print("\n输入列表并建堆后") + max_heap.print() + + # 获取堆顶元素 + peek = max_heap.peek() + print(f"\n堆顶元素为 {peek}") + + # 元素入堆 + val = 7 + max_heap.push(val) + print(f"\n元素 {val} 入堆后") + max_heap.print() + + # 堆顶元素出堆 + peek = max_heap.pop() + print(f"\n堆顶元素 {peek} 出堆后") + max_heap.print() + + # 获取堆大小 + size = max_heap.size() + print(f"\n堆元素数量为 {size}") + + # 判断堆是否为空 + is_empty = max_heap.is_empty() + print(f"\n堆是否为空 {is_empty}") diff --git a/algorithms/hello_algo/chapter08_heap/top_k.py b/algorithms/hello_algo/chapter08_heap/top_k.py new file mode 100644 index 0000000..2de6220 --- /dev/null +++ b/algorithms/hello_algo/chapter08_heap/top_k.py @@ -0,0 +1,39 @@ +""" +File: top_k.py +Created Time: 2023-06-10 +Author: Krahets (krahets@163.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import print_heap + +import heapq + + +def top_k_heap(nums: list[int], k: int) -> list[int]: + """基于堆查找数组中最大的 k 个元素""" + # 初始化小顶堆 + heap = [] + # 将数组的前 k 个元素入堆 + for i in range(k): + heapq.heappush(heap, nums[i]) + # 从第 k+1 个元素开始,保持堆的长度为 k + for i in range(k, len(nums)): + # 若当前元素大于堆顶元素,则将堆顶元素出堆、当前元素入堆 + if nums[i] > heap[0]: + heapq.heappop(heap) + heapq.heappush(heap, nums[i]) + return heap + + +"""Driver Code""" +if __name__ == "__main__": + nums = [1, 7, 6, 3, 2] + k = 3 + + res = top_k_heap(nums, k) + print(f"最大的 {k} 个元素为") + print_heap(res) diff --git a/algorithms/hello_algo/chapter09_graph/graph_adjacency_list.py b/algorithms/hello_algo/chapter09_graph/graph_adjacency_list.py new file mode 100644 index 0000000..abff0b4 --- /dev/null +++ b/algorithms/hello_algo/chapter09_graph/graph_adjacency_list.py @@ -0,0 +1,111 @@ +""" +File: graph_adjacency_list.py +Created Time: 2023-02-23 +Author: Krahets (krahets@163.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import Vertex, vals_to_vets + + +class GraphAdjList: + """基于邻接表实现的无向图类""" + + def __init__(self, edges: list[list[Vertex]]): + """构造方法""" + # 邻接表,key: 顶点,value:该顶点的所有邻接顶点 + self.adj_list = dict[Vertex, list[Vertex]]() + # 添加所有顶点和边 + for edge in edges: + self.add_vertex(edge[0]) + self.add_vertex(edge[1]) + self.add_edge(edge[0], edge[1]) + + def size(self) -> int: + """获取顶点数量""" + return len(self.adj_list) + + def add_edge(self, vet1: Vertex, vet2: Vertex): + """添加边""" + if vet1 not in self.adj_list or vet2 not in self.adj_list or vet1 == vet2: + raise ValueError() + # 添加边 vet1 - vet2 + self.adj_list[vet1].append(vet2) + self.adj_list[vet2].append(vet1) + + def remove_edge(self, vet1: Vertex, vet2: Vertex): + """删除边""" + if vet1 not in self.adj_list or vet2 not in self.adj_list or vet1 == vet2: + raise ValueError() + # 删除边 vet1 - vet2 + self.adj_list[vet1].remove(vet2) + self.adj_list[vet2].remove(vet1) + + def add_vertex(self, vet: Vertex): + """添加顶点""" + if vet in self.adj_list: + return + # 在邻接表中添加一个新链表 + self.adj_list[vet] = [] + + def remove_vertex(self, vet: Vertex): + """删除顶点""" + if vet not in self.adj_list: + raise ValueError() + # 在邻接表中删除顶点 vet 对应的链表 + self.adj_list.pop(vet) + # 遍历其他顶点的链表,删除所有包含 vet 的边 + for vertex in self.adj_list: + if vet in self.adj_list[vertex]: + self.adj_list[vertex].remove(vet) + + def print(self): + """打印邻接表""" + print("邻接表 =") + for vertex in self.adj_list: + tmp = [v.val for v in self.adj_list[vertex]] + print(f"{vertex.val}: {tmp},") + + +"""Driver Code""" +if __name__ == "__main__": + # 初始化无向图 + v = vals_to_vets([1, 3, 2, 5, 4]) + edges = [ + [v[0], v[1]], + [v[0], v[3]], + [v[1], v[2]], + [v[2], v[3]], + [v[2], v[4]], + [v[3], v[4]], + ] + graph = GraphAdjList(edges) + print("\n初始化后,图为") + graph.print() + + # 添加边 + # 顶点 1, 2 即 v[0], v[2] + graph.add_edge(v[0], v[2]) + print("\n添加边 1-2 后,图为") + graph.print() + + # 删除边 + # 顶点 1, 3 即 v[0], v[1] + graph.remove_edge(v[0], v[1]) + print("\n删除边 1-3 后,图为") + graph.print() + + # 添加顶点 + v5 = Vertex(6) + graph.add_vertex(v5) + print("\n添加顶点 6 后,图为") + graph.print() + + # 删除顶点 + # 顶点 3 即 v[1] + graph.remove_vertex(v[1]) + print("\n删除顶点 3 后,图为") + graph.print() diff --git a/algorithms/hello_algo/chapter09_graph/graph_adjacency_matrix.py b/algorithms/hello_algo/chapter09_graph/graph_adjacency_matrix.py new file mode 100644 index 0000000..d2db803 --- /dev/null +++ b/algorithms/hello_algo/chapter09_graph/graph_adjacency_matrix.py @@ -0,0 +1,116 @@ +""" +File: graph_adjacency_matrix.py +Created Time: 2023-02-23 +Author: Krahets (krahets@163.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import Vertex, print_matrix + + +class GraphAdjMat: + """基于邻接矩阵实现的无向图类""" + + def __init__(self, vertices: list[int], edges: list[list[int]]): + """构造方法""" + # 顶点列表,元素代表“顶点值”,索引代表“顶点索引” + self.vertices: list[int] = [] + # 邻接矩阵,行列索引对应“顶点索引” + self.adj_mat: list[list[int]] = [] + # 添加顶点 + for val in vertices: + self.add_vertex(val) + # 添加边 + # 请注意,edges 元素代表顶点索引,即对应 vertices 元素索引 + for e in edges: + self.add_edge(e[0], e[1]) + + def size(self) -> int: + """获取顶点数量""" + return len(self.vertices) + + def add_vertex(self, val: int): + """添加顶点""" + n = self.size() + # 向顶点列表中添加新顶点的值 + self.vertices.append(val) + # 在邻接矩阵中添加一行 + new_row = [0] * n + self.adj_mat.append(new_row) + # 在邻接矩阵中添加一列 + for row in self.adj_mat: + row.append(0) + + def remove_vertex(self, index: int): + """删除顶点""" + if index >= self.size(): + raise IndexError() + # 在顶点列表中移除索引 index 的顶点 + self.vertices.pop(index) + # 在邻接矩阵中删除索引 index 的行 + self.adj_mat.pop(index) + # 在邻接矩阵中删除索引 index 的列 + for row in self.adj_mat: + row.pop(index) + + def add_edge(self, i: int, j: int): + """添加边""" + # 参数 i, j 对应 vertices 元素索引 + # 索引越界与相等处理 + if i < 0 or j < 0 or i >= self.size() or j >= self.size() or i == j: + raise IndexError() + # 在无向图中,邻接矩阵沿主对角线对称,即满足 (i, j) == (j, i) + self.adj_mat[i][j] = 1 + self.adj_mat[j][i] = 1 + + def remove_edge(self, i: int, j: int): + """删除边""" + # 参数 i, j 对应 vertices 元素索引 + # 索引越界与相等处理 + if i < 0 or j < 0 or i >= self.size() or j >= self.size() or i == j: + raise IndexError() + self.adj_mat[i][j] = 0 + self.adj_mat[j][i] = 0 + + def print(self): + """打印邻接矩阵""" + print("顶点列表 =", self.vertices) + print("邻接矩阵 =") + print_matrix(self.adj_mat) + + +"""Driver Code""" +if __name__ == "__main__": + # 初始化无向图 + # 请注意,edges 元素代表顶点索引,即对应 vertices 元素索引 + vertices = [1, 3, 2, 5, 4] + edges = [[0, 1], [0, 3], [1, 2], [2, 3], [2, 4], [3, 4]] + graph = GraphAdjMat(vertices, edges) + print("\n初始化后,图为") + graph.print() + + # 添加边 + # 顶点 1, 2 的索引分别为 0, 2 + graph.add_edge(0, 2) + print("\n添加边 1-2 后,图为") + graph.print() + + # 删除边 + # 顶点 1, 3 的索引分别为 0, 1 + graph.remove_edge(0, 1) + print("\n删除边 1-3 后,图为") + graph.print() + + # 添加顶点 + graph.add_vertex(6) + print("\n添加顶点 6 后,图为") + graph.print() + + # 删除顶点 + # 顶点 3 的索引为 1 + graph.remove_vertex(1) + print("\n删除顶点 3 后,图为") + graph.print() diff --git a/algorithms/hello_algo/chapter09_graph/graph_bfs.py b/algorithms/hello_algo/chapter09_graph/graph_bfs.py new file mode 100644 index 0000000..dffd532 --- /dev/null +++ b/algorithms/hello_algo/chapter09_graph/graph_bfs.py @@ -0,0 +1,64 @@ +""" +File: graph_bfs.py +Created Time: 2023-02-23 +Author: Krahets (krahets@163.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import Vertex, vals_to_vets, vets_to_vals +from collections import deque +from graph_adjacency_list import GraphAdjList + + +def graph_bfs(graph: GraphAdjList, start_vet: Vertex) -> list[Vertex]: + """广度优先遍历 BFS""" + # 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点 + # 顶点遍历序列 + res = [] + # 哈希表,用于记录已被访问过的顶点 + visited = set[Vertex]([start_vet]) + # 队列用于实现 BFS + que = deque[Vertex]([start_vet]) + # 以顶点 vet 为起点,循环直至访问完所有顶点 + while len(que) > 0: + vet = que.popleft() # 队首顶点出队 + res.append(vet) # 记录访问顶点 + # 遍历该顶点的所有邻接顶点 + for adj_vet in graph.adj_list[vet]: + if adj_vet in visited: + continue # 跳过已被访问过的顶点 + que.append(adj_vet) # 只入队未访问的顶点 + visited.add(adj_vet) # 标记该顶点已被访问 + # 返回顶点遍历序列 + return res + + +"""Driver Code""" +if __name__ == "__main__": + # 初始化无向图 + v = vals_to_vets([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) + edges = [ + [v[0], v[1]], + [v[0], v[3]], + [v[1], v[2]], + [v[1], v[4]], + [v[2], v[5]], + [v[3], v[4]], + [v[3], v[6]], + [v[4], v[5]], + [v[4], v[7]], + [v[5], v[8]], + [v[6], v[7]], + [v[7], v[8]], + ] + graph = GraphAdjList(edges) + print("\n初始化后,图为") + graph.print() + + # 广度优先遍历 BFS + res = graph_bfs(graph, v[0]) + print("\n广度优先遍历(BFS)顶点序列为") + print(vets_to_vals(res)) diff --git a/algorithms/hello_algo/chapter09_graph/graph_dfs.py b/algorithms/hello_algo/chapter09_graph/graph_dfs.py new file mode 100644 index 0000000..43c5f4d --- /dev/null +++ b/algorithms/hello_algo/chapter09_graph/graph_dfs.py @@ -0,0 +1,57 @@ +""" +File: graph_dfs.py +Created Time: 2023-02-23 +Author: Krahets (krahets@163.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import Vertex, vets_to_vals, vals_to_vets +from graph_adjacency_list import GraphAdjList + + +def dfs(graph: GraphAdjList, visited: set[Vertex], res: list[Vertex], vet: Vertex): + """深度优先遍历 DFS 辅助函数""" + res.append(vet) # 记录访问顶点 + visited.add(vet) # 标记该顶点已被访问 + # 遍历该顶点的所有邻接顶点 + for adjVet in graph.adj_list[vet]: + if adjVet in visited: + continue # 跳过已被访问过的顶点 + # 递归访问邻接顶点 + dfs(graph, visited, res, adjVet) + + +def graph_dfs(graph: GraphAdjList, start_vet: Vertex) -> list[Vertex]: + """深度优先遍历 DFS""" + # 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点 + # 顶点遍历序列 + res = [] + # 哈希表,用于记录已被访问过的顶点 + visited = set[Vertex]() + dfs(graph, visited, res, start_vet) + return res + + +"""Driver Code""" +if __name__ == "__main__": + # 初始化无向图 + v = vals_to_vets([0, 1, 2, 3, 4, 5, 6]) + edges = [ + [v[0], v[1]], + [v[0], v[3]], + [v[1], v[2]], + [v[2], v[5]], + [v[4], v[5]], + [v[5], v[6]], + ] + graph = GraphAdjList(edges) + print("\n初始化后,图为") + graph.print() + + # 深度优先遍历 DFS + res = graph_dfs(graph, v[0]) + print("\n深度优先遍历(DFS)顶点序列为") + print(vets_to_vals(res)) diff --git a/algorithms/hello_algo/chapter10_searching/binary_search.py b/algorithms/hello_algo/chapter10_searching/binary_search.py new file mode 100644 index 0000000..26005ab --- /dev/null +++ b/algorithms/hello_algo/chapter10_searching/binary_search.py @@ -0,0 +1,52 @@ +""" +File: binary_search.py +Created Time: 2022-11-26 +Author: timi (xisunyy@163.com) +""" + + +def binary_search(nums: list[int], target: int) -> int: + """二分查找(双闭区间)""" + # 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素 + i, j = 0, len(nums) - 1 + # 循环,当搜索区间为空时跳出(当 i > j 时为空) + while i <= j: + # 理论上 Python 的数字可以无限大(取决于内存大小),无须考虑大数越界问题 + m = (i + j) // 2 # 计算中点索引 m + if nums[m] < target: + i = m + 1 # 此情况说明 target 在区间 [m+1, j] 中 + elif nums[m] > target: + j = m - 1 # 此情况说明 target 在区间 [i, m-1] 中 + else: + return m # 找到目标元素,返回其索引 + return -1 # 未找到目标元素,返回 -1 + + +def binary_search_lcro(nums: list[int], target: int) -> int: + """二分查找(左闭右开)""" + # 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1 + i, j = 0, len(nums) + # 循环,当搜索区间为空时跳出(当 i = j 时为空) + while i < j: + m = (i + j) // 2 # 计算中点索引 m + if nums[m] < target: + i = m + 1 # 此情况说明 target 在区间 [m+1, j) 中 + elif nums[m] > target: + j = m # 此情况说明 target 在区间 [i, m) 中 + else: + return m # 找到目标元素,返回其索引 + return -1 # 未找到目标元素,返回 -1 + + +"""Driver Code""" +if __name__ == "__main__": + target = 6 + nums = [1, 3, 6, 8, 12, 15, 23, 26, 31, 35] + + # 二分查找(双闭区间) + index: int = binary_search(nums, target) + print("目标元素 6 的索引 = ", index) + + # 二分查找(左闭右开) + index: int = binary_search_lcro(nums, target) + print("目标元素 6 的索引 = ", index) diff --git a/algorithms/hello_algo/chapter10_searching/binary_search_edge.py b/algorithms/hello_algo/chapter10_searching/binary_search_edge.py new file mode 100644 index 0000000..5e4589a --- /dev/null +++ b/algorithms/hello_algo/chapter10_searching/binary_search_edge.py @@ -0,0 +1,49 @@ +""" +File: binary_search_edge.py +Created Time: 2023-08-04 +Author: Krahets (krahets@163.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from binary_search_insertion import binary_search_insertion + + +def binary_search_left_edge(nums: list[int], target: int) -> int: + """二分查找最左一个 target""" + # 等价于查找 target 的插入点 + i = binary_search_insertion(nums, target) + # 未找到 target ,返回 -1 + if i == len(nums) or nums[i] != target: + return -1 + # 找到 target ,返回索引 i + return i + + +def binary_search_right_edge(nums: list[int], target: int) -> int: + """二分查找最右一个 target""" + # 转化为查找最左一个 target + 1 + i = binary_search_insertion(nums, target + 1) + # j 指向最右一个 target ,i 指向首个大于 target 的元素 + j = i - 1 + # 未找到 target ,返回 -1 + if j == -1 or nums[j] != target: + return -1 + # 找到 target ,返回索引 j + return j + + +"""Driver Code""" +if __name__ == "__main__": + # 包含重复元素的数组 + nums = [1, 3, 6, 6, 6, 6, 6, 10, 12, 15] + print(f"\n数组 nums = {nums}") + + # 二分查找左边界和右边界 + for target in [6, 7]: + index = binary_search_left_edge(nums, target) + print(f"最左一个元素 {target} 的索引为 {index}") + index = binary_search_right_edge(nums, target) + print(f"最右一个元素 {target} 的索引为 {index}") diff --git a/algorithms/hello_algo/chapter10_searching/binary_search_insertion.py b/algorithms/hello_algo/chapter10_searching/binary_search_insertion.py new file mode 100644 index 0000000..3d0ef4d --- /dev/null +++ b/algorithms/hello_algo/chapter10_searching/binary_search_insertion.py @@ -0,0 +1,54 @@ +""" +File: binary_search_insertion.py +Created Time: 2023-08-04 +Author: Krahets (krahets@163.com) +""" + + +def binary_search_insertion_simple(nums: list[int], target: int) -> int: + """二分查找插入点(无重复元素)""" + i, j = 0, len(nums) - 1 # 初始化双闭区间 [0, n-1] + while i <= j: + m = (i + j) // 2 # 计算中点索引 m + if nums[m] < target: + i = m + 1 # target 在区间 [m+1, j] 中 + elif nums[m] > target: + j = m - 1 # target 在区间 [i, m-1] 中 + else: + return m # 找到 target ,返回插入点 m + # 未找到 target ,返回插入点 i + return i + + +def binary_search_insertion(nums: list[int], target: int) -> int: + """二分查找插入点(存在重复元素)""" + i, j = 0, len(nums) - 1 # 初始化双闭区间 [0, n-1] + while i <= j: + m = (i + j) // 2 # 计算中点索引 m + if nums[m] < target: + i = m + 1 # target 在区间 [m+1, j] 中 + elif nums[m] > target: + j = m - 1 # target 在区间 [i, m-1] 中 + else: + j = m - 1 # 首个小于 target 的元素在区间 [i, m-1] 中 + # 返回插入点 i + return i + + +"""Driver Code""" +if __name__ == "__main__": + # 无重复元素的数组 + nums = [1, 3, 6, 8, 12, 15, 23, 26, 31, 35] + print(f"\n数组 nums = {nums}") + # 二分查找插入点 + for target in [6, 9]: + index = binary_search_insertion_simple(nums, target) + print(f"元素 {target} 的插入点的索引为 {index}") + + # 包含重复元素的数组 + nums = [1, 3, 6, 6, 6, 6, 6, 10, 12, 15] + print(f"\n数组 nums = {nums}") + # 二分查找插入点 + for target in [2, 6, 20]: + index = binary_search_insertion(nums, target) + print(f"元素 {target} 的插入点的索引为 {index}") diff --git a/algorithms/hello_algo/chapter10_searching/hashing_search.py b/algorithms/hello_algo/chapter10_searching/hashing_search.py new file mode 100644 index 0000000..febc170 --- /dev/null +++ b/algorithms/hello_algo/chapter10_searching/hashing_search.py @@ -0,0 +1,51 @@ +""" +File: hashing_search.py +Created Time: 2022-11-26 +Author: timi (xisunyy@163.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import ListNode, list_to_linked_list + + +def hashing_search_array(hmap: dict[int, int], target: int) -> int: + """哈希查找(数组)""" + # 哈希表的 key: 目标元素,value: 索引 + # 若哈希表中无此 key ,返回 -1 + return hmap.get(target, -1) + + +def hashing_search_linkedlist( + hmap: dict[int, ListNode], target: int +) -> ListNode | None: + """哈希查找(链表)""" + # 哈希表的 key: 目标元素,value: 节点对象 + # 若哈希表中无此 key ,返回 None + return hmap.get(target, None) + + +"""Driver Code""" +if __name__ == "__main__": + target = 3 + + # 哈希查找(数组) + nums = [1, 5, 3, 2, 4, 7, 5, 9, 10, 8] + # 初始化哈希表 + map0 = dict[int, int]() + for i in range(len(nums)): + map0[nums[i]] = i # key: 元素,value: 索引 + index: int = hashing_search_array(map0, target) + print("目标元素 3 的索引 =", index) + + # 哈希查找(链表) + head: ListNode = list_to_linked_list(nums) + # 初始化哈希表 + map1 = dict[int, ListNode]() + while head: + map1[head.val] = head # key: 节点值,value: 节点 + head = head.next + node: ListNode = hashing_search_linkedlist(map1, target) + print("目标节点值 3 的对应节点对象为", node) diff --git a/algorithms/hello_algo/chapter10_searching/linear_search.py b/algorithms/hello_algo/chapter10_searching/linear_search.py new file mode 100644 index 0000000..8395204 --- /dev/null +++ b/algorithms/hello_algo/chapter10_searching/linear_search.py @@ -0,0 +1,45 @@ +""" +File: linear_search.py +Created Time: 2022-11-26 +Author: timi (xisunyy@163.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import ListNode, list_to_linked_list + + +def linear_search_array(nums: list[int], target: int) -> int: + """线性查找(数组)""" + # 遍历数组 + for i in range(len(nums)): + if nums[i] == target: # 找到目标元素,返回其索引 + return i + return -1 # 未找到目标元素,返回 -1 + + +def linear_search_linkedlist(head: ListNode, target: int) -> ListNode | None: + """线性查找(链表)""" + # 遍历链表 + while head: + if head.val == target: # 找到目标节点,返回之 + return head + head = head.next + return None # 未找到目标节点,返回 None + + +"""Driver Code""" +if __name__ == "__main__": + target = 3 + + # 在数组中执行线性查找 + nums = [1, 5, 3, 2, 4, 7, 5, 9, 10, 8] + index: int = linear_search_array(nums, target) + print("目标元素 3 的索引 =", index) + + # 在链表中执行线性查找 + head: ListNode = list_to_linked_list(nums) + node: ListNode | None = linear_search_linkedlist(head, target) + print("目标节点值 3 的对应节点对象为", node) diff --git a/algorithms/hello_algo/chapter10_searching/two_sum.py b/algorithms/hello_algo/chapter10_searching/two_sum.py new file mode 100644 index 0000000..994e305 --- /dev/null +++ b/algorithms/hello_algo/chapter10_searching/two_sum.py @@ -0,0 +1,42 @@ +""" +File: two_sum.py +Created Time: 2022-11-25 +Author: Krahets (krahets@163.com) +""" + + +def two_sum_brute_force(nums: list[int], target: int) -> list[int]: + """方法一:暴力枚举""" + # 两层循环,时间复杂度 O(n^2) + for i in range(len(nums) - 1): + for j in range(i + 1, len(nums)): + if nums[i] + nums[j] == target: + return [i, j] + return [] + + +def two_sum_hash_table(nums: list[int], target: int) -> list[int]: + """方法二:辅助哈希表""" + # 辅助哈希表,空间复杂度 O(n) + dic = {} + # 单层循环,时间复杂度 O(n) + for i in range(len(nums)): + if target - nums[i] in dic: + return [dic[target - nums[i]], i] + dic[nums[i]] = i + return [] + + +"""Driver Code""" +if __name__ == "__main__": + # ======= Test Case ======= + nums = [2, 7, 11, 15] + target = 13 + + # ====== Driver Code ====== + # 方法一 + res: list[int] = two_sum_brute_force(nums, target) + print("方法一 res =", res) + # 方法二 + res: list[int] = two_sum_hash_table(nums, target) + print("方法二 res =", res) diff --git a/algorithms/hello_algo/chapter11_sorting/bubble_sort.py b/algorithms/hello_algo/chapter11_sorting/bubble_sort.py new file mode 100644 index 0000000..238444e --- /dev/null +++ b/algorithms/hello_algo/chapter11_sorting/bubble_sort.py @@ -0,0 +1,44 @@ +""" +File: bubble_sort.py +Created Time: 2022-11-25 +Author: timi (xisunyy@163.com) +""" + + +def bubble_sort(nums: list[int]): + """冒泡排序""" + n = len(nums) + # 外循环:未排序区间为 [0, i] + for i in range(n - 1, 0, -1): + # 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端 + for j in range(i): + if nums[j] > nums[j + 1]: + # 交换 nums[j] 与 nums[j + 1] + nums[j], nums[j + 1] = nums[j + 1], nums[j] + + +def bubble_sort_with_flag(nums: list[int]): + """冒泡排序(标志优化)""" + n = len(nums) + # 外循环:未排序区间为 [0, i] + for i in range(n - 1, 0, -1): + flag = False # 初始化标志位 + # 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端 + for j in range(i): + if nums[j] > nums[j + 1]: + # 交换 nums[j] 与 nums[j + 1] + nums[j], nums[j + 1] = nums[j + 1], nums[j] + flag = True # 记录交换元素 + if not flag: + break # 此轮冒泡未交换任何元素,直接跳出 + + +"""Driver Code""" +if __name__ == "__main__": + nums = [4, 1, 3, 1, 5, 2] + bubble_sort(nums) + print("冒泡排序完成后 nums =", nums) + + nums1 = [4, 1, 3, 1, 5, 2] + bubble_sort_with_flag(nums1) + print("冒泡排序完成后 nums =", nums1) diff --git a/algorithms/hello_algo/chapter11_sorting/bucket_sort.py b/algorithms/hello_algo/chapter11_sorting/bucket_sort.py new file mode 100644 index 0000000..764a123 --- /dev/null +++ b/algorithms/hello_algo/chapter11_sorting/bucket_sort.py @@ -0,0 +1,35 @@ +""" +File: bucket_sort.py +Created Time: 2023-03-30 +Author: Krahets (krahets@163.com) +""" + + +def bucket_sort(nums: list[float]): + """桶排序""" + # 初始化 k = n/2 个桶,预期向每个桶分配 2 个元素 + k = len(nums) // 2 + buckets = [[] for _ in range(k)] + # 1. 将数组元素分配到各个桶中 + for num in nums: + # 输入数据范围 [0, 1),使用 num * k 映射到索引范围 [0, k-1] + i = int(num * k) + # 将 num 添加进桶 i + buckets[i].append(num) + # 2. 对各个桶执行排序 + for bucket in buckets: + # 使用内置排序函数,也可以替换成其他排序算法 + bucket.sort() + # 3. 遍历桶合并结果 + i = 0 + for bucket in buckets: + for num in bucket: + nums[i] = num + i += 1 + + +if __name__ == "__main__": + # 设输入数据为浮点数,范围为 [0, 1) + nums = [0.49, 0.96, 0.82, 0.09, 0.57, 0.43, 0.91, 0.75, 0.15, 0.37] + bucket_sort(nums) + print("桶排序完成后 nums =", nums) diff --git a/algorithms/hello_algo/chapter11_sorting/counting_sort.py b/algorithms/hello_algo/chapter11_sorting/counting_sort.py new file mode 100644 index 0000000..8f249ac --- /dev/null +++ b/algorithms/hello_algo/chapter11_sorting/counting_sort.py @@ -0,0 +1,64 @@ +""" +File: counting_sort.py +Created Time: 2023-03-21 +Author: Krahets (krahets@163.com) +""" + + +def counting_sort_naive(nums: list[int]): + """计数排序""" + # 简单实现,无法用于排序对象 + # 1. 统计数组最大元素 m + m = 0 + for num in nums: + m = max(m, num) + # 2. 统计各数字的出现次数 + # counter[num] 代表 num 的出现次数 + counter = [0] * (m + 1) + for num in nums: + counter[num] += 1 + # 3. 遍历 counter ,将各元素填入原数组 nums + i = 0 + for num in range(m + 1): + for _ in range(counter[num]): + nums[i] = num + i += 1 + + +def counting_sort(nums: list[int]): + """计数排序""" + # 完整实现,可排序对象,并且是稳定排序 + # 1. 统计数组最大元素 m + m = max(nums) + # 2. 统计各数字的出现次数 + # counter[num] 代表 num 的出现次数 + counter = [0] * (m + 1) + for num in nums: + counter[num] += 1 + # 3. 求 counter 的前缀和,将“出现次数”转换为“尾索引” + # 即 counter[num]-1 是 num 在 res 中最后一次出现的索引 + for i in range(m): + counter[i + 1] += counter[i] + # 4. 倒序遍历 nums ,将各元素填入结果数组 res + # 初始化数组 res 用于记录结果 + n = len(nums) + res = [0] * n + for i in range(n - 1, -1, -1): + num = nums[i] + res[counter[num] - 1] = num # 将 num 放置到对应索引处 + counter[num] -= 1 # 令前缀和自减 1 ,得到下次放置 num 的索引 + # 使用结果数组 res 覆盖原数组 nums + for i in range(n): + nums[i] = res[i] + + +"""Driver Code""" +if __name__ == "__main__": + nums = [1, 0, 1, 2, 0, 4, 0, 2, 2, 4] + + counting_sort_naive(nums) + print(f"计数排序(无法排序对象)完成后 nums = {nums}") + + nums1 = [1, 0, 1, 2, 0, 4, 0, 2, 2, 4] + counting_sort(nums1) + print(f"计数排序完成后 nums1 = {nums1}") diff --git a/algorithms/hello_algo/chapter11_sorting/heap_sort.py b/algorithms/hello_algo/chapter11_sorting/heap_sort.py new file mode 100644 index 0000000..405d75f --- /dev/null +++ b/algorithms/hello_algo/chapter11_sorting/heap_sort.py @@ -0,0 +1,45 @@ +""" +File: heap_sort.py +Created Time: 2023-05-24 +Author: Krahets (krahets@163.com) +""" + + +def sift_down(nums: list[int], n: int, i: int): + """堆的长度为 n ,从节点 i 开始,从顶至底堆化""" + while True: + # 判断节点 i, l, r 中值最大的节点,记为 ma + l = 2 * i + 1 + r = 2 * i + 2 + ma = i + if l < n and nums[l] > nums[ma]: + ma = l + if r < n and nums[r] > nums[ma]: + ma = r + # 若节点 i 最大或索引 l, r 越界,则无须继续堆化,跳出 + if ma == i: + break + # 交换两节点 + nums[i], nums[ma] = nums[ma], nums[i] + # 循环向下堆化 + i = ma + + +def heap_sort(nums: list[int]): + """堆排序""" + # 建堆操作:堆化除叶节点以外的其他所有节点 + for i in range(len(nums) // 2 - 1, -1, -1): + sift_down(nums, len(nums), i) + # 从堆中提取最大元素,循环 n-1 轮 + for i in range(len(nums) - 1, 0, -1): + # 交换根节点与最右叶节点(即交换首元素与尾元素) + nums[0], nums[i] = nums[i], nums[0] + # 以根节点为起点,从顶至底进行堆化 + sift_down(nums, i, 0) + + +"""Driver Code""" +if __name__ == "__main__": + nums = [4, 1, 3, 1, 5, 2] + heap_sort(nums) + print("堆排序完成后 nums =", nums) diff --git a/algorithms/hello_algo/chapter11_sorting/insertion_sort.py b/algorithms/hello_algo/chapter11_sorting/insertion_sort.py new file mode 100644 index 0000000..975dbfe --- /dev/null +++ b/algorithms/hello_algo/chapter11_sorting/insertion_sort.py @@ -0,0 +1,25 @@ +""" +File: insertion_sort.py +Created Time: 2022-11-25 +Author: timi (xisunyy@163.com) +""" + + +def insertion_sort(nums: list[int]): + """插入排序""" + # 外循环:已排序区间为 [0, i-1] + for i in range(1, len(nums)): + base = nums[i] + j = i - 1 + # 内循环:将 base 插入到已排序区间 [0, i-1] 中的正确位置 + while j >= 0 and nums[j] > base: + nums[j + 1] = nums[j] # 将 nums[j] 向右移动一位 + j -= 1 + nums[j + 1] = base # 将 base 赋值到正确位置 + + +"""Driver Code""" +if __name__ == "__main__": + nums = [4, 1, 3, 1, 5, 2] + insertion_sort(nums) + print("插入排序完成后 nums =", nums) diff --git a/algorithms/hello_algo/chapter11_sorting/merge_sort.py b/algorithms/hello_algo/chapter11_sorting/merge_sort.py new file mode 100644 index 0000000..33dc93a --- /dev/null +++ b/algorithms/hello_algo/chapter11_sorting/merge_sort.py @@ -0,0 +1,55 @@ +""" +File: merge_sort.py +Created Time: 2022-11-25 +Author: timi (xisunyy@163.com), Krahets (krahets@163.com) +""" + + +def merge(nums: list[int], left: int, mid: int, right: int): + """合并左子数组和右子数组""" + # 左子数组区间 [left, mid], 右子数组区间 [mid+1, right] + # 创建一个临时数组 tmp ,用于存放合并后的结果 + tmp = [0] * (right - left + 1) + # 初始化左子数组和右子数组的起始索引 + i, j, k = left, mid + 1, 0 + # 当左右子数组都还有元素时,比较并将较小的元素复制到临时数组中 + while i <= mid and j <= right: + if nums[i] <= nums[j]: + tmp[k] = nums[i] + i += 1 + else: + tmp[k] = nums[j] + j += 1 + k += 1 + # 将左子数组和右子数组的剩余元素复制到临时数组中 + while i <= mid: + tmp[k] = nums[i] + i += 1 + k += 1 + while j <= right: + tmp[k] = nums[j] + j += 1 + k += 1 + # 将临时数组 tmp 中的元素复制回原数组 nums 的对应区间 + for k in range(0, len(tmp)): + nums[left + k] = tmp[k] + + +def merge_sort(nums: list[int], left: int, right: int): + """归并排序""" + # 终止条件 + if left >= right: + return # 当子数组长度为 1 时终止递归 + # 划分阶段 + mid = (left + right) // 2 # 计算中点 + merge_sort(nums, left, mid) # 递归左子数组 + merge_sort(nums, mid + 1, right) # 递归右子数组 + # 合并阶段 + merge(nums, left, mid, right) + + +"""Driver Code""" +if __name__ == "__main__": + nums = [7, 3, 2, 6, 0, 1, 5, 4] + merge_sort(nums, 0, len(nums) - 1) + print("归并排序完成后 nums =", nums) diff --git a/algorithms/hello_algo/chapter11_sorting/quick_sort.py b/algorithms/hello_algo/chapter11_sorting/quick_sort.py new file mode 100644 index 0000000..9257236 --- /dev/null +++ b/algorithms/hello_algo/chapter11_sorting/quick_sort.py @@ -0,0 +1,130 @@ +""" +File: quick_sort.py +Created Time: 2022-11-25 +Author: timi (xisunyy@163.com) +""" + + +class QuickSort: + """快速排序类""" + + def partition(self, nums: list[int], left: int, right: int) -> int: + """哨兵划分""" + # 以 nums[left] 作为基准数 + i, j = left, right + while i < j: + while i < j and nums[j] >= nums[left]: + j -= 1 # 从右向左找首个小于基准数的元素 + while i < j and nums[i] <= nums[left]: + i += 1 # 从左向右找首个大于基准数的元素 + # 元素交换 + nums[i], nums[j] = nums[j], nums[i] + # 将基准数交换至两子数组的分界线 + nums[i], nums[left] = nums[left], nums[i] + return i # 返回基准数的索引 + + def quick_sort(self, nums: list[int], left: int, right: int): + """快速排序""" + # 子数组长度为 1 时终止递归 + if left >= right: + return + # 哨兵划分 + pivot = self.partition(nums, left, right) + # 递归左子数组、右子数组 + self.quick_sort(nums, left, pivot - 1) + self.quick_sort(nums, pivot + 1, right) + + +class QuickSortMedian: + """快速排序类(中位基准数优化)""" + + def median_three(self, nums: list[int], left: int, mid: int, right: int) -> int: + """选取三个元素的中位数""" + # 此处使用异或运算来简化代码 + # 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1 + if (nums[left] < nums[mid]) ^ (nums[left] < nums[right]): + return left + elif (nums[mid] < nums[left]) ^ (nums[mid] < nums[right]): + return mid + return right + + def partition(self, nums: list[int], left: int, right: int) -> int: + """哨兵划分(三数取中值)""" + # 以 nums[left] 作为基准数 + med = self.median_three(nums, left, (left + right) // 2, right) + # 将中位数交换至数组最左端 + nums[left], nums[med] = nums[med], nums[left] + # 以 nums[left] 作为基准数 + i, j = left, right + while i < j: + while i < j and nums[j] >= nums[left]: + j -= 1 # 从右向左找首个小于基准数的元素 + while i < j and nums[i] <= nums[left]: + i += 1 # 从左向右找首个大于基准数的元素 + # 元素交换 + nums[i], nums[j] = nums[j], nums[i] + # 将基准数交换至两子数组的分界线 + nums[i], nums[left] = nums[left], nums[i] + return i # 返回基准数的索引 + + def quick_sort(self, nums: list[int], left: int, right: int): + """快速排序""" + # 子数组长度为 1 时终止递归 + if left >= right: + return + # 哨兵划分 + pivot = self.partition(nums, left, right) + # 递归左子数组、右子数组 + self.quick_sort(nums, left, pivot - 1) + self.quick_sort(nums, pivot + 1, right) + + +class QuickSortTailCall: + """快速排序类(尾递归优化)""" + + def partition(self, nums: list[int], left: int, right: int) -> int: + """哨兵划分""" + # 以 nums[left] 作为基准数 + i, j = left, right + while i < j: + while i < j and nums[j] >= nums[left]: + j -= 1 # 从右向左找首个小于基准数的元素 + while i < j and nums[i] <= nums[left]: + i += 1 # 从左向右找首个大于基准数的元素 + # 元素交换 + nums[i], nums[j] = nums[j], nums[i] + # 将基准数交换至两子数组的分界线 + nums[i], nums[left] = nums[left], nums[i] + return i # 返回基准数的索引 + + def quick_sort(self, nums: list[int], left: int, right: int): + """快速排序(尾递归优化)""" + # 子数组长度为 1 时终止 + while left < right: + # 哨兵划分操作 + pivot = self.partition(nums, left, right) + # 对两个子数组中较短的那个执行快排 + if pivot - left < right - pivot: + self.quick_sort(nums, left, pivot - 1) # 递归排序左子数组 + left = pivot + 1 # 剩余未排序区间为 [pivot + 1, right] + else: + self.quick_sort(nums, pivot + 1, right) # 递归排序右子数组 + right = pivot - 1 # 剩余未排序区间为 [left, pivot - 1] + + +"""Driver Code""" +if __name__ == "__main__": + # 快速排序 + nums = [2, 4, 1, 0, 3, 5] + QuickSort().quick_sort(nums, 0, len(nums) - 1) + print("快速排序完成后 nums =", nums) + + # 快速排序(中位基准数优化) + nums1 = [2, 4, 1, 0, 3, 5] + QuickSortMedian().quick_sort(nums1, 0, len(nums1) - 1) + print("快速排序(中位基准数优化)完成后 nums =", nums1) + + # 快速排序(尾递归优化) + nums2 = [2, 4, 1, 0, 3, 5] + QuickSortTailCall().quick_sort(nums2, 0, len(nums2) - 1) + print("快速排序(尾递归优化)完成后 nums =", nums2) diff --git a/algorithms/hello_algo/chapter11_sorting/radix_sort.py b/algorithms/hello_algo/chapter11_sorting/radix_sort.py new file mode 100644 index 0000000..a3b534c --- /dev/null +++ b/algorithms/hello_algo/chapter11_sorting/radix_sort.py @@ -0,0 +1,69 @@ +""" +File: radix_sort.py +Created Time: 2023-03-26 +Author: Krahets (krahets@163.com) +""" + + +def digit(num: int, exp: int) -> int: + """获取元素 num 的第 k 位,其中 exp = 10^(k-1)""" + # 传入 exp 而非 k 可以避免在此重复执行昂贵的次方计算 + return (num // exp) % 10 + + +def counting_sort_digit(nums: list[int], exp: int): + """计数排序(根据 nums 第 k 位排序)""" + # 十进制的位范围为 0~9 ,因此需要长度为 10 的桶 + counter = [0] * 10 + n = len(nums) + # 统计 0~9 各数字的出现次数 + for i in range(n): + d = digit(nums[i], exp) # 获取 nums[i] 第 k 位,记为 d + counter[d] += 1 # 统计数字 d 的出现次数 + # 求前缀和,将“出现个数”转换为“数组索引” + for i in range(1, 10): + counter[i] += counter[i - 1] + # 倒序遍历,根据桶内统计结果,将各元素填入 res + res = [0] * n + for i in range(n - 1, -1, -1): + d = digit(nums[i], exp) + j = counter[d] - 1 # 获取 d 在数组中的索引 j + res[j] = nums[i] # 将当前元素填入索引 j + counter[d] -= 1 # 将 d 的数量减 1 + # 使用结果覆盖原数组 nums + for i in range(n): + nums[i] = res[i] + + +def radix_sort(nums: list[int]): + """基数排序""" + # 获取数组的最大元素,用于判断最大位数 + m = max(nums) + # 按照从低位到高位的顺序遍历 + exp = 1 + while exp <= m: + # 对数组元素的第 k 位执行计数排序 + # k = 1 -> exp = 1 + # k = 2 -> exp = 10 + # 即 exp = 10^(k-1) + counting_sort_digit(nums, exp) + exp *= 10 + + +"""Driver Code""" +if __name__ == "__main__": + # 基数排序 + nums = [ + 10546151, + 35663510, + 42865989, + 34862445, + 81883077, + 88906420, + 72429244, + 30524779, + 82060337, + 63832996, + ] + radix_sort(nums) + print("基数排序完成后 nums =", nums) diff --git a/algorithms/hello_algo/chapter11_sorting/selection_sort.py b/algorithms/hello_algo/chapter11_sorting/selection_sort.py new file mode 100644 index 0000000..f4f8061 --- /dev/null +++ b/algorithms/hello_algo/chapter11_sorting/selection_sort.py @@ -0,0 +1,26 @@ +""" +File: selection_sort.py +Created Time: 2023-05-22 +Author: Krahets (krahets@163.com) +""" + + +def selection_sort(nums: list[int]): + """选择排序""" + n = len(nums) + # 外循环:未排序区间为 [i, n-1] + for i in range(n - 1): + # 内循环:找到未排序区间内的最小元素 + k = i + for j in range(i + 1, n): + if nums[j] < nums[k]: + k = j # 记录最小元素的索引 + # 将该最小元素与未排序区间的首个元素交换 + nums[i], nums[k] = nums[k], nums[i] + + +"""Driver Code""" +if __name__ == "__main__": + nums = [4, 1, 3, 1, 5, 2] + selection_sort(nums) + print("选择排序完成后 nums =", nums) diff --git a/algorithms/hello_algo/chapter12_divide_and_conquer/binary_search_recur.py b/algorithms/hello_algo/chapter12_divide_and_conquer/binary_search_recur.py new file mode 100644 index 0000000..0297820 --- /dev/null +++ b/algorithms/hello_algo/chapter12_divide_and_conquer/binary_search_recur.py @@ -0,0 +1,40 @@ +""" +File: binary_search_recur.py +Created Time: 2023-07-17 +Author: krahets (krahets@163.com) +""" + + +def dfs(nums: list[int], target: int, i: int, j: int) -> int: + """二分查找:问题 f(i, j)""" + # 若区间为空,代表无目标元素,则返回 -1 + if i > j: + return -1 + # 计算中点索引 m + m = (i + j) // 2 + if nums[m] < target: + # 递归子问题 f(m+1, j) + return dfs(nums, target, m + 1, j) + elif nums[m] > target: + # 递归子问题 f(i, m-1) + return dfs(nums, target, i, m - 1) + else: + # 找到目标元素,返回其索引 + return m + + +def binary_search(nums: list[int], target: int) -> int: + """二分查找""" + n = len(nums) + # 求解问题 f(0, n-1) + return dfs(nums, target, 0, n - 1) + + +"""Driver Code""" +if __name__ == "__main__": + target = 6 + nums = [1, 3, 6, 8, 12, 15, 23, 26, 31, 35] + + # 二分查找(双闭区间) + index: int = binary_search(nums, target) + print("目标元素 6 的索引 = ", index) diff --git a/algorithms/hello_algo/chapter12_divide_and_conquer/build_tree.py b/algorithms/hello_algo/chapter12_divide_and_conquer/build_tree.py new file mode 100644 index 0000000..3ec59c3 --- /dev/null +++ b/algorithms/hello_algo/chapter12_divide_and_conquer/build_tree.py @@ -0,0 +1,54 @@ +""" +File: build_tree.py +Created Time: 2023-07-15 +Author: Krahets (krahets@163.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import TreeNode, print_tree + + +def dfs( + preorder: list[int], + inorder_map: dict[int, int], + i: int, + l: int, + r: int, +) -> TreeNode | None: + """构建二叉树:分治""" + # 子树区间为空时终止 + if r - l < 0: + return None + # 初始化根节点 + root = TreeNode(preorder[i]) + # 查询 m ,从而划分左右子树 + m = inorder_map[preorder[i]] + # 子问题:构建左子树 + root.left = dfs(preorder, inorder_map, i + 1, l, m - 1) + # 子问题:构建右子树 + root.right = dfs(preorder, inorder_map, i + 1 + m - l, m + 1, r) + # 返回根节点 + return root + + +def build_tree(preorder: list[int], inorder: list[int]) -> TreeNode | None: + """构建二叉树""" + # 初始化哈希表,存储 inorder 元素到索引的映射 + inorder_map = {val: i for i, val in enumerate(inorder)} + root = dfs(preorder, inorder_map, 0, 0, len(inorder) - 1) + return root + + +"""Driver Code""" +if __name__ == "__main__": + preorder = [3, 9, 2, 1, 7] + inorder = [9, 3, 1, 2, 7] + print(f"前序遍历 = {preorder}") + print(f"中序遍历 = {inorder}") + + root = build_tree(preorder, inorder) + print("构建的二叉树为:") + print_tree(root) diff --git a/algorithms/hello_algo/chapter12_divide_and_conquer/hanota.py b/algorithms/hello_algo/chapter12_divide_and_conquer/hanota.py new file mode 100644 index 0000000..34cfd93 --- /dev/null +++ b/algorithms/hello_algo/chapter12_divide_and_conquer/hanota.py @@ -0,0 +1,53 @@ +""" +File: hanota.py +Created Time: 2023-07-16 +Author: Krahets (krahets@163.com) +""" + + +def move(src: list[int], tar: list[int]): + """移动一个圆盘""" + # 从 src 顶部拿出一个圆盘 + pan = src.pop() + # 将圆盘放入 tar 顶部 + tar.append(pan) + + +def dfs(i: int, src: list[int], buf: list[int], tar: list[int]): + """求解汉诺塔:问题 f(i)""" + # 若 src 只剩下一个圆盘,则直接将其移到 tar + if i == 1: + move(src, tar) + return + # 子问题 f(i-1) :将 src 顶部 i-1 个圆盘借助 tar 移到 buf + dfs(i - 1, src, tar, buf) + # 子问题 f(1) :将 src 剩余一个圆盘移到 tar + move(src, tar) + # 子问题 f(i-1) :将 buf 顶部 i-1 个圆盘借助 src 移到 tar + dfs(i - 1, buf, src, tar) + + +def solve_hanota(A: list[int], B: list[int], C: list[int]): + """求解汉诺塔""" + n = len(A) + # 将 A 顶部 n 个圆盘借助 B 移到 C + dfs(n, A, B, C) + + +"""Driver Code""" +if __name__ == "__main__": + # 列表尾部是柱子顶部 + A = [5, 4, 3, 2, 1] + B = [] + C = [] + print("初始状态下:") + print(f"A = {A}") + print(f"B = {B}") + print(f"C = {C}") + + solve_hanota(A, B, C) + + print("圆盘移动完成后:") + print(f"A = {A}") + print(f"B = {B}") + print(f"C = {C}") diff --git a/algorithms/hello_algo/chapter13_backtracking/n_queens.py b/algorithms/hello_algo/chapter13_backtracking/n_queens.py new file mode 100644 index 0000000..b8b1f11 --- /dev/null +++ b/algorithms/hello_algo/chapter13_backtracking/n_queens.py @@ -0,0 +1,62 @@ +""" +File: n_queens.py +Created Time: 2023-04-26 +Author: Krahets (krahets@163.com) +""" + + +def backtrack( + row: int, + n: int, + state: list[list[str]], + res: list[list[list[str]]], + cols: list[bool], + diags1: list[bool], + diags2: list[bool], +): + """回溯算法:N 皇后""" + # 当放置完所有行时,记录解 + if row == n: + res.append([list(row) for row in state]) + return + # 遍历所有列 + for col in range(n): + # 计算该格子对应的主对角线和副对角线 + diag1 = row - col + n - 1 + diag2 = row + col + # 剪枝:不允许该格子所在列、主对角线、副对角线存在皇后 + if not cols[col] and not diags1[diag1] and not diags2[diag2]: + # 尝试:将皇后放置在该格子 + state[row][col] = "Q" + cols[col] = diags1[diag1] = diags2[diag2] = True + # 放置下一行 + backtrack(row + 1, n, state, res, cols, diags1, diags2) + # 回退:将该格子恢复为空位 + state[row][col] = "#" + cols[col] = diags1[diag1] = diags2[diag2] = False + + +def n_queens(n: int) -> list[list[list[str]]]: + """求解 N 皇后""" + # 初始化 n*n 大小的棋盘,其中 'Q' 代表皇后,'#' 代表空位 + state = [["#" for _ in range(n)] for _ in range(n)] + cols = [False] * n # 记录列是否有皇后 + diags1 = [False] * (2 * n - 1) # 记录主对角线是否有皇后 + diags2 = [False] * (2 * n - 1) # 记录副对角线是否有皇后 + res = [] + backtrack(0, n, state, res, cols, diags1, diags2) + + return res + + +"""Driver Code""" +if __name__ == "__main__": + n = 4 + res = n_queens(n) + + print(f"输入棋盘长宽为 {n}") + print(f"皇后放置方案共有 {len(res)} 种") + for state in res: + print("--------------------") + for row in state: + print(row) diff --git a/algorithms/hello_algo/chapter13_backtracking/permutations_i.py b/algorithms/hello_algo/chapter13_backtracking/permutations_i.py new file mode 100644 index 0000000..7e5d549 --- /dev/null +++ b/algorithms/hello_algo/chapter13_backtracking/permutations_i.py @@ -0,0 +1,44 @@ +""" +File: permutations_i.py +Created Time: 2023-04-15 +Author: Krahets (krahets@163.com) +""" + + +def backtrack( + state: list[int], choices: list[int], selected: list[bool], res: list[list[int]] +): + """回溯算法:全排列 I""" + # 当状态长度等于元素数量时,记录解 + if len(state) == len(choices): + res.append(list(state)) + return + # 遍历所有选择 + for i, choice in enumerate(choices): + # 剪枝:不允许重复选择元素 + if not selected[i]: + # 尝试:做出选择,更新状态 + selected[i] = True + state.append(choice) + # 进行下一轮选择 + backtrack(state, choices, selected, res) + # 回退:撤销选择,恢复到之前的状态 + selected[i] = False + state.pop() + + +def permutations_i(nums: list[int]) -> list[list[int]]: + """全排列 I""" + res = [] + backtrack(state=[], choices=nums, selected=[False] * len(nums), res=res) + return res + + +"""Driver Code""" +if __name__ == "__main__": + nums = [1, 2, 3] + + res = permutations_i(nums) + + print(f"输入数组 nums = {nums}") + print(f"所有排列 res = {res}") diff --git a/algorithms/hello_algo/chapter13_backtracking/permutations_ii.py b/algorithms/hello_algo/chapter13_backtracking/permutations_ii.py new file mode 100644 index 0000000..d01b13e --- /dev/null +++ b/algorithms/hello_algo/chapter13_backtracking/permutations_ii.py @@ -0,0 +1,44 @@ +""" +File: permutations_ii.py +Created Time: 2023-04-15 +Author: Krahets (krahets@163.com) +""" + + +def backtrack(state: list[int], choices: list[int], selected: list[bool], res: list[list[int]]): + """回溯算法:全排列 II""" + # 当状态长度等于元素数量时,记录解 + if len(state) == len(choices): + res.append(list(state)) + return + # 遍历所有选择 + duplicated = set[int]() + for i, choice in enumerate(choices): + # 剪枝:不允许重复选择元素 且 不允许重复选择相等元素 + if not selected[i] and choice not in duplicated: + # 尝试:做出选择,更新状态 + duplicated.add(choice) # 记录选择过的元素值 + selected[i] = True + state.append(choice) + # 进行下一轮选择 + backtrack(state, choices, selected, res) + # 回退:撤销选择,恢复到之前的状态 + selected[i] = False + state.pop() + + +def permutations_ii(nums: list[int]) -> list[list[int]]: + """全排列 II""" + res = [] + backtrack(state=[], choices=nums, selected=[False] * len(nums), res=res) + return res + + +"""Driver Code""" +if __name__ == "__main__": + nums = [1, 2, 2] + + res = permutations_ii(nums) + + print(f"输入数组 nums = {nums}") + print(f"所有排列 res = {res}") diff --git a/algorithms/hello_algo/chapter13_backtracking/preorder_traversal_i_compact.py b/algorithms/hello_algo/chapter13_backtracking/preorder_traversal_i_compact.py new file mode 100644 index 0000000..5ab0de2 --- /dev/null +++ b/algorithms/hello_algo/chapter13_backtracking/preorder_traversal_i_compact.py @@ -0,0 +1,36 @@ +""" +File: preorder_traversal_i_compact.py +Created Time: 2023-04-15 +Author: Krahets (krahets@163.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import TreeNode, print_tree, list_to_tree + + +def pre_order(root: TreeNode): + """前序遍历:例题一""" + if root is None: + return + if root.val == 7: + # 记录解 + res.append(root) + pre_order(root.left) + pre_order(root.right) + + +"""Driver Code""" +if __name__ == "__main__": + root = list_to_tree([1, 7, 3, 4, 5, 6, 7]) + print("\n初始化二叉树") + print_tree(root) + + # 前序遍历 + res = list[TreeNode]() + pre_order(root) + + print("\n输出所有值为 7 的节点") + print([node.val for node in res]) diff --git a/algorithms/hello_algo/chapter13_backtracking/preorder_traversal_ii_compact.py b/algorithms/hello_algo/chapter13_backtracking/preorder_traversal_ii_compact.py new file mode 100644 index 0000000..960e293 --- /dev/null +++ b/algorithms/hello_algo/chapter13_backtracking/preorder_traversal_ii_compact.py @@ -0,0 +1,42 @@ +""" +File: preorder_traversal_ii_compact.py +Created Time: 2023-04-15 +Author: Krahets (krahets@163.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import TreeNode, print_tree, list_to_tree + + +def pre_order(root: TreeNode): + """前序遍历:例题二""" + if root is None: + return + # 尝试 + path.append(root) + if root.val == 7: + # 记录解 + res.append(list(path)) + pre_order(root.left) + pre_order(root.right) + # 回退 + path.pop() + + +"""Driver Code""" +if __name__ == "__main__": + root = list_to_tree([1, 7, 3, 4, 5, 6, 7]) + print("\n初始化二叉树") + print_tree(root) + + # 前序遍历 + path = list[TreeNode]() + res = list[list[TreeNode]]() + pre_order(root) + + print("\n输出所有根节点到节点 7 的路径") + for path in res: + print([node.val for node in path]) diff --git a/algorithms/hello_algo/chapter13_backtracking/preorder_traversal_iii_compact.py b/algorithms/hello_algo/chapter13_backtracking/preorder_traversal_iii_compact.py new file mode 100644 index 0000000..d3ca381 --- /dev/null +++ b/algorithms/hello_algo/chapter13_backtracking/preorder_traversal_iii_compact.py @@ -0,0 +1,43 @@ +""" +File: preorder_traversal_iii_compact.py +Created Time: 2023-04-15 +Author: Krahets (krahets@163.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import TreeNode, print_tree, list_to_tree + + +def pre_order(root: TreeNode): + """前序遍历:例题三""" + # 剪枝 + if root is None or root.val == 3: + return + # 尝试 + path.append(root) + if root.val == 7: + # 记录解 + res.append(list(path)) + pre_order(root.left) + pre_order(root.right) + # 回退 + path.pop() + + +"""Driver Code""" +if __name__ == "__main__": + root = list_to_tree([1, 7, 3, 4, 5, 6, 7]) + print("\n初始化二叉树") + print_tree(root) + + # 前序遍历 + path = list[TreeNode]() + res = list[list[TreeNode]]() + pre_order(root) + + print("\n输出所有根节点到节点 7 的路径,路径中不包含值为 3 的节点") + for path in res: + print([node.val for node in path]) diff --git a/algorithms/hello_algo/chapter13_backtracking/preorder_traversal_iii_template.py b/algorithms/hello_algo/chapter13_backtracking/preorder_traversal_iii_template.py new file mode 100644 index 0000000..f331685 --- /dev/null +++ b/algorithms/hello_algo/chapter13_backtracking/preorder_traversal_iii_template.py @@ -0,0 +1,71 @@ +""" +File: preorder_traversal_iii_template.py +Created Time: 2023-04-15 +Author: Krahets (krahets@163.com) +""" + +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) +from algorithms.hello_algo.modules import TreeNode, print_tree, list_to_tree + + +def is_solution(state: list[TreeNode]) -> bool: + """判断当前状态是否为解""" + return state and state[-1].val == 7 + + +def record_solution(state: list[TreeNode], res: list[list[TreeNode]]): + """记录解""" + res.append(list(state)) + + +def is_valid(state: list[TreeNode], choice: TreeNode) -> bool: + """判断在当前状态下,该选择是否合法""" + return choice is not None and choice.val != 3 + + +def make_choice(state: list[TreeNode], choice: TreeNode): + """更新状态""" + state.append(choice) + + +def undo_choice(state: list[TreeNode], choice: TreeNode): + """恢复状态""" + state.pop() + + +def backtrack( + state: list[TreeNode], choices: list[TreeNode], res: list[list[TreeNode]] +): + """回溯算法:例题三""" + # 检查是否为解 + if is_solution(state): + # 记录解 + record_solution(state, res) + # 遍历所有选择 + for choice in choices: + # 剪枝:检查选择是否合法 + if is_valid(state, choice): + # 尝试:做出选择,更新状态 + make_choice(state, choice) + # 进行下一轮选择 + backtrack(state, [choice.left, choice.right], res) + # 回退:撤销选择,恢复到之前的状态 + undo_choice(state, choice) + + +"""Driver Code""" +if __name__ == "__main__": + root = list_to_tree([1, 7, 3, 4, 5, 6, 7]) + print("\n初始化二叉树") + print_tree(root) + + # 回溯算法 + res = [] + backtrack(state=[], choices=[root], res=res) + + print("\n输出所有根节点到节点 7 的路径,要求路径中不包含值为 3 的节点") + for path in res: + print([node.val for node in path]) diff --git a/algorithms/hello_algo/chapter13_backtracking/subset_sum_i.py b/algorithms/hello_algo/chapter13_backtracking/subset_sum_i.py new file mode 100644 index 0000000..af5cd1a --- /dev/null +++ b/algorithms/hello_algo/chapter13_backtracking/subset_sum_i.py @@ -0,0 +1,48 @@ +""" +File: subset_sum_i.py +Created Time: 2023-06-17 +Author: Krahets (krahets@163.com) +""" + + +def backtrack( + state: list[int], target: int, choices: list[int], start: int, res: list[list[int]] +): + """回溯算法:子集和 I""" + # 子集和等于 target 时,记录解 + if target == 0: + res.append(list(state)) + return + # 遍历所有选择 + # 剪枝二:从 start 开始遍历,避免生成重复子集 + for i in range(start, len(choices)): + # 剪枝一:若子集和超过 target ,则直接结束循环 + # 这是因为数组已排序,后边元素更大,子集和一定超过 target + if target - choices[i] < 0: + break + # 尝试:做出选择,更新 target, start + state.append(choices[i]) + # 进行下一轮选择 + backtrack(state, target - choices[i], choices, i, res) + # 回退:撤销选择,恢复到之前的状态 + state.pop() + + +def subset_sum_i(nums: list[int], target: int) -> list[list[int]]: + """求解子集和 I""" + state = [] # 状态(子集) + nums.sort() # 对 nums 进行排序 + start = 0 # 遍历起始点 + res = [] # 结果列表(子集列表) + backtrack(state, target, nums, start, res) + return res + + +"""Driver Code""" +if __name__ == "__main__": + nums = [3, 4, 5] + target = 9 + res = subset_sum_i(nums, target) + + print(f"输入数组 nums = {nums}, target = {target}") + print(f"所有和等于 {target} 的子集 res = {res}") diff --git a/algorithms/hello_algo/chapter13_backtracking/subset_sum_i_naive.py b/algorithms/hello_algo/chapter13_backtracking/subset_sum_i_naive.py new file mode 100644 index 0000000..917b877 --- /dev/null +++ b/algorithms/hello_algo/chapter13_backtracking/subset_sum_i_naive.py @@ -0,0 +1,50 @@ +""" +File: subset_sum_i_naive.py +Created Time: 2023-06-17 +Author: Krahets (krahets@163.com) +""" + + +def backtrack( + state: list[int], + target: int, + total: int, + choices: list[int], + res: list[list[int]], +): + """回溯算法:子集和 I""" + # 子集和等于 target 时,记录解 + if total == target: + res.append(list(state)) + return + # 遍历所有选择 + for i in range(len(choices)): + # 剪枝:若子集和超过 target ,则跳过该选择 + if total + choices[i] > target: + continue + # 尝试:做出选择,更新元素和 total + state.append(choices[i]) + # 进行下一轮选择 + backtrack(state, target, total + choices[i], choices, res) + # 回退:撤销选择,恢复到之前的状态 + state.pop() + + +def subset_sum_i_naive(nums: list[int], target: int) -> list[list[int]]: + """求解子集和 I(包含重复子集)""" + state = [] # 状态(子集) + total = 0 # 子集和 + res = [] # 结果列表(子集列表) + backtrack(state, target, total, nums, res) + return res + + +"""Driver Code""" +if __name__ == "__main__": + nums = [3, 4, 5] + target = 9 + res = subset_sum_i_naive(nums, target) + + print(f"输入数组 nums = {nums}, target = {target}") + print(f"所有和等于 {target} 的子集 res = {res}") + print(f"请注意,该方法输出的结果包含重复集合") diff --git a/algorithms/hello_algo/chapter13_backtracking/subset_sum_ii.py b/algorithms/hello_algo/chapter13_backtracking/subset_sum_ii.py new file mode 100644 index 0000000..40b3150 --- /dev/null +++ b/algorithms/hello_algo/chapter13_backtracking/subset_sum_ii.py @@ -0,0 +1,52 @@ +""" +File: subset_sum_ii.py +Created Time: 2023-06-17 +Author: Krahets (krahets@163.com) +""" + + +def backtrack( + state: list[int], target: int, choices: list[int], start: int, res: list[list[int]] +): + """回溯算法:子集和 II""" + # 子集和等于 target 时,记录解 + if target == 0: + res.append(list(state)) + return + # 遍历所有选择 + # 剪枝二:从 start 开始遍历,避免生成重复子集 + # 剪枝三:从 start 开始遍历,避免重复选择同一元素 + for i in range(start, len(choices)): + # 剪枝一:若子集和超过 target ,则直接结束循环 + # 这是因为数组已排序,后边元素更大,子集和一定超过 target + if target - choices[i] < 0: + break + # 剪枝四:如果该元素与左边元素相等,说明该搜索分支重复,直接跳过 + if i > start and choices[i] == choices[i - 1]: + continue + # 尝试:做出选择,更新 target, start + state.append(choices[i]) + # 进行下一轮选择 + backtrack(state, target - choices[i], choices, i + 1, res) + # 回退:撤销选择,恢复到之前的状态 + state.pop() + + +def subset_sum_ii(nums: list[int], target: int) -> list[list[int]]: + """求解子集和 II""" + state = [] # 状态(子集) + nums.sort() # 对 nums 进行排序 + start = 0 # 遍历起始点 + res = [] # 结果列表(子集列表) + backtrack(state, target, nums, start, res) + return res + + +"""Driver Code""" +if __name__ == "__main__": + nums = [4, 4, 5] + target = 9 + res = subset_sum_ii(nums, target) + + print(f"输入数组 nums = {nums}, target = {target}") + print(f"所有和等于 {target} 的子集 res = {res}") diff --git a/algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_backtrack.py b/algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_backtrack.py new file mode 100644 index 0000000..962df85 --- /dev/null +++ b/algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_backtrack.py @@ -0,0 +1,37 @@ +""" +File: climbing_stairs_backtrack.py +Created Time: 2023-06-30 +Author: Krahets (krahets@163.com) +""" + + +def backtrack(choices: list[int], state: int, n: int, res: list[int]) -> int: + """回溯""" + # 当爬到第 n 阶时,方案数量加 1 + if state == n: + res[0] += 1 + # 遍历所有选择 + for choice in choices: + # 剪枝:不允许越过第 n 阶 + if state + choice > n: + break + # 尝试:做出选择,更新状态 + backtrack(choices, state + choice, n, res) + # 回退 + + +def climbing_stairs_backtrack(n: int) -> int: + """爬楼梯:回溯""" + choices = [1, 2] # 可选择向上爬 1 或 2 阶 + state = 0 # 从第 0 阶开始爬 + res = [0] # 使用 res[0] 记录方案数量 + backtrack(choices, state, n, res) + return res[0] + + +"""Driver Code""" +if __name__ == "__main__": + n = 9 + + res = climbing_stairs_backtrack(n) + print(f"爬 {n} 阶楼梯共有 {res} 种方案") diff --git a/algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_constraint_dp.py b/algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_constraint_dp.py new file mode 100644 index 0000000..4c20d79 --- /dev/null +++ b/algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_constraint_dp.py @@ -0,0 +1,29 @@ +""" +File: climbing_stairs_constraint_dp.py +Created Time: 2023-06-30 +Author: Krahets (krahets@163.com) +""" + + +def climbing_stairs_constraint_dp(n: int) -> int: + """带约束爬楼梯:动态规划""" + if n == 1 or n == 2: + return 1 + # 初始化 dp 表,用于存储子问题的解 + dp = [[0] * 3 for _ in range(n + 1)] + # 初始状态:预设最小子问题的解 + dp[1][1], dp[1][2] = 1, 0 + dp[2][1], dp[2][2] = 0, 1 + # 状态转移:从较小子问题逐步求解较大子问题 + for i in range(3, n + 1): + dp[i][1] = dp[i - 1][2] + dp[i][2] = dp[i - 2][1] + dp[i - 2][2] + return dp[n][1] + dp[n][2] + + +"""Driver Code""" +if __name__ == "__main__": + n = 9 + + res = climbing_stairs_constraint_dp(n) + print(f"爬 {n} 阶楼梯共有 {res} 种方案") diff --git a/algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_dfs.py b/algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_dfs.py new file mode 100644 index 0000000..5e93699 --- /dev/null +++ b/algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_dfs.py @@ -0,0 +1,28 @@ +""" +File: climbing_stairs_dfs.py +Created Time: 2023-06-30 +Author: Krahets (krahets@163.com) +""" + + +def dfs(i: int) -> int: + """搜索""" + # 已知 dp[1] 和 dp[2] ,返回之 + if i == 1 or i == 2: + return i + # dp[i] = dp[i-1] + dp[i-2] + count = dfs(i - 1) + dfs(i - 2) + return count + + +def climbing_stairs_dfs(n: int) -> int: + """爬楼梯:搜索""" + return dfs(n) + + +"""Driver Code""" +if __name__ == "__main__": + n = 9 + + res = climbing_stairs_dfs(n) + print(f"爬 {n} 阶楼梯共有 {res} 种方案") diff --git a/algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_dfs_mem.py b/algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_dfs_mem.py new file mode 100644 index 0000000..6ee8836 --- /dev/null +++ b/algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_dfs_mem.py @@ -0,0 +1,35 @@ +""" +File: climbing_stairs_dfs_mem.py +Created Time: 2023-06-30 +Author: Krahets (krahets@163.com) +""" + + +def dfs(i: int, mem: list[int]) -> int: + """记忆化搜索""" + # 已知 dp[1] 和 dp[2] ,返回之 + if i == 1 or i == 2: + return i + # 若存在记录 dp[i] ,则直接返回之 + if mem[i] != -1: + return mem[i] + # dp[i] = dp[i-1] + dp[i-2] + count = dfs(i - 1, mem) + dfs(i - 2, mem) + # 记录 dp[i] + mem[i] = count + return count + + +def climbing_stairs_dfs_mem(n: int) -> int: + """爬楼梯:记忆化搜索""" + # mem[i] 记录爬到第 i 阶的方案总数,-1 代表无记录 + mem = [-1] * (n + 1) + return dfs(n, mem) + + +"""Driver Code""" +if __name__ == "__main__": + n = 9 + + res = climbing_stairs_dfs_mem(n) + print(f"爬 {n} 阶楼梯共有 {res} 种方案") diff --git a/algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_dp.py b/algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_dp.py new file mode 100644 index 0000000..e1f274d --- /dev/null +++ b/algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_dp.py @@ -0,0 +1,40 @@ +""" +File: climbing_stairs_dp.py +Created Time: 2023-06-30 +Author: Krahets (krahets@163.com) +""" + + +def climbing_stairs_dp(n: int) -> int: + """爬楼梯:动态规划""" + if n == 1 or n == 2: + return n + # 初始化 dp 表,用于存储子问题的解 + dp = [0] * (n + 1) + # 初始状态:预设最小子问题的解 + dp[1], dp[2] = 1, 2 + # 状态转移:从较小子问题逐步求解较大子问题 + for i in range(3, n + 1): + dp[i] = dp[i - 1] + dp[i - 2] + return dp[n] + + +def climbing_stairs_dp_comp(n: int) -> int: + """爬楼梯:空间优化后的动态规划""" + if n == 1 or n == 2: + return n + a, b = 1, 2 + for _ in range(3, n + 1): + a, b = b, a + b + return b + + +"""Driver Code""" +if __name__ == "__main__": + n = 9 + + res = climbing_stairs_dp(n) + print(f"爬 {n} 阶楼梯共有 {res} 种方案") + + res = climbing_stairs_dp_comp(n) + print(f"爬 {n} 阶楼梯共有 {res} 种方案") diff --git a/algorithms/hello_algo/chapter14_dynamic_programming/coin_change.py b/algorithms/hello_algo/chapter14_dynamic_programming/coin_change.py new file mode 100644 index 0000000..2aef95b --- /dev/null +++ b/algorithms/hello_algo/chapter14_dynamic_programming/coin_change.py @@ -0,0 +1,60 @@ +""" +File: coin_change.py +Created Time: 2023-07-10 +Author: Krahets (krahets@163.com) +""" + + +def coin_change_dp(coins: list[int], amt: int) -> int: + """零钱兑换:动态规划""" + n = len(coins) + MAX = amt + 1 + # 初始化 dp 表 + dp = [[0] * (amt + 1) for _ in range(n + 1)] + # 状态转移:首行首列 + for a in range(1, amt + 1): + dp[0][a] = MAX + # 状态转移:其余行列 + for i in range(1, n + 1): + for a in range(1, amt + 1): + if coins[i - 1] > a: + # 若超过背包容量,则不选硬币 i + dp[i][a] = dp[i - 1][a] + else: + # 不选和选硬币 i 这两种方案的较小值 + dp[i][a] = min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1) + return dp[n][amt] if dp[n][amt] != MAX else -1 + + +def coin_change_dp_comp(coins: list[int], amt: int) -> int: + """零钱兑换:空间优化后的动态规划""" + n = len(coins) + MAX = amt + 1 + # 初始化 dp 表 + dp = [MAX] * (amt + 1) + dp[0] = 0 + # 状态转移 + for i in range(1, n + 1): + # 正序遍历 + for a in range(1, amt + 1): + if coins[i - 1] > a: + # 若超过背包容量,则不选硬币 i + dp[a] = dp[a] + else: + # 不选和选硬币 i 这两种方案的较小值 + dp[a] = min(dp[a], dp[a - coins[i - 1]] + 1) + return dp[amt] if dp[amt] != MAX else -1 + + +"""Driver Code""" +if __name__ == "__main__": + coins = [1, 2, 5] + amt = 4 + + # 动态规划 + res = coin_change_dp(coins, amt) + print(f"凑到目标金额所需的最少硬币数量为 {res}") + + # 空间优化后的动态规划 + res = coin_change_dp_comp(coins, amt) + print(f"凑到目标金额所需的最少硬币数量为 {res}") diff --git a/algorithms/hello_algo/chapter14_dynamic_programming/coin_change_ii.py b/algorithms/hello_algo/chapter14_dynamic_programming/coin_change_ii.py new file mode 100644 index 0000000..abc3230 --- /dev/null +++ b/algorithms/hello_algo/chapter14_dynamic_programming/coin_change_ii.py @@ -0,0 +1,59 @@ +""" +File: coin_change_ii.py +Created Time: 2023-07-10 +Author: Krahets (krahets@163.com) +""" + + +def coin_change_ii_dp(coins: list[int], amt: int) -> int: + """零钱兑换 II:动态规划""" + n = len(coins) + # 初始化 dp 表 + dp = [[0] * (amt + 1) for _ in range(n + 1)] + # 初始化首列 + for i in range(n + 1): + dp[i][0] = 1 + # 状态转移 + for i in range(1, n + 1): + for a in range(1, amt + 1): + if coins[i - 1] > a: + # 若超过背包容量,则不选硬币 i + dp[i][a] = dp[i - 1][a] + else: + # 不选和选硬币 i 这两种方案之和 + dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]] + return dp[n][amt] + + +def coin_change_ii_dp_comp(coins: list[int], amt: int) -> int: + """零钱兑换 II:空间优化后的动态规划""" + n = len(coins) + # 初始化 dp 表 + dp = [0] * (amt + 1) + dp[0] = 1 + # 状态转移 + for i in range(1, n + 1): + # 正序遍历 + for a in range(1, amt + 1): + if coins[i - 1] > a: + # 若超过背包容量,则不选硬币 i + dp[a] = dp[a] + else: + # 不选和选硬币 i 这两种方案之和 + dp[a] = dp[a] + dp[a - coins[i - 1]] + return dp[amt] + + +"""Driver Code""" +if __name__ == "__main__": + coins = [1, 2, 5] + amt = 5 + n = len(coins) + + # 动态规划 + res = coin_change_ii_dp(coins, amt) + print(f"凑出目标金额的硬币组合数量为 {res}") + + # 空间优化后的动态规划 + res = coin_change_ii_dp_comp(coins, amt) + print(f"凑出目标金额的硬币组合数量为 {res}") diff --git a/algorithms/hello_algo/chapter14_dynamic_programming/edit_distance.py b/algorithms/hello_algo/chapter14_dynamic_programming/edit_distance.py new file mode 100644 index 0000000..1b405fe --- /dev/null +++ b/algorithms/hello_algo/chapter14_dynamic_programming/edit_distance.py @@ -0,0 +1,123 @@ +""" +File: edit_distancde.py +Created Time: 2023-07-04 +Author: Krahets (krahets@163.com) +""" + + +def edit_distance_dfs(s: str, t: str, i: int, j: int) -> int: + """编辑距离:暴力搜索""" + # 若 s 和 t 都为空,则返回 0 + if i == 0 and j == 0: + return 0 + # 若 s 为空,则返回 t 长度 + if i == 0: + return j + # 若 t 为空,则返回 s 长度 + if j == 0: + return i + # 若两字符相等,则直接跳过此两字符 + if s[i - 1] == t[j - 1]: + return edit_distance_dfs(s, t, i - 1, j - 1) + # 最少编辑步数 = 插入、删除、替换这三种操作的最少编辑步数 + 1 + insert = edit_distance_dfs(s, t, i, j - 1) + delete = edit_distance_dfs(s, t, i - 1, j) + replace = edit_distance_dfs(s, t, i - 1, j - 1) + # 返回最少编辑步数 + return min(insert, delete, replace) + 1 + + +def edit_distance_dfs_mem(s: str, t: str, mem: list[list[int]], i: int, j: int) -> int: + """编辑距离:记忆化搜索""" + # 若 s 和 t 都为空,则返回 0 + if i == 0 and j == 0: + return 0 + # 若 s 为空,则返回 t 长度 + if i == 0: + return j + # 若 t 为空,则返回 s 长度 + if j == 0: + return i + # 若已有记录,则直接返回之 + if mem[i][j] != -1: + return mem[i][j] + # 若两字符相等,则直接跳过此两字符 + if s[i - 1] == t[j - 1]: + return edit_distance_dfs_mem(s, t, mem, i - 1, j - 1) + # 最少编辑步数 = 插入、删除、替换这三种操作的最少编辑步数 + 1 + insert = edit_distance_dfs_mem(s, t, mem, i, j - 1) + delete = edit_distance_dfs_mem(s, t, mem, i - 1, j) + replace = edit_distance_dfs_mem(s, t, mem, i - 1, j - 1) + # 记录并返回最少编辑步数 + mem[i][j] = min(insert, delete, replace) + 1 + return mem[i][j] + + +def edit_distance_dp(s: str, t: str) -> int: + """编辑距离:动态规划""" + n, m = len(s), len(t) + dp = [[0] * (m + 1) for _ in range(n + 1)] + # 状态转移:首行首列 + for i in range(1, n + 1): + dp[i][0] = i + for j in range(1, m + 1): + dp[0][j] = j + # 状态转移:其余行列 + for i in range(1, n + 1): + for j in range(1, m + 1): + if s[i - 1] == t[j - 1]: + # 若两字符相等,则直接跳过此两字符 + dp[i][j] = dp[i - 1][j - 1] + else: + # 最少编辑步数 = 插入、删除、替换这三种操作的最少编辑步数 + 1 + dp[i][j] = min(dp[i][j - 1], dp[i - 1][j], dp[i - 1][j - 1]) + 1 + return dp[n][m] + + +def edit_distance_dp_comp(s: str, t: str) -> int: + """编辑距离:空间优化后的动态规划""" + n, m = len(s), len(t) + dp = [0] * (m + 1) + # 状态转移:首行 + for j in range(1, m + 1): + dp[j] = j + # 状态转移:其余行 + for i in range(1, n + 1): + # 状态转移:首列 + leftup = dp[0] # 暂存 dp[i-1, j-1] + dp[0] += 1 + # 状态转移:其余列 + for j in range(1, m + 1): + temp = dp[j] + if s[i - 1] == t[j - 1]: + # 若两字符相等,则直接跳过此两字符 + dp[j] = leftup + else: + # 最少编辑步数 = 插入、删除、替换这三种操作的最少编辑步数 + 1 + dp[j] = min(dp[j - 1], dp[j], leftup) + 1 + leftup = temp # 更新为下一轮的 dp[i-1, j-1] + return dp[m] + + +"""Driver Code""" +if __name__ == "__main__": + s = "bag" + t = "pack" + n, m = len(s), len(t) + + # 暴力搜索 + res = edit_distance_dfs(s, t, n, m) + print(f"将 {s} 更改为 {t} 最少需要编辑 {res} 步") + + # 记忆化搜索 + mem = [[-1] * (m + 1) for _ in range(n + 1)] + res = edit_distance_dfs_mem(s, t, mem, n, m) + print(f"将 {s} 更改为 {t} 最少需要编辑 {res} 步") + + # 动态规划 + res = edit_distance_dp(s, t) + print(f"将 {s} 更改为 {t} 最少需要编辑 {res} 步") + + # 空间优化后的动态规划 + res = edit_distance_dp_comp(s, t) + print(f"将 {s} 更改为 {t} 最少需要编辑 {res} 步") diff --git a/algorithms/hello_algo/chapter14_dynamic_programming/knapsack.py b/algorithms/hello_algo/chapter14_dynamic_programming/knapsack.py new file mode 100644 index 0000000..2dd2d35 --- /dev/null +++ b/algorithms/hello_algo/chapter14_dynamic_programming/knapsack.py @@ -0,0 +1,101 @@ +""" +File: knapsack.py +Created Time: 2023-07-03 +Author: Krahets (krahets@163.com) +""" + + +def knapsack_dfs(wgt: list[int], val: list[int], i: int, c: int) -> int: + """0-1 背包:暴力搜索""" + # 若已选完所有物品或背包无容量,则返回价值 0 + if i == 0 or c == 0: + return 0 + # 若超过背包容量,则只能不放入背包 + if wgt[i - 1] > c: + return knapsack_dfs(wgt, val, i - 1, c) + # 计算不放入和放入物品 i 的最大价值 + no = knapsack_dfs(wgt, val, i - 1, c) + yes = knapsack_dfs(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1] + # 返回两种方案中价值更大的那一个 + return max(no, yes) + + +def knapsack_dfs_mem( + wgt: list[int], val: list[int], mem: list[list[int]], i: int, c: int +) -> int: + """0-1 背包:记忆化搜索""" + # 若已选完所有物品或背包无容量,则返回价值 0 + if i == 0 or c == 0: + return 0 + # 若已有记录,则直接返回 + if mem[i][c] != -1: + return mem[i][c] + # 若超过背包容量,则只能不放入背包 + if wgt[i - 1] > c: + return knapsack_dfs_mem(wgt, val, mem, i - 1, c) + # 计算不放入和放入物品 i 的最大价值 + no = knapsack_dfs_mem(wgt, val, mem, i - 1, c) + yes = knapsack_dfs_mem(wgt, val, mem, i - 1, c - wgt[i - 1]) + val[i - 1] + # 记录并返回两种方案中价值更大的那一个 + mem[i][c] = max(no, yes) + return mem[i][c] + + +def knapsack_dp(wgt: list[int], val: list[int], cap: int) -> int: + """0-1 背包:动态规划""" + n = len(wgt) + # 初始化 dp 表 + dp = [[0] * (cap + 1) for _ in range(n + 1)] + # 状态转移 + for i in range(1, n + 1): + for c in range(1, cap + 1): + if wgt[i - 1] > c: + # 若超过背包容量,则不选物品 i + dp[i][c] = dp[i - 1][c] + else: + # 不选和选物品 i 这两种方案的较大值 + dp[i][c] = max(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + val[i - 1]) + return dp[n][cap] + + +def knapsack_dp_comp(wgt: list[int], val: list[int], cap: int) -> int: + """0-1 背包:空间优化后的动态规划""" + n = len(wgt) + # 初始化 dp 表 + dp = [0] * (cap + 1) + # 状态转移 + for i in range(1, n + 1): + # 倒序遍历 + for c in range(cap, 0, -1): + if wgt[i - 1] > c: + # 若超过背包容量,则不选物品 i + dp[c] = dp[c] + else: + # 不选和选物品 i 这两种方案的较大值 + dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]) + return dp[cap] + + +"""Driver Code""" +if __name__ == "__main__": + wgt = [10, 20, 30, 40, 50] + val = [50, 120, 150, 210, 240] + cap = 50 + n = len(wgt) + + # 暴力搜索 + res = knapsack_dfs(wgt, val, n, cap) + print(f"不超过背包容量的最大物品价值为 {res}") + + # 记忆化搜索 + mem = [[-1] * (cap + 1) for _ in range(n + 1)] + res = knapsack_dfs_mem(wgt, val, mem, n, cap) + print(f"不超过背包容量的最大物品价值为 {res}") + + # 动态规划 + res = knapsack_dp(wgt, val, cap) + print(f"不超过背包容量的最大物品价值为 {res}") + + # 空间优化后的动态规划 + res = knapsack_dp_comp(wgt, val, cap) + print(f"不超过背包容量的最大物品价值为 {res}") diff --git a/algorithms/hello_algo/chapter14_dynamic_programming/min_cost_climbing_stairs_dp.py b/algorithms/hello_algo/chapter14_dynamic_programming/min_cost_climbing_stairs_dp.py new file mode 100644 index 0000000..2e27481 --- /dev/null +++ b/algorithms/hello_algo/chapter14_dynamic_programming/min_cost_climbing_stairs_dp.py @@ -0,0 +1,43 @@ +""" +File: min_cost_climbing_stairs_dp.py +Created Time: 2023-06-30 +Author: Krahets (krahets@163.com) +""" + + +def min_cost_climbing_stairs_dp(cost: list[int]) -> int: + """爬楼梯最小代价:动态规划""" + n = len(cost) - 1 + if n == 1 or n == 2: + return cost[n] + # 初始化 dp 表,用于存储子问题的解 + dp = [0] * (n + 1) + # 初始状态:预设最小子问题的解 + dp[1], dp[2] = cost[1], cost[2] + # 状态转移:从较小子问题逐步求解较大子问题 + for i in range(3, n + 1): + dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i] + return dp[n] + + +def min_cost_climbing_stairs_dp_comp(cost: list[int]) -> int: + """爬楼梯最小代价:空间优化后的动态规划""" + n = len(cost) - 1 + if n == 1 or n == 2: + return cost[n] + a, b = cost[1], cost[2] + for i in range(3, n + 1): + a, b = b, min(a, b) + cost[i] + return b + + +"""Driver Code""" +if __name__ == "__main__": + cost = [0, 1, 10, 1, 1, 1, 10, 1, 1, 10, 1] + print(f"输入楼梯的代价列表为 {cost}") + + res = min_cost_climbing_stairs_dp(cost) + print(f"爬完楼梯的最低代价为 {res}") + + res = min_cost_climbing_stairs_dp_comp(cost) + print(f"爬完楼梯的最低代价为 {res}") diff --git a/algorithms/hello_algo/chapter14_dynamic_programming/min_path_sum.py b/algorithms/hello_algo/chapter14_dynamic_programming/min_path_sum.py new file mode 100644 index 0000000..5192c84 --- /dev/null +++ b/algorithms/hello_algo/chapter14_dynamic_programming/min_path_sum.py @@ -0,0 +1,104 @@ +""" +File: min_path_sum.py +Created Time: 2023-07-04 +Author: Krahets (krahets@163.com) +""" + +from math import inf + + +def min_path_sum_dfs(grid: list[list[int]], i: int, j: int) -> int: + """最小路径和:暴力搜索""" + # 若为左上角单元格,则终止搜索 + if i == 0 and j == 0: + return grid[0][0] + # 若行列索引越界,则返回 +∞ 代价 + if i < 0 or j < 0: + return inf + # 计算从左上角到 (i-1, j) 和 (i, j-1) 的最小路径代价 + up = min_path_sum_dfs(grid, i - 1, j) + left = min_path_sum_dfs(grid, i, j - 1) + # 返回从左上角到 (i, j) 的最小路径代价 + return min(left, up) + grid[i][j] + + +def min_path_sum_dfs_mem( + grid: list[list[int]], mem: list[list[int]], i: int, j: int +) -> int: + """最小路径和:记忆化搜索""" + # 若为左上角单元格,则终止搜索 + if i == 0 and j == 0: + return grid[0][0] + # 若行列索引越界,则返回 +∞ 代价 + if i < 0 or j < 0: + return inf + # 若已有记录,则直接返回 + if mem[i][j] != -1: + return mem[i][j] + # 左边和上边单元格的最小路径代价 + up = min_path_sum_dfs_mem(grid, mem, i - 1, j) + left = min_path_sum_dfs_mem(grid, mem, i, j - 1) + # 记录并返回左上角到 (i, j) 的最小路径代价 + mem[i][j] = min(left, up) + grid[i][j] + return mem[i][j] + + +def min_path_sum_dp(grid: list[list[int]]) -> int: + """最小路径和:动态规划""" + n, m = len(grid), len(grid[0]) + # 初始化 dp 表 + dp = [[0] * m for _ in range(n)] + dp[0][0] = grid[0][0] + # 状态转移:首行 + for j in range(1, m): + dp[0][j] = dp[0][j - 1] + grid[0][j] + # 状态转移:首列 + for i in range(1, n): + dp[i][0] = dp[i - 1][0] + grid[i][0] + # 状态转移:其余行列 + for i in range(1, n): + for j in range(1, m): + dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j] + return dp[n - 1][m - 1] + + +def min_path_sum_dp_comp(grid: list[list[int]]) -> int: + """最小路径和:空间优化后的动态规划""" + n, m = len(grid), len(grid[0]) + # 初始化 dp 表 + dp = [0] * m + # 状态转移:首行 + dp[0] = grid[0][0] + for j in range(1, m): + dp[j] = dp[j - 1] + grid[0][j] + # 状态转移:其余行 + for i in range(1, n): + # 状态转移:首列 + dp[0] = dp[0] + grid[i][0] + # 状态转移:其余列 + for j in range(1, m): + dp[j] = min(dp[j - 1], dp[j]) + grid[i][j] + return dp[m - 1] + + +"""Driver Code""" +if __name__ == "__main__": + grid = [[1, 3, 1, 5], [2, 2, 4, 2], [5, 3, 2, 1], [4, 3, 5, 2]] + n, m = len(grid), len(grid[0]) + + # 暴力搜索 + res = min_path_sum_dfs(grid, n - 1, m - 1) + print(f"从左上角到右下角的做小路径和为 {res}") + + # 记忆化搜索 + mem = [[-1] * m for _ in range(n)] + res = min_path_sum_dfs_mem(grid, mem, n - 1, m - 1) + print(f"从左上角到右下角的做小路径和为 {res}") + + # 动态规划 + res = min_path_sum_dp(grid) + print(f"从左上角到右下角的做小路径和为 {res}") + + # 空间优化后的动态规划 + res = min_path_sum_dp_comp(grid) + print(f"从左上角到右下角的做小路径和为 {res}") diff --git a/algorithms/hello_algo/chapter14_dynamic_programming/unbounded_knapsack.py b/algorithms/hello_algo/chapter14_dynamic_programming/unbounded_knapsack.py new file mode 100644 index 0000000..20fb1a4 --- /dev/null +++ b/algorithms/hello_algo/chapter14_dynamic_programming/unbounded_knapsack.py @@ -0,0 +1,55 @@ +""" +File: unbounded_knapsack.py +Created Time: 2023-07-10 +Author: Krahets (krahets@163.com) +""" + + +def unbounded_knapsack_dp(wgt: list[int], val: list[int], cap: int) -> int: + """完全背包:动态规划""" + n = len(wgt) + # 初始化 dp 表 + dp = [[0] * (cap + 1) for _ in range(n + 1)] + # 状态转移 + for i in range(1, n + 1): + for c in range(1, cap + 1): + if wgt[i - 1] > c: + # 若超过背包容量,则不选物品 i + dp[i][c] = dp[i - 1][c] + else: + # 不选和选物品 i 这两种方案的较大值 + dp[i][c] = max(dp[i - 1][c], dp[i][c - wgt[i - 1]] + val[i - 1]) + return dp[n][cap] + + +def unbounded_knapsack_dp_comp(wgt: list[int], val: list[int], cap: int) -> int: + """完全背包:空间优化后的动态规划""" + n = len(wgt) + # 初始化 dp 表 + dp = [0] * (cap + 1) + # 状态转移 + for i in range(1, n + 1): + # 正序遍历 + for c in range(1, cap + 1): + if wgt[i - 1] > c: + # 若超过背包容量,则不选物品 i + dp[c] = dp[c] + else: + # 不选和选物品 i 这两种方案的较大值 + dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]) + return dp[cap] + + +"""Driver Code""" +if __name__ == "__main__": + wgt = [1, 2, 3] + val = [5, 11, 15] + cap = 4 + + # 动态规划 + res = unbounded_knapsack_dp(wgt, val, cap) + print(f"不超过背包容量的最大物品价值为 {res}") + + # 空间优化后的动态规划 + res = unbounded_knapsack_dp_comp(wgt, val, cap) + print(f"不超过背包容量的最大物品价值为 {res}") diff --git a/algorithms/hello_algo/chapter15_greedy/coin_change_greedy.py b/algorithms/hello_algo/chapter15_greedy/coin_change_greedy.py new file mode 100644 index 0000000..f233acb --- /dev/null +++ b/algorithms/hello_algo/chapter15_greedy/coin_change_greedy.py @@ -0,0 +1,48 @@ +""" +File: coin_change_greedy.py +Created Time: 2023-07-18 +Author: Krahets (krahets@163.com) +""" + + +def coin_change_greedy(coins: list[int], amt: int) -> int: + """零钱兑换:贪心""" + # 假设 coins 列表有序 + i = len(coins) - 1 + count = 0 + # 循环进行贪心选择,直到无剩余金额 + while amt > 0: + # 找到小于且最接近剩余金额的硬币 + while i > 0 and coins[i] > amt: + i -= 1 + # 选择 coins[i] + amt -= coins[i] + count += 1 + # 若未找到可行方案,则返回 -1 + return count if amt == 0 else -1 + + +"""Driver Code""" +if __name__ == "__main__": + # 贪心:能够保证找到全局最优解 + coins = [1, 5, 10, 20, 50, 100] + amt = 186 + res = coin_change_greedy(coins, amt) + print(f"\ncoins = {coins}, amt = {amt}") + print(f"凑到 {amt} 所需的最少硬币数量为 {res}") + + # 贪心:无法保证找到全局最优解 + coins = [1, 20, 50] + amt = 60 + res = coin_change_greedy(coins, amt) + print(f"\ncoins = {coins}, amt = {amt}") + print(f"凑到 {amt} 所需的最少硬币数量为 {res}") + print(f"实际上需要的最少数量为 3 ,即 20 + 20 + 20") + + # 贪心:无法保证找到全局最优解 + coins = [1, 49, 50] + amt = 98 + res = coin_change_greedy(coins, amt) + print(f"\ncoins = {coins}, amt = {amt}") + print(f"凑到 {amt} 所需的最少硬币数量为 {res}") + print(f"实际上需要的最少数量为 2 ,即 49 + 49") diff --git a/algorithms/hello_algo/chapter15_greedy/fractional_knapsack.py b/algorithms/hello_algo/chapter15_greedy/fractional_knapsack.py new file mode 100644 index 0000000..0191bdb --- /dev/null +++ b/algorithms/hello_algo/chapter15_greedy/fractional_knapsack.py @@ -0,0 +1,46 @@ +""" +File: fractional_knapsack.py +Created Time: 2023-07-19 +Author: Krahets (krahets@163.com) +""" + + +class Item: + """物品""" + + def __init__(self, w: int, v: int): + self.w = w # 物品重量 + self.v = v # 物品价值 + + +def fractional_knapsack(wgt: list[int], val: list[int], cap: int) -> int: + """分数背包:贪心""" + # 创建物品列表,包含两个属性:重量、价值 + items = [Item(w, v) for w, v in zip(wgt, val)] + # 按照单位价值 item.v / item.w 从高到低进行排序 + items.sort(key=lambda item: item.v / item.w, reverse=True) + # 循环贪心选择 + res = 0 + for item in items: + if item.w <= cap: + # 若剩余容量充足,则将当前物品整个装进背包 + res += item.v + cap -= item.w + else: + # 若剩余容量不足,则将当前物品的一部分装进背包 + res += (item.v / item.w) * cap + # 已无剩余容量,因此跳出循环 + break + return res + + +"""Driver Code""" +if __name__ == "__main__": + wgt = [10, 20, 30, 40, 50] + val = [50, 120, 150, 210, 240] + cap = 50 + n = len(wgt) + + # 贪心算法 + res = fractional_knapsack(wgt, val, cap) + print(f"不超过背包容量的最大物品价值为 {res}") diff --git a/algorithms/hello_algo/chapter15_greedy/max_capacity.py b/algorithms/hello_algo/chapter15_greedy/max_capacity.py new file mode 100644 index 0000000..12377b4 --- /dev/null +++ b/algorithms/hello_algo/chapter15_greedy/max_capacity.py @@ -0,0 +1,33 @@ +""" +File: max_capacity.py +Created Time: 2023-07-21 +Author: Krahets (krahets@163.com) +""" + + +def max_capacity(ht: list[int]) -> int: + """最大容量:贪心""" + # 初始化 i, j 分列数组两端 + i, j = 0, len(ht) - 1 + # 初始最大容量为 0 + res = 0 + # 循环贪心选择,直至两板相遇 + while i < j: + # 更新最大容量 + cap = min(ht[i], ht[j]) * (j - i) + res = max(res, cap) + # 向内移动短板 + if ht[i] < ht[j]: + i += 1 + else: + j -= 1 + return res + + +"""Driver Code""" +if __name__ == "__main__": + ht = [3, 8, 5, 2, 7, 7, 3, 4] + + # 贪心算法 + res = max_capacity(ht) + print(f"最大容量为 {res}") diff --git a/algorithms/hello_algo/chapter15_greedy/max_product_cutting.py b/algorithms/hello_algo/chapter15_greedy/max_product_cutting.py new file mode 100644 index 0000000..921a354 --- /dev/null +++ b/algorithms/hello_algo/chapter15_greedy/max_product_cutting.py @@ -0,0 +1,33 @@ +""" +File: max_product_cutting.py +Created Time: 2023-07-21 +Author: Krahets (krahets@163.com) +""" + +import math + + +def max_product_cutting(n: int) -> int: + """最大切分乘积:贪心""" + # 当 n <= 3 时,必须切分出一个 1 + if n <= 3: + return 1 * (n - 1) + # 贪心地切分出 3 ,a 为 3 的个数,b 为余数 + a, b = n // 3, n % 3 + if b == 1: + # 当余数为 1 时,将一对 1 * 3 转化为 2 * 2 + return int(math.pow(3, a - 1)) * 2 * 2 + if b == 2: + # 当余数为 2 时,不做处理 + return int(math.pow(3, a)) * 2 + # 当余数为 0 时,不做处理 + return int(math.pow(3, a)) + + +"""Driver Code""" +if __name__ == "__main__": + n = 58 + + # 贪心算法 + res = max_product_cutting(n) + print(f"最大切分乘积为 {res}") diff --git a/algorithms/hello_algo/modules/__init__.py b/algorithms/hello_algo/modules/__init__.py new file mode 100644 index 0000000..0ff746b --- /dev/null +++ b/algorithms/hello_algo/modules/__init__.py @@ -0,0 +1,20 @@ +# Follow the PEP 585 – Type Hinting Generics In Standard Collections +# https://peps.python.org/pep-0585/ +from __future__ import annotations + +# Import common libs here to simplify the code by `from module import *` +from .list_node import ( + ListNode, + list_to_linked_list, + linked_list_to_list, + get_list_node, +) +from .tree_node import TreeNode, list_to_tree, tree_to_list +from .vertex import Vertex, vals_to_vets, vets_to_vals +from .print_util import ( + print_matrix, + print_linked_list, + print_tree, + print_dict, + print_heap, +) diff --git a/algorithms/hello_algo/modules/list_node.py b/algorithms/hello_algo/modules/list_node.py new file mode 100644 index 0000000..8baca16 --- /dev/null +++ b/algorithms/hello_algo/modules/list_node.py @@ -0,0 +1,39 @@ +""" +File: list_node.py +Created Time: 2021-12-11 +Author: Krahets (krahets@163.com) +""" + + +class ListNode: + """Definition for a singly-linked list node""" + + def __init__(self, val: int): + self.val: int = val # 节点值 + self.next: ListNode | None = None # 后继节点引用 + + +def list_to_linked_list(arr: list[int]) -> ListNode | None: + """Generate a linked list with a list""" + dum = head = ListNode(0) + for a in arr: + node = ListNode(a) + head.next = node + head = head.next + return dum.next + + +def linked_list_to_list(head: ListNode | None) -> list[int]: + """Serialize a linked list into an array""" + arr: list[int] = [] + while head: + arr.append(head.val) + head = head.next + return arr + + +def get_list_node(head: ListNode | None, val: int) -> ListNode | None: + """Get a list node with specific value from a linked list""" + while head and head.val != val: + head = head.next + return head diff --git a/algorithms/hello_algo/modules/print_util.py b/algorithms/hello_algo/modules/print_util.py new file mode 100644 index 0000000..b210db3 --- /dev/null +++ b/algorithms/hello_algo/modules/print_util.py @@ -0,0 +1,79 @@ +""" +File: print_util.py +Created Time: 2021-12-11 +Author: Krahets (krahets@163.com), msk397 (machangxinq@gmail.com) +""" + +from .tree_node import TreeNode, list_to_tree +from .list_node import ListNode, linked_list_to_list + + +def print_matrix(mat: list[list[int]]): + """Print a matrix""" + s = [] + for arr in mat: + s.append(" " + str(arr)) + print("[\n" + ",\n".join(s) + "\n]") + + +def print_linked_list(head: ListNode | None): + """Print a linked list""" + arr: list[int] = linked_list_to_list(head) + print(" -> ".join([str(a) for a in arr])) + + +class Trunk: + def __init__(self, prev, string: str | None = None): + self.prev = prev + self.str = string + + +def show_trunks(p: Trunk | None): + if p is None: + return + show_trunks(p.prev) + print(p.str, end="") + + +def print_tree(root: TreeNode | None, prev: Trunk | None = None, is_right: bool = False): + """ + Print a binary tree + This tree printer is borrowed from TECHIE DELIGHT + https://www.techiedelight.com/c-program-print-binary-tree/ + """ + if root is None: + return + + prev_str = " " + trunk = Trunk(prev, prev_str) + print_tree(root.right, trunk, True) + + if prev is None: + trunk.str = "———" + elif is_right: + trunk.str = "/———" + prev_str = " |" + else: + trunk.str = "\———" + prev.str = prev_str + + show_trunks(trunk) + print(" " + str(root.val)) + if prev: + prev.str = prev_str + trunk.str = " |" + print_tree(root.left, trunk, False) + + +def print_dict(hmap: dict): + """Print a dict""" + for key, value in hmap.items(): + print(key, "->", value) + + +def print_heap(heap: list[int]): + """Print a heap both in array and tree representations""" + print("堆的数组表示:", heap) + print("堆的树状表示:") + root: TreeNode | None = list_to_tree(heap) + print_tree(root) diff --git a/algorithms/hello_algo/modules/tree_node.py b/algorithms/hello_algo/modules/tree_node.py new file mode 100644 index 0000000..4aebcd9 --- /dev/null +++ b/algorithms/hello_algo/modules/tree_node.py @@ -0,0 +1,69 @@ +""" +File: tree_node.py +Created Time: 2021-12-11 +Author: Krahets (krahets@163.com) +""" + +from collections import deque + + +class TreeNode: + """二叉树节点类""" + + def __init__(self, val: int = 0): + self.val: int = val # 节点值 + self.height: int = 0 # 节点高度 + self.left: TreeNode | None = None # 左子节点引用 + self.right: TreeNode | None = None # 右子节点引用 + + # 序列化编码规则请参考: + # https://www.hello-algo.com/chapter_tree/array_representation_of_tree/ + # 二叉树的数组表示: + # [1, 2, 3, 4, None, 6, 7, 8, 9, None, None, 12, None, None, 15] + # 二叉树的链表表示: + # /——— 15 + # /——— 7 + # /——— 3 + # | \——— 6 + # | \——— 12 + # ——— 1 + # \——— 2 + # | /——— 9 + # \——— 4 + # \——— 8 + + +def list_to_tree_dfs(arr: list[int], i: int) -> TreeNode | None: + """将列表反序列化为二叉树:递归""" + # 如果索引超出数组长度,或者对应的元素为 None ,则返回 None + if i < 0 or i >= len(arr) or arr[i] is None: + return None + # 构建当前节点 + root = TreeNode(arr[i]) + # 递归构建左右子树 + root.left = list_to_tree_dfs(arr, 2 * i + 1) + root.right = list_to_tree_dfs(arr, 2 * i + 2) + return root + + +def list_to_tree(arr: list[int]) -> TreeNode | None: + """将列表反序列化为二叉树""" + return list_to_tree_dfs(arr, 0) + + +def tree_to_list_dfs(root: TreeNode, i: int, res: list[int]) -> list[int]: + """将二叉树序列化为列表:递归""" + if root is None: + return + if i >= len(res): + res += [None] * (i - len(res) + 1) + res[i] = root.val + tree_to_list_dfs(root.left, 2 * i + 1, res) + tree_to_list_dfs(root.right, 2 * i + 2, res) + + +def tree_to_list(root: TreeNode | None) -> list[int]: + """将二叉树序列化为列表""" + res = [] + tree_to_list_dfs(root, 0, res) + return res diff --git a/algorithms/hello_algo/modules/vertex.py b/algorithms/hello_algo/modules/vertex.py new file mode 100644 index 0000000..012115d --- /dev/null +++ b/algorithms/hello_algo/modules/vertex.py @@ -0,0 +1,20 @@ +# File: vertex.py +# Created Time: 2023-02-23 +# Author: Krahets (krahets@163.com) + + +class Vertex: + """顶点类""" + + def __init__(self, val: int): + self.val = val + + +def vals_to_vets(vals: list[int]) -> list["Vertex"]: + """输入值列表 vals ,返回顶点列表 vets""" + return [Vertex(val) for val in vals] + + +def vets_to_vals(vets: list["Vertex"]) -> list[int]: + """输入顶点列表 vets ,返回值列表 vals""" + return [vet.val for vet in vets] diff --git a/algorithms/hello_algo/test_all.py b/algorithms/hello_algo/test_all.py new file mode 100644 index 0000000..267afd1 --- /dev/null +++ b/algorithms/hello_algo/test_all.py @@ -0,0 +1,33 @@ +import os +import glob +import subprocess + +env = os.environ.copy() +env["PYTHONIOENCODING"] = "utf-8" + +if __name__ == "__main__": + # find source code files + src_paths = sorted(glob.glob("chapter*/*.py")) + errors = [] + + # run python code + for src_path in src_paths: + process = subprocess.Popen( + ["python", src_path], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + env=env, + encoding='utf-8' + ) + # Wait for the process to complete, and get the output and error messages + stdout, stderr = process.communicate() + # Check the exit status + exit_status = process.returncode + if exit_status != 0: + errors.append(stderr) + + print(f"Tested {len(src_paths)} files") + print(f"Found exception in {len(errors)} files") + if len(errors) > 0: + raise RuntimeError("\n\n".join(errors)) From d1c210be68c70dcb2b2714c7e2234d4bb953e33e Mon Sep 17 00:00:00 2001 From: xiongneng Date: Sun, 31 Dec 2023 10:17:46 +0800 Subject: [PATCH 52/54] update category --- README.md | 35 ++-- algorithms/__init__.py | 2 - algorithms/{hello_algo => }/build.py | 0 .../__init__.py | 0 .../hashing}/__init__.py | 0 .../hashing}/array_hash_map.py | 0 .../hashing}/built_in_hash.py | 3 +- .../hashing}/hash_map.py | 2 +- .../hashing}/hash_map_chaining.py | 3 +- .../hashing}/hash_map_open_addressing.py | 3 +- .../hashing}/simple_hash.py | 1 - .../linkedlist/__init__.py | 0 .../linkedlist/linked_list_double.py | 2 +- .../linkedlist/linked_list_double_cycle.py | 2 +- .../linkedlist/linked_list_single.py | 4 +- .../linkedlist/linked_list_single_cycle.py | 2 +- .../linkedlist/lru_cache.py | 6 +- .../linkedlist/palindromic_number.py | 14 +- .../queue/__init__.py | 1 - .../queue}/array_deque.py | 1 - .../queue}/array_queue.py | 0 .../queue}/deque.py | 0 .../queue/linked_queue.py | 2 +- .../queue}/linkedlist_deque.py | 1 - .../queue}/linkedlist_queue.py | 2 +- .../queue/prior_queue.py | 2 +- .../queue}/queue.py | 0 .../stack/__init__.py | 1 - .../stack}/array_stack.py | 0 .../stack}/linkedlist_stack.py | 2 +- .../stack}/stack.py | 0 .../stack/stack_array.py | 5 +- .../stack/stack_linked_list.py | 3 +- algorithms/c01_linear/queue/array_queue.py | 64 -------- algorithms/{c04_tree => c02_tree}/__init__.py | 0 .../array_binary_tree.py | 3 +- .../chapter07_tree => c02_tree}/avl_tree.py | 2 +- .../binary_search_tree.py | 2 +- .../binary_tree.py | 2 +- .../binary_tree_bfs.py | 2 +- .../binary_tree_dfs.py | 2 +- .../{c04_tree => c02_tree}/bisearch_tree.py | 0 algorithms/{c04_tree => c02_tree}/btree.py | 0 .../chapter08_heap => c02_tree}/heap.py | 3 +- .../chapter08_heap => c02_tree}/my_heap.py | 3 +- .../{c04_tree => c02_tree}/redblack_tree.py | 2 +- .../chapter08_heap => c02_tree}/top_k.py | 3 +- .../{c05_graph => c03_graph}/__init__.py | 1 - .../graph_adjacency_list.py | 3 +- .../graph_adjacency_matrix.py | 3 +- .../graph_bfs.py | 3 +- .../graph_dfs.py | 3 +- algorithms/{c02_sort => c04_sort}/__init__.py | 0 .../{c02_sort => c04_sort}/base/__init__.py | 0 .../{c02_sort => c04_sort}/base/sortutil.py | 0 .../{c02_sort => c04_sort}/base/template.py | 0 .../bubble_sort.py | 0 .../bucket_sort.py | 1 - .../counting_sort.py | 1 - .../heap_sort.py | 1 - .../insertion_sort.py | 0 .../{c02_sort => c04_sort}/m00_bubble_sort.py | 2 +- .../{c02_sort => c04_sort}/m01_insert_sort.py | 4 +- .../{c02_sort => c04_sort}/m02_select_sort.py | 2 +- .../{c02_sort => c04_sort}/m03_merge_sort.py | 2 +- .../m04_merge_insert_sort.py | 4 +- .../{c02_sort => c04_sort}/m05_quick_sort.py | 2 +- .../{c02_sort => c04_sort}/m06_heap_sort.py | 2 +- .../{c02_sort => c04_sort}/m07_count_sort.py | 0 .../{c02_sort => c04_sort}/m08_radix_sort.py | 0 .../{c02_sort => c04_sort}/m09_bucket_sort.py | 2 +- .../{c02_sort => c04_sort}/m10_find_minmax.py | 0 .../{c02_sort => c04_sort}/m11_imin_select.py | 0 .../m12_imin_select2.py | 2 +- .../{c02_sort => c04_sort}/m13_imin_list.py | 2 +- .../merge_sort.py | 1 - .../quick_sort.py | 0 .../radix_sort.py | 1 - .../selection_sort.py | 1 - .../{c03_search => c05_search}/__init__.py | 0 .../binary_search.py | 0 .../binary_search_edge.py | 1 - .../binary_search_insertion.py | 1 - .../hashing_search.py | 2 +- .../linear_search.py | 2 +- .../two_sum.py | 1 - algorithms/c06_string/__init__.py | 1 - .../{c08_divide => c07_divide}/__init__.py | 0 .../binary_search_recur.py | 0 .../build_tree.py | 3 +- .../hanota.py | 1 - .../{hello_algo => c08_backtrack}/__init__.py | 0 algorithms/c08_backtrack/backtrack.py | 43 +++++ .../n_queens.py | 1 - .../permutations_i.py | 1 - .../permutations_ii.py | 1 - .../preorder_traversal_i_compact.py | 3 +- .../preorder_traversal_ii_compact.py | 3 +- .../preorder_traversal_iii_compact.py | 3 +- .../preorder_traversal_iii_template.py | 7 +- algorithms/c08_backtrack/search_node.py | 44 +++++ .../subset_sum_i.py | 1 - .../subset_sum_i_naive.py | 1 - .../subset_sum_ii.py | 1 - .../{c10_dynamic => c09_dynamic}/__init__.py | 0 .../climbing_stairs_backtrack.py | 1 - .../climbing_stairs_constraint_dp.py | 1 - .../climbing_stairs_dfs.py | 1 - .../climbing_stairs_dfs_mem.py | 1 - .../climbing_stairs_dp.py | 1 - .../coin_change.py | 1 - .../coin_change_ii.py | 1 - .../edit_distance.py | 1 - .../knapsack.py | 1 - .../m01_cut_steel.py | 0 .../m02_fibonacci.py | 0 .../m03_matrix_chain.py | 0 .../m04_elevator.py | 0 .../m05_subsequence.py | 0 .../{c10_dynamic => c09_dynamic}/m06_bag.py | 0 .../min_cost_climbing_stairs_dp.py | 1 - .../min_path_sum.py | 1 - .../unbounded_knapsack.py | 1 - .../{c07_greedy => c10_greedy}/__init__.py | 1 - .../coin_change_greedy.py | 1 - .../fractional_knapsack.py | 1 - .../m01_activity.py | 0 .../max_capacity.py | 1 - .../max_product_cutting.py | 1 - algorithms/c12_ai/basic/__init__.py | 5 - algorithms/c12_ai/basic/a01_maze_bfs.py | 4 +- algorithms/c12_ai/basic/a02_maze_dfs.py | 6 +- algorithms/c14_leetcode/__init__.py | 1 - .../a19_remove_nth_node_from_end_of_list.py | 2 - .../p000/a20_valid_parentheses.py | 2 +- .../p000/a21_merge_two_sorted_lists.py | 1 + .../p000/a23_merge_k_sorted_lists.py | 2 +- .../c14_leetcode/p000/a70_climbing_stairs.py | 1 + .../c14_leetcode/p000/a86_partition_list.py | 2 +- .../p100/a142_linked_list_cycle_ii.py | 2 +- .../c14_leetcode/p100/a155_min_stack.py | 4 +- .../a160_intersection_of_two_linked_lists.py | 2 +- .../p200/a206_reverse_linked_list.py | 8 +- .../p800/a876_middle_of_the_linked_list.py | 3 +- .../iteration.py | 65 -------- .../recursion.py | 69 -------- .../space_complexity.py | 90 ----------- .../time_complexity.py | 151 ------------------ .../worst_best_time_complexity.py | 36 ----- .../chapter04_array_and_linkedlist/array.py | 99 ------------ .../linked_list.py | 84 ---------- .../chapter04_array_and_linkedlist/list.py | 59 ------- .../chapter04_array_and_linkedlist/my_list.py | 118 -------------- .../modules => models}/__init__.py | 0 .../modules => models}/list_node.py | 1 - .../modules => models}/print_util.py | 1 - .../modules => models}/tree_node.py | 1 - .../{hello_algo/modules => models}/vertex.py | 3 +- algorithms/test.py | 11 -- algorithms/{hello_algo => }/test_all.py | 0 160 files changed, 182 insertions(+), 1019 deletions(-) rename algorithms/{hello_algo => }/build.py (100%) rename algorithms/{c01_linear => c01_data_structure}/__init__.py (100%) rename algorithms/{c09_backtrack => c01_data_structure/hashing}/__init__.py (100%) rename algorithms/{hello_algo/chapter06_hashing => c01_data_structure/hashing}/array_hash_map.py (100%) rename algorithms/{hello_algo/chapter06_hashing => c01_data_structure/hashing}/built_in_hash.py (90%) rename algorithms/{hello_algo/chapter06_hashing => c01_data_structure/hashing}/hash_map.py (95%) rename algorithms/{hello_algo/chapter06_hashing => c01_data_structure/hashing}/hash_map_chaining.py (97%) rename algorithms/{hello_algo/chapter06_hashing => c01_data_structure/hashing}/hash_map_open_addressing.py (97%) rename algorithms/{hello_algo/chapter06_hashing => c01_data_structure/hashing}/simple_hash.py (96%) rename algorithms/{c01_linear => c01_data_structure}/linkedlist/__init__.py (100%) rename algorithms/{c01_linear => c01_data_structure}/linkedlist/linked_list_double.py (96%) rename algorithms/{c01_linear => c01_data_structure}/linkedlist/linked_list_double_cycle.py (96%) rename algorithms/{c01_linear => c01_data_structure}/linkedlist/linked_list_single.py (95%) rename algorithms/{c01_linear => c01_data_structure}/linkedlist/linked_list_single_cycle.py (96%) rename algorithms/{c01_linear => c01_data_structure}/linkedlist/lru_cache.py (86%) rename algorithms/{c01_linear => c01_data_structure}/linkedlist/palindromic_number.py (87%) rename algorithms/{c01_linear => c01_data_structure}/queue/__init__.py (98%) rename algorithms/{hello_algo/chapter05_stack_and_queue => c01_data_structure/queue}/array_deque.py (99%) rename algorithms/{hello_algo/chapter05_stack_and_queue => c01_data_structure/queue}/array_queue.py (100%) rename algorithms/{hello_algo/chapter05_stack_and_queue => c01_data_structure/queue}/deque.py (100%) rename algorithms/{c01_linear => c01_data_structure}/queue/linked_queue.py (96%) rename algorithms/{hello_algo/chapter05_stack_and_queue => c01_data_structure/queue}/linkedlist_deque.py (99%) rename algorithms/{hello_algo/chapter05_stack_and_queue => c01_data_structure/queue}/linkedlist_queue.py (97%) rename algorithms/{c01_linear => c01_data_structure}/queue/prior_queue.py (97%) rename algorithms/{hello_algo/chapter05_stack_and_queue => c01_data_structure/queue}/queue.py (100%) rename algorithms/{c01_linear => c01_data_structure}/stack/__init__.py (98%) rename algorithms/{hello_algo/chapter05_stack_and_queue => c01_data_structure/stack}/array_stack.py (100%) rename algorithms/{hello_algo/chapter05_stack_and_queue => c01_data_structure/stack}/linkedlist_stack.py (97%) rename algorithms/{hello_algo/chapter05_stack_and_queue => c01_data_structure/stack}/stack.py (100%) rename algorithms/{c01_linear => c01_data_structure}/stack/stack_array.py (94%) rename algorithms/{c01_linear => c01_data_structure}/stack/stack_linked_list.py (96%) delete mode 100644 algorithms/c01_linear/queue/array_queue.py rename algorithms/{c04_tree => c02_tree}/__init__.py (100%) rename algorithms/{hello_algo/chapter07_tree => c02_tree}/array_binary_tree.py (96%) rename algorithms/{hello_algo/chapter07_tree => c02_tree}/avl_tree.py (99%) rename algorithms/{hello_algo/chapter07_tree => c02_tree}/binary_search_tree.py (98%) rename algorithms/{hello_algo/chapter07_tree => c02_tree}/binary_tree.py (92%) rename algorithms/{hello_algo/chapter07_tree => c02_tree}/binary_tree_bfs.py (93%) rename algorithms/{hello_algo/chapter07_tree => c02_tree}/binary_tree_dfs.py (95%) rename algorithms/{c04_tree => c02_tree}/bisearch_tree.py (100%) rename algorithms/{c04_tree => c02_tree}/btree.py (100%) rename algorithms/{hello_algo/chapter08_heap => c02_tree}/heap.py (95%) rename algorithms/{hello_algo/chapter08_heap => c02_tree}/my_heap.py (97%) rename algorithms/{c04_tree => c02_tree}/redblack_tree.py (99%) rename algorithms/{hello_algo/chapter08_heap => c02_tree}/top_k.py (91%) rename algorithms/{c05_graph => c03_graph}/__init__.py (98%) rename algorithms/{hello_algo/chapter09_graph => c03_graph}/graph_adjacency_list.py (96%) rename algorithms/{hello_algo/chapter09_graph => c03_graph}/graph_adjacency_matrix.py (97%) rename algorithms/{hello_algo/chapter09_graph => c03_graph}/graph_bfs.py (94%) rename algorithms/{hello_algo/chapter09_graph => c03_graph}/graph_dfs.py (93%) rename algorithms/{c02_sort => c04_sort}/__init__.py (100%) rename algorithms/{c02_sort => c04_sort}/base/__init__.py (100%) rename algorithms/{c02_sort => c04_sort}/base/sortutil.py (100%) rename algorithms/{c02_sort => c04_sort}/base/template.py (100%) rename algorithms/{hello_algo/chapter11_sorting => c04_sort}/bubble_sort.py (100%) rename algorithms/{hello_algo/chapter11_sorting => c04_sort}/bucket_sort.py (96%) rename algorithms/{hello_algo/chapter11_sorting => c04_sort}/counting_sort.py (98%) rename algorithms/{hello_algo/chapter11_sorting => c04_sort}/heap_sort.py (97%) rename algorithms/{hello_algo/chapter11_sorting => c04_sort}/insertion_sort.py (100%) rename algorithms/{c02_sort => c04_sort}/m00_bubble_sort.py (93%) rename algorithms/{c02_sort => c04_sort}/m01_insert_sort.py (91%) rename algorithms/{c02_sort => c04_sort}/m02_select_sort.py (94%) rename algorithms/{c02_sort => c04_sort}/m03_merge_sort.py (97%) rename algorithms/{c02_sort => c04_sort}/m04_merge_insert_sort.py (96%) rename algorithms/{c02_sort => c04_sort}/m05_quick_sort.py (97%) rename algorithms/{c02_sort => c04_sort}/m06_heap_sort.py (97%) rename algorithms/{c02_sort => c04_sort}/m07_count_sort.py (100%) rename algorithms/{c02_sort => c04_sort}/m08_radix_sort.py (100%) rename algorithms/{c02_sort => c04_sort}/m09_bucket_sort.py (94%) rename algorithms/{c02_sort => c04_sort}/m10_find_minmax.py (100%) rename algorithms/{c02_sort => c04_sort}/m11_imin_select.py (100%) rename algorithms/{c02_sort => c04_sort}/m12_imin_select2.py (97%) rename algorithms/{c02_sort => c04_sort}/m13_imin_list.py (94%) rename algorithms/{hello_algo/chapter11_sorting => c04_sort}/merge_sort.py (96%) rename algorithms/{hello_algo/chapter11_sorting => c04_sort}/quick_sort.py (100%) rename algorithms/{hello_algo/chapter11_sorting => c04_sort}/radix_sort.py (98%) rename algorithms/{hello_algo/chapter11_sorting => c04_sort}/selection_sort.py (95%) rename algorithms/{c03_search => c05_search}/__init__.py (100%) rename algorithms/{hello_algo/chapter10_searching => c05_search}/binary_search.py (100%) rename algorithms/{hello_algo/chapter10_searching => c05_search}/binary_search_edge.py (97%) rename algorithms/{hello_algo/chapter10_searching => c05_search}/binary_search_insertion.py (98%) rename algorithms/{hello_algo/chapter10_searching => c05_search}/hashing_search.py (95%) rename algorithms/{hello_algo/chapter10_searching => c05_search}/linear_search.py (94%) rename algorithms/{hello_algo/chapter10_searching => c05_search}/two_sum.py (96%) rename algorithms/{c08_divide => c07_divide}/__init__.py (100%) rename algorithms/{hello_algo/chapter12_divide_and_conquer => c07_divide}/binary_search_recur.py (100%) rename algorithms/{hello_algo/chapter12_divide_and_conquer => c07_divide}/build_tree.py (93%) rename algorithms/{hello_algo/chapter12_divide_and_conquer => c07_divide}/hanota.py (97%) rename algorithms/{hello_algo => c08_backtrack}/__init__.py (100%) create mode 100644 algorithms/c08_backtrack/backtrack.py rename algorithms/{hello_algo/chapter13_backtracking => c08_backtrack}/n_queens.py (98%) rename algorithms/{hello_algo/chapter13_backtracking => c08_backtrack}/permutations_i.py (97%) rename algorithms/{hello_algo/chapter13_backtracking => c08_backtrack}/permutations_ii.py (97%) rename algorithms/{hello_algo/chapter13_backtracking => c08_backtrack}/preorder_traversal_i_compact.py (86%) rename algorithms/{hello_algo/chapter13_backtracking => c08_backtrack}/preorder_traversal_ii_compact.py (88%) rename algorithms/{hello_algo/chapter13_backtracking => c08_backtrack}/preorder_traversal_iii_compact.py (88%) rename algorithms/{hello_algo/chapter13_backtracking => c08_backtrack}/preorder_traversal_iii_template.py (89%) create mode 100644 algorithms/c08_backtrack/search_node.py rename algorithms/{hello_algo/chapter13_backtracking => c08_backtrack}/subset_sum_i.py (97%) rename algorithms/{hello_algo/chapter13_backtracking => c08_backtrack}/subset_sum_i_naive.py (97%) rename algorithms/{hello_algo/chapter13_backtracking => c08_backtrack}/subset_sum_ii.py (98%) rename algorithms/{c10_dynamic => c09_dynamic}/__init__.py (100%) rename algorithms/{hello_algo/chapter14_dynamic_programming => c09_dynamic}/climbing_stairs_backtrack.py (96%) rename algorithms/{hello_algo/chapter14_dynamic_programming => c09_dynamic}/climbing_stairs_constraint_dp.py (95%) rename algorithms/{hello_algo/chapter14_dynamic_programming => c09_dynamic}/climbing_stairs_dfs.py (93%) rename algorithms/{hello_algo/chapter14_dynamic_programming => c09_dynamic}/climbing_stairs_dfs_mem.py (95%) rename algorithms/{hello_algo/chapter14_dynamic_programming => c09_dynamic}/climbing_stairs_dp.py (96%) rename algorithms/{hello_algo/chapter14_dynamic_programming => c09_dynamic}/coin_change.py (98%) rename algorithms/{hello_algo/chapter14_dynamic_programming => c09_dynamic}/coin_change_ii.py (97%) rename algorithms/{hello_algo/chapter14_dynamic_programming => c09_dynamic}/edit_distance.py (99%) rename algorithms/{hello_algo/chapter14_dynamic_programming => c09_dynamic}/knapsack.py (98%) rename algorithms/{c10_dynamic => c09_dynamic}/m01_cut_steel.py (100%) rename algorithms/{c10_dynamic => c09_dynamic}/m02_fibonacci.py (100%) rename algorithms/{c10_dynamic => c09_dynamic}/m03_matrix_chain.py (100%) rename algorithms/{c10_dynamic => c09_dynamic}/m04_elevator.py (100%) rename algorithms/{c10_dynamic => c09_dynamic}/m05_subsequence.py (100%) rename algorithms/{c10_dynamic => c09_dynamic}/m06_bag.py (100%) rename algorithms/{hello_algo/chapter14_dynamic_programming => c09_dynamic}/min_cost_climbing_stairs_dp.py (97%) rename algorithms/{hello_algo/chapter14_dynamic_programming => c09_dynamic}/min_path_sum.py (98%) rename algorithms/{hello_algo/chapter14_dynamic_programming => c09_dynamic}/unbounded_knapsack.py (97%) rename algorithms/{c07_greedy => c10_greedy}/__init__.py (97%) rename algorithms/{hello_algo/chapter15_greedy => c10_greedy}/coin_change_greedy.py (97%) rename algorithms/{hello_algo/chapter15_greedy => c10_greedy}/fractional_knapsack.py (97%) rename algorithms/{c07_greedy => c10_greedy}/m01_activity.py (100%) rename algorithms/{hello_algo/chapter15_greedy => c10_greedy}/max_capacity.py (95%) rename algorithms/{hello_algo/chapter15_greedy => c10_greedy}/max_product_cutting.py (95%) delete mode 100644 algorithms/hello_algo/chapter02_computational_complexity/iteration.py delete mode 100644 algorithms/hello_algo/chapter02_computational_complexity/recursion.py delete mode 100644 algorithms/hello_algo/chapter02_computational_complexity/space_complexity.py delete mode 100644 algorithms/hello_algo/chapter02_computational_complexity/time_complexity.py delete mode 100644 algorithms/hello_algo/chapter02_computational_complexity/worst_best_time_complexity.py delete mode 100644 algorithms/hello_algo/chapter04_array_and_linkedlist/array.py delete mode 100644 algorithms/hello_algo/chapter04_array_and_linkedlist/linked_list.py delete mode 100644 algorithms/hello_algo/chapter04_array_and_linkedlist/list.py delete mode 100644 algorithms/hello_algo/chapter04_array_and_linkedlist/my_list.py rename algorithms/{hello_algo/modules => models}/__init__.py (100%) rename algorithms/{hello_algo/modules => models}/list_node.py (96%) rename algorithms/{hello_algo/modules => models}/print_util.py (96%) rename algorithms/{hello_algo/modules => models}/tree_node.py (98%) rename algorithms/{hello_algo/modules => models}/vertex.py (92%) delete mode 100644 algorithms/test.py rename algorithms/{hello_algo => }/test_all.py (100%) diff --git a/README.md b/README.md index 2bed321..07adfed 100644 --- a/README.md +++ b/README.md @@ -2,24 +2,25 @@ 算法参考书籍列表,建议按照顺序阅读: +* 《Hello算法》 * 《算法图解》 * 《啊哈算法》 * 《算法导论》 -* 《人工智能算法图解》 * 《labuladong的算法小抄》 +* 《人工智能算法图解》 ## 章节说明 -1. 【第一章】线性表数据结构:数组、链表、队列、栈。 -2. 【第二章】各类排序算法:(冒泡、插入、选择)、(快排、归并)、(桶、计数、基数)。 -3. 【第三章】各类搜索算法:二分查找、调表、散列表、哈希算法 -4. 【第四章】树数据结构:二叉树、红黑树、递归树、堆。 -5. 【第五章】图数据结构 +1. 【第一章】基础数据结构:数组、链表、队列、栈、哈希表。 +2. 【第二章】树数据结构:二叉树、红黑树、递归树、堆。 +3. 【第三章】图数据结构 +4. 【第四章】各类排序算法:(冒泡、插入、选择)、(快排、归并)、(桶、计数、基数)。 +5. 【第五章】各类搜索算法:二分查找、调表、散列表、哈希算法 6. 【第六章】字符串匹配算法 -7. 【第七章】贪心算法 -8. 【第八章】分治算法 -9. 【第九章】回溯算法 -10. 【第十章】动态规划算法 +7. 【第七章】分治算法 +8. 【第八章】回溯算法 +9. 【第九章】动态规划算法 +10. 【第十章】贪心算法 11. 【第十一章】高级数据结构和算法 12. 【第十二章】AI算法 13. 【第十三章】算法示例程序 @@ -29,15 +30,15 @@ 书中经典的算法示例使用python3语言实现。 -整个工程分为三个部分。第1部分是阅读经典算法书籍后自己的总结,作为基础算法部分。 -第2部分是人工智能AI算法示例,第3部分是自己在LeetCode上面的刷题总结。 +整个工程分为三个部分。第一部分是阅读经典算法书籍后自己的总结,作为基础算法部分。 +第二部分是人工智能AI算法示例,第三部分是自己在LeetCode上面的刷题总结。 从2013年就开始写这个系列,写到动态规划后就停了,那段时间实在是太懒了。 今年2020年开始决定继续把之前的捡起来,重新更新这个系列,做事情得有始有终,希望能把这个系列坚持写完。 有任何问题都可以联系我: -* Email: yidao620@gmail.com +* Email: yidao620@gmail.com * Blog: https://www.xncoding.com/ * GitHub: https://github.com/yidao620c @@ -67,12 +68,12 @@ Meanwhile you'd better follow the rules below Copyright (c) 2013-2020 [Xiong Neng](https://www.xncoding.com/) and other contributors -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/algorithms/__init__.py b/algorithms/__init__.py index 3af313b..cf0aa6e 100644 --- a/algorithms/__init__.py +++ b/algorithms/__init__.py @@ -3,5 +3,3 @@ """ 《算法导论》第3版,使用python3语言实现书中经典的算法示例 """ - - diff --git a/algorithms/hello_algo/build.py b/algorithms/build.py similarity index 100% rename from algorithms/hello_algo/build.py rename to algorithms/build.py diff --git a/algorithms/c01_linear/__init__.py b/algorithms/c01_data_structure/__init__.py similarity index 100% rename from algorithms/c01_linear/__init__.py rename to algorithms/c01_data_structure/__init__.py diff --git a/algorithms/c09_backtrack/__init__.py b/algorithms/c01_data_structure/hashing/__init__.py similarity index 100% rename from algorithms/c09_backtrack/__init__.py rename to algorithms/c01_data_structure/hashing/__init__.py diff --git a/algorithms/hello_algo/chapter06_hashing/array_hash_map.py b/algorithms/c01_data_structure/hashing/array_hash_map.py similarity index 100% rename from algorithms/hello_algo/chapter06_hashing/array_hash_map.py rename to algorithms/c01_data_structure/hashing/array_hash_map.py diff --git a/algorithms/hello_algo/chapter06_hashing/built_in_hash.py b/algorithms/c01_data_structure/hashing/built_in_hash.py similarity index 90% rename from algorithms/hello_algo/chapter06_hashing/built_in_hash.py rename to algorithms/c01_data_structure/hashing/built_in_hash.py index 3070bfa..09b6713 100644 --- a/algorithms/hello_algo/chapter06_hashing/built_in_hash.py +++ b/algorithms/c01_data_structure/hashing/built_in_hash.py @@ -1,14 +1,13 @@ """ File: built_in_hash.py Created Time: 2023-06-15 -Author: Krahets (krahets@163.com) """ import sys from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import ListNode +from algorithms.models import ListNode """Driver Code""" if __name__ == "__main__": diff --git a/algorithms/hello_algo/chapter06_hashing/hash_map.py b/algorithms/c01_data_structure/hashing/hash_map.py similarity index 95% rename from algorithms/hello_algo/chapter06_hashing/hash_map.py rename to algorithms/c01_data_structure/hashing/hash_map.py index b2ca690..a9d23af 100644 --- a/algorithms/hello_algo/chapter06_hashing/hash_map.py +++ b/algorithms/c01_data_structure/hashing/hash_map.py @@ -8,7 +8,7 @@ from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import print_dict +from algorithms.models import print_dict """Driver Code""" if __name__ == "__main__": diff --git a/algorithms/hello_algo/chapter06_hashing/hash_map_chaining.py b/algorithms/c01_data_structure/hashing/hash_map_chaining.py similarity index 97% rename from algorithms/hello_algo/chapter06_hashing/hash_map_chaining.py rename to algorithms/c01_data_structure/hashing/hash_map_chaining.py index 733b867..448ee2c 100644 --- a/algorithms/hello_algo/chapter06_hashing/hash_map_chaining.py +++ b/algorithms/c01_data_structure/hashing/hash_map_chaining.py @@ -1,14 +1,13 @@ """ File: hash_map_chaining.py Created Time: 2023-06-13 -Author: Krahets (krahets@163.com) """ import sys from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.chapter06_hashing.array_hash_map import Pair +from algorithms.c01_data_structure.hashing.array_hash_map import Pair class HashMapChaining: diff --git a/algorithms/hello_algo/chapter06_hashing/hash_map_open_addressing.py b/algorithms/c01_data_structure/hashing/hash_map_open_addressing.py similarity index 97% rename from algorithms/hello_algo/chapter06_hashing/hash_map_open_addressing.py rename to algorithms/c01_data_structure/hashing/hash_map_open_addressing.py index a08fdbe..f57c916 100644 --- a/algorithms/hello_algo/chapter06_hashing/hash_map_open_addressing.py +++ b/algorithms/c01_data_structure/hashing/hash_map_open_addressing.py @@ -1,14 +1,13 @@ """ File: hash_map_open_addressing.py Created Time: 2023-06-13 -Author: Krahets (krahets@163.com) """ import sys from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.chapter06_hashing.array_hash_map import Pair +from algorithms.c01_data_structure.hashing.array_hash_map import Pair class HashMapOpenAddressing: diff --git a/algorithms/hello_algo/chapter06_hashing/simple_hash.py b/algorithms/c01_data_structure/hashing/simple_hash.py similarity index 96% rename from algorithms/hello_algo/chapter06_hashing/simple_hash.py rename to algorithms/c01_data_structure/hashing/simple_hash.py index e63c182..c1a02e1 100644 --- a/algorithms/hello_algo/chapter06_hashing/simple_hash.py +++ b/algorithms/c01_data_structure/hashing/simple_hash.py @@ -1,7 +1,6 @@ """ File: simple_hash.py Created Time: 2023-06-15 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/c01_linear/linkedlist/__init__.py b/algorithms/c01_data_structure/linkedlist/__init__.py similarity index 100% rename from algorithms/c01_linear/linkedlist/__init__.py rename to algorithms/c01_data_structure/linkedlist/__init__.py diff --git a/algorithms/c01_linear/linkedlist/linked_list_double.py b/algorithms/c01_data_structure/linkedlist/linked_list_double.py similarity index 96% rename from algorithms/c01_linear/linkedlist/linked_list_double.py rename to algorithms/c01_data_structure/linkedlist/linked_list_double.py index 414d099..f694991 100644 --- a/algorithms/c01_linear/linkedlist/linked_list_double.py +++ b/algorithms/c01_data_structure/linkedlist/linked_list_double.py @@ -2,7 +2,7 @@ """ 双向链表数据结构 """ -from algorithms.c01_linear import NodeDouble +from algorithms.c01_data_structure import NodeDouble class LinkedListDouble: diff --git a/algorithms/c01_linear/linkedlist/linked_list_double_cycle.py b/algorithms/c01_data_structure/linkedlist/linked_list_double_cycle.py similarity index 96% rename from algorithms/c01_linear/linkedlist/linked_list_double_cycle.py rename to algorithms/c01_data_structure/linkedlist/linked_list_double_cycle.py index a988215..2241a61 100644 --- a/algorithms/c01_linear/linkedlist/linked_list_double_cycle.py +++ b/algorithms/c01_data_structure/linkedlist/linked_list_double_cycle.py @@ -2,7 +2,7 @@ """ 双向循环链表数据结构 """ -from algorithms.c01_linear import NodeDouble +from algorithms.c01_data_structure import NodeDouble class LinkedListDouble: diff --git a/algorithms/c01_linear/linkedlist/linked_list_single.py b/algorithms/c01_data_structure/linkedlist/linked_list_single.py similarity index 95% rename from algorithms/c01_linear/linkedlist/linked_list_single.py rename to algorithms/c01_data_structure/linkedlist/linked_list_single.py index d1b1b30..0579f23 100644 --- a/algorithms/c01_linear/linkedlist/linked_list_single.py +++ b/algorithms/c01_data_structure/linkedlist/linked_list_single.py @@ -2,7 +2,7 @@ """ 单向链表数据结构 """ -from algorithms.c01_linear import Node +from algorithms.c01_data_structure import Node class LinkedListSingle: @@ -82,4 +82,4 @@ def __iter__(self): node = node.next def print(self): - print(list(x for x in self)) \ No newline at end of file + print(list(x for x in self)) diff --git a/algorithms/c01_linear/linkedlist/linked_list_single_cycle.py b/algorithms/c01_data_structure/linkedlist/linked_list_single_cycle.py similarity index 96% rename from algorithms/c01_linear/linkedlist/linked_list_single_cycle.py rename to algorithms/c01_data_structure/linkedlist/linked_list_single_cycle.py index 9a73142..2d07470 100644 --- a/algorithms/c01_linear/linkedlist/linked_list_single_cycle.py +++ b/algorithms/c01_data_structure/linkedlist/linked_list_single_cycle.py @@ -2,7 +2,7 @@ """ 单向循环链表数据结构 """ -from algorithms.c01_linear import Node +from algorithms.c01_data_structure import Node class LinkedListSingleCycle: diff --git a/algorithms/c01_linear/linkedlist/lru_cache.py b/algorithms/c01_data_structure/linkedlist/lru_cache.py similarity index 86% rename from algorithms/c01_linear/linkedlist/lru_cache.py rename to algorithms/c01_data_structure/linkedlist/lru_cache.py index a1ce6af..5f29ece 100644 --- a/algorithms/c01_linear/linkedlist/lru_cache.py +++ b/algorithms/c01_data_structure/linkedlist/lru_cache.py @@ -11,8 +11,8 @@ 2.1 如果此时缓存未满,则将此结点直接插入到链表的头部; 2.2 如果此时缓存已满,则链表尾结点删除,将新的数据结点插入链表的头部。 """ -from algorithms.c01_linear import Node -from algorithms.c01_linear.linkedlist.linked_list_single import LinkedListSingle +from algorithms.c01_data_structure import Node +from algorithms.c01_data_structure.linkedlist.linked_list_single import LinkedListSingle def lru(list_single_, data): @@ -22,7 +22,7 @@ def lru(list_single_, data): list_single_.insert(list_single_.head, find_node) else: if not list_single_.is_full(): - list_single_.insert(list_single_.head, new_node = Node(data)) + list_single_.insert(list_single_.head, new_node=Node(data)) else: tail = list_single_.get_tail() new_node = Node(data) diff --git a/algorithms/c01_linear/linkedlist/palindromic_number.py b/algorithms/c01_data_structure/linkedlist/palindromic_number.py similarity index 87% rename from algorithms/c01_linear/linkedlist/palindromic_number.py rename to algorithms/c01_data_structure/linkedlist/palindromic_number.py index 7ba3720..51582b2 100644 --- a/algorithms/c01_linear/linkedlist/palindromic_number.py +++ b/algorithms/c01_data_structure/linkedlist/palindromic_number.py @@ -14,8 +14,8 @@ 1.2.1 如果是返回上中位数,后半部分串头取next <<=这里使用这张上中位数数 1.2.2 如果是返回下中位数,后半部分串头既是当前节点位置,但前半部分串尾要删除掉当前节点 """ -from algorithms.c01_linear import Node -from algorithms.c01_linear.linkedlist.linked_list_single import LinkedListSingle +from algorithms.c01_data_structure import Node +from algorithms.c01_data_structure.linkedlist.linked_list_single import LinkedListSingle def palindromic(list_single_): @@ -25,17 +25,17 @@ def palindromic(list_single_): return list_single_.head.next.data == list_single_.head.next.next.data slow = list_single_.head.next.next # slow指向第2个节点 - slow_next = slow.next # 保存下一步的slow后驱节点 - fast = slow.next # fast指向第3个节点 + slow_next = slow.next # 保存下一步的slow后驱节点 + fast = slow.next # fast指向第3个节点 slow.next = list_single_.head.next # 第一个slow指针反向 list_single_.head.next.next = None # 第一个节点下一个指针初始化为None while fast.next and fast.next.next: # 还能继续往前跑 fast = fast.next.next # 快指针先往后面走2步 - slow_pre = slow # 临时保存slow - slow = slow_next # slow往后走1步 + slow_pre = slow # 临时保存slow + slow = slow_next # slow往后走1步 slow_next = slow.next # 保存slow下一步的后驱节点 - slow.next = slow_pre # 将slow节点的next反转 + slow.next = slow_pre # 将slow节点的next反转 if not fast.next: # 奇数情况 # 左边指针从slow.next开始,右边指针从slow_next开始 slow = slow.next diff --git a/algorithms/c01_linear/queue/__init__.py b/algorithms/c01_data_structure/queue/__init__.py similarity index 98% rename from algorithms/c01_linear/queue/__init__.py rename to algorithms/c01_data_structure/queue/__init__.py index dbc8407..4920954 100644 --- a/algorithms/c01_linear/queue/__init__.py +++ b/algorithms/c01_data_structure/queue/__init__.py @@ -2,4 +2,3 @@ """ description... """ - diff --git a/algorithms/hello_algo/chapter05_stack_and_queue/array_deque.py b/algorithms/c01_data_structure/queue/array_deque.py similarity index 99% rename from algorithms/hello_algo/chapter05_stack_and_queue/array_deque.py rename to algorithms/c01_data_structure/queue/array_deque.py index 308f8e7..ffd0faf 100644 --- a/algorithms/hello_algo/chapter05_stack_and_queue/array_deque.py +++ b/algorithms/c01_data_structure/queue/array_deque.py @@ -1,7 +1,6 @@ """ File: array_deque.py Created Time: 2023-03-01 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/chapter05_stack_and_queue/array_queue.py b/algorithms/c01_data_structure/queue/array_queue.py similarity index 100% rename from algorithms/hello_algo/chapter05_stack_and_queue/array_queue.py rename to algorithms/c01_data_structure/queue/array_queue.py diff --git a/algorithms/hello_algo/chapter05_stack_and_queue/deque.py b/algorithms/c01_data_structure/queue/deque.py similarity index 100% rename from algorithms/hello_algo/chapter05_stack_and_queue/deque.py rename to algorithms/c01_data_structure/queue/deque.py diff --git a/algorithms/c01_linear/queue/linked_queue.py b/algorithms/c01_data_structure/queue/linked_queue.py similarity index 96% rename from algorithms/c01_linear/queue/linked_queue.py rename to algorithms/c01_data_structure/queue/linked_queue.py index 1ae58d7..9d10fc0 100644 --- a/algorithms/c01_linear/queue/linked_queue.py +++ b/algorithms/c01_data_structure/queue/linked_queue.py @@ -2,7 +2,7 @@ """基于链表实现的一个简单队列 队尾插入元素,队头取元素。就跟在菜市场排队买菜原理是一样的 """ -from algorithms.c01_linear import Node +from algorithms.c01_data_structure import Node class LinkedQueue: diff --git a/algorithms/hello_algo/chapter05_stack_and_queue/linkedlist_deque.py b/algorithms/c01_data_structure/queue/linkedlist_deque.py similarity index 99% rename from algorithms/hello_algo/chapter05_stack_and_queue/linkedlist_deque.py rename to algorithms/c01_data_structure/queue/linkedlist_deque.py index e4e42fc..b47963c 100644 --- a/algorithms/hello_algo/chapter05_stack_and_queue/linkedlist_deque.py +++ b/algorithms/c01_data_structure/queue/linkedlist_deque.py @@ -1,7 +1,6 @@ """ File: linkedlist_deque.py Created Time: 2023-03-01 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/chapter05_stack_and_queue/linkedlist_queue.py b/algorithms/c01_data_structure/queue/linkedlist_queue.py similarity index 97% rename from algorithms/hello_algo/chapter05_stack_and_queue/linkedlist_queue.py rename to algorithms/c01_data_structure/queue/linkedlist_queue.py index 16b6a67..58f1794 100644 --- a/algorithms/hello_algo/chapter05_stack_and_queue/linkedlist_queue.py +++ b/algorithms/c01_data_structure/queue/linkedlist_queue.py @@ -8,7 +8,7 @@ from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import ListNode +from algorithms.models import ListNode class LinkedListQueue: diff --git a/algorithms/c01_linear/queue/prior_queue.py b/algorithms/c01_data_structure/queue/prior_queue.py similarity index 97% rename from algorithms/c01_linear/queue/prior_queue.py rename to algorithms/c01_data_structure/queue/prior_queue.py index 51c138a..daf0ed5 100644 --- a/algorithms/c01_linear/queue/prior_queue.py +++ b/algorithms/c01_data_structure/queue/prior_queue.py @@ -4,7 +4,7 @@ """ from functools import total_ordering -from algorithms.c01_linear.stack.stack_linked_list import LinkedStack +from algorithms.c01_data_structure.stack.stack_linked_list import LinkedStack class MaxPriorQueue: diff --git a/algorithms/hello_algo/chapter05_stack_and_queue/queue.py b/algorithms/c01_data_structure/queue/queue.py similarity index 100% rename from algorithms/hello_algo/chapter05_stack_and_queue/queue.py rename to algorithms/c01_data_structure/queue/queue.py diff --git a/algorithms/c01_linear/stack/__init__.py b/algorithms/c01_data_structure/stack/__init__.py similarity index 98% rename from algorithms/c01_linear/stack/__init__.py rename to algorithms/c01_data_structure/stack/__init__.py index 259323b..c0053c9 100644 --- a/algorithms/c01_linear/stack/__init__.py +++ b/algorithms/c01_data_structure/stack/__init__.py @@ -5,4 +5,3 @@ LeetCode题目: 20,155,224,232,496,682,844 """ - diff --git a/algorithms/hello_algo/chapter05_stack_and_queue/array_stack.py b/algorithms/c01_data_structure/stack/array_stack.py similarity index 100% rename from algorithms/hello_algo/chapter05_stack_and_queue/array_stack.py rename to algorithms/c01_data_structure/stack/array_stack.py diff --git a/algorithms/hello_algo/chapter05_stack_and_queue/linkedlist_stack.py b/algorithms/c01_data_structure/stack/linkedlist_stack.py similarity index 97% rename from algorithms/hello_algo/chapter05_stack_and_queue/linkedlist_stack.py rename to algorithms/c01_data_structure/stack/linkedlist_stack.py index 5ecd9c5..34cf9ea 100644 --- a/algorithms/hello_algo/chapter05_stack_and_queue/linkedlist_stack.py +++ b/algorithms/c01_data_structure/stack/linkedlist_stack.py @@ -8,7 +8,7 @@ from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import ListNode +from algorithms.models import ListNode class LinkedListStack: diff --git a/algorithms/hello_algo/chapter05_stack_and_queue/stack.py b/algorithms/c01_data_structure/stack/stack.py similarity index 100% rename from algorithms/hello_algo/chapter05_stack_and_queue/stack.py rename to algorithms/c01_data_structure/stack/stack.py diff --git a/algorithms/c01_linear/stack/stack_array.py b/algorithms/c01_data_structure/stack/stack_array.py similarity index 94% rename from algorithms/c01_linear/stack/stack_array.py rename to algorithms/c01_data_structure/stack/stack_array.py index 029f53a..8936f42 100644 --- a/algorithms/c01_linear/stack/stack_array.py +++ b/algorithms/c01_data_structure/stack/stack_array.py @@ -2,7 +2,7 @@ """ 基于数组实现的栈结构 """ -from algorithms.c01_linear import Node +from algorithms.c01_data_structure import Node class ArrayStack: @@ -42,6 +42,7 @@ def __iter__(self): while self.num > 0: yield self.pop() + if __name__ == '__main__': s = ArrayStack(3) s.push(1) @@ -51,4 +52,4 @@ def __iter__(self): print(s.pop()) print(s.pop()) print(s.pop()) - print("=================") \ No newline at end of file + print("=================") diff --git a/algorithms/c01_linear/stack/stack_linked_list.py b/algorithms/c01_data_structure/stack/stack_linked_list.py similarity index 96% rename from algorithms/c01_linear/stack/stack_linked_list.py rename to algorithms/c01_data_structure/stack/stack_linked_list.py index 02417bc..a733946 100644 --- a/algorithms/c01_linear/stack/stack_linked_list.py +++ b/algorithms/c01_data_structure/stack/stack_linked_list.py @@ -4,7 +4,7 @@ 另一方面,迭代器应该一直可以迭代。迭代器的 `__iter__` 方法应该返回自身。 一般可使用生成器函数实现更符合python风格的可迭代对象。 """ -from algorithms.c01_linear import Node +from algorithms.c01_data_structure import Node class LinkedStack: @@ -38,4 +38,3 @@ def peek(self): def __iter__(self): while self.n > 0: yield self.pop() - diff --git a/algorithms/c01_linear/queue/array_queue.py b/algorithms/c01_linear/queue/array_queue.py deleted file mode 100644 index 4958614..0000000 --- a/algorithms/c01_linear/queue/array_queue.py +++ /dev/null @@ -1,64 +0,0 @@ -# -*- encoding: utf-8 -*- -"""基于环形数组实现的一个简单队列 -数组A[1..n]实现最多容纳n-1个元素的队列。 -""" - - -class ArrayQueue: - def __init__(self, size): - self.head = 0 # 队头元素下标 - self.tail = 0 # 下一个插入位置 - self._arr = [None] * size # 实际存放数据的数组 - - def is_empty(self): - return self.head == self.tail - - def is_full(self): - return self.size() == len(self._arr) - 1 - - def size(self): - return (len(self._arr) + self.tail - self.head) % len(self._arr) - - def enqueue(self, item): - # 队列满了则抛出异常 - if self.is_full(): - raise LookupError('Queue is full') - self._arr[self.tail] = item - self.tail = (self.tail + 1) % len(self._arr) - - def dequeue(self): - # 队列空则抛出异常 - if self.is_empty(): - raise LookupError('Queue underflow') - item = self._arr[self.head] - self._arr[self.head] = None - self.head = (self.head + 1) % len(self._arr) - return item - - def __iter__(self): - while not self.is_empty(): - yield self.dequeue() - - -if __name__ == '__main__': - q = ArrayQueue(6) - q.enqueue(1) - q.enqueue(2) - q.enqueue(3) - q.enqueue(4) - q.enqueue(5) - print(q.dequeue()) - print(q.dequeue()) - print(q.dequeue()) - print(q.dequeue()) - print(q.dequeue()) - q.enqueue(1) - q.enqueue(2) - q.enqueue(3) - q.enqueue(4) - q.enqueue(5) - print(q.dequeue()) - print(q.dequeue()) - print(q.dequeue()) - print(q.dequeue()) - print(q.dequeue()) diff --git a/algorithms/c04_tree/__init__.py b/algorithms/c02_tree/__init__.py similarity index 100% rename from algorithms/c04_tree/__init__.py rename to algorithms/c02_tree/__init__.py diff --git a/algorithms/hello_algo/chapter07_tree/array_binary_tree.py b/algorithms/c02_tree/array_binary_tree.py similarity index 96% rename from algorithms/hello_algo/chapter07_tree/array_binary_tree.py rename to algorithms/c02_tree/array_binary_tree.py index f20c655..5d262a1 100644 --- a/algorithms/hello_algo/chapter07_tree/array_binary_tree.py +++ b/algorithms/c02_tree/array_binary_tree.py @@ -1,14 +1,13 @@ """ File: array_binary_tree.py Created Time: 2023-07-19 -Author: Krahets (krahets@163.com) """ import sys from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import TreeNode, list_to_tree, print_tree +from algorithms.models import list_to_tree, print_tree class ArrayBinaryTree: diff --git a/algorithms/hello_algo/chapter07_tree/avl_tree.py b/algorithms/c02_tree/avl_tree.py similarity index 99% rename from algorithms/hello_algo/chapter07_tree/avl_tree.py rename to algorithms/c02_tree/avl_tree.py index e1216c4..2a29a16 100644 --- a/algorithms/hello_algo/chapter07_tree/avl_tree.py +++ b/algorithms/c02_tree/avl_tree.py @@ -8,7 +8,7 @@ from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import TreeNode, print_tree +from algorithms.models import TreeNode, print_tree class AVLTree: diff --git a/algorithms/hello_algo/chapter07_tree/binary_search_tree.py b/algorithms/c02_tree/binary_search_tree.py similarity index 98% rename from algorithms/hello_algo/chapter07_tree/binary_search_tree.py rename to algorithms/c02_tree/binary_search_tree.py index f6c489d..0a6eb9d 100644 --- a/algorithms/hello_algo/chapter07_tree/binary_search_tree.py +++ b/algorithms/c02_tree/binary_search_tree.py @@ -8,7 +8,7 @@ from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import TreeNode, print_tree +from algorithms.models import TreeNode, print_tree class BinarySearchTree: diff --git a/algorithms/hello_algo/chapter07_tree/binary_tree.py b/algorithms/c02_tree/binary_tree.py similarity index 92% rename from algorithms/hello_algo/chapter07_tree/binary_tree.py rename to algorithms/c02_tree/binary_tree.py index e115fd0..674ee14 100644 --- a/algorithms/hello_algo/chapter07_tree/binary_tree.py +++ b/algorithms/c02_tree/binary_tree.py @@ -8,7 +8,7 @@ from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import TreeNode, print_tree +from algorithms.models import TreeNode, print_tree """Driver Code""" if __name__ == "__main__": diff --git a/algorithms/hello_algo/chapter07_tree/binary_tree_bfs.py b/algorithms/c02_tree/binary_tree_bfs.py similarity index 93% rename from algorithms/hello_algo/chapter07_tree/binary_tree_bfs.py rename to algorithms/c02_tree/binary_tree_bfs.py index db4fda0..e09765b 100644 --- a/algorithms/hello_algo/chapter07_tree/binary_tree_bfs.py +++ b/algorithms/c02_tree/binary_tree_bfs.py @@ -8,7 +8,7 @@ from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import TreeNode, list_to_tree, print_tree +from algorithms.models import TreeNode, list_to_tree, print_tree from collections import deque diff --git a/algorithms/hello_algo/chapter07_tree/binary_tree_dfs.py b/algorithms/c02_tree/binary_tree_dfs.py similarity index 95% rename from algorithms/hello_algo/chapter07_tree/binary_tree_dfs.py rename to algorithms/c02_tree/binary_tree_dfs.py index c2df87a..91b93bc 100644 --- a/algorithms/hello_algo/chapter07_tree/binary_tree_dfs.py +++ b/algorithms/c02_tree/binary_tree_dfs.py @@ -8,7 +8,7 @@ from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import TreeNode, list_to_tree, print_tree +from algorithms.models import TreeNode, list_to_tree, print_tree def pre_order(root: TreeNode | None): diff --git a/algorithms/c04_tree/bisearch_tree.py b/algorithms/c02_tree/bisearch_tree.py similarity index 100% rename from algorithms/c04_tree/bisearch_tree.py rename to algorithms/c02_tree/bisearch_tree.py diff --git a/algorithms/c04_tree/btree.py b/algorithms/c02_tree/btree.py similarity index 100% rename from algorithms/c04_tree/btree.py rename to algorithms/c02_tree/btree.py diff --git a/algorithms/hello_algo/chapter08_heap/heap.py b/algorithms/c02_tree/heap.py similarity index 95% rename from algorithms/hello_algo/chapter08_heap/heap.py rename to algorithms/c02_tree/heap.py index 1d1a5e6..3ff78a5 100644 --- a/algorithms/hello_algo/chapter08_heap/heap.py +++ b/algorithms/c02_tree/heap.py @@ -1,14 +1,13 @@ """ File: heap.py Created Time: 2023-02-23 -Author: Krahets (krahets@163.com) """ import sys from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import print_heap +from algorithms.models import print_heap import heapq diff --git a/algorithms/hello_algo/chapter08_heap/my_heap.py b/algorithms/c02_tree/my_heap.py similarity index 97% rename from algorithms/hello_algo/chapter08_heap/my_heap.py rename to algorithms/c02_tree/my_heap.py index 97a79f4..d70344a 100644 --- a/algorithms/hello_algo/chapter08_heap/my_heap.py +++ b/algorithms/c02_tree/my_heap.py @@ -1,14 +1,13 @@ """ File: my_heap.py Created Time: 2023-02-23 -Author: Krahets (krahets@163.com) """ import sys from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import print_heap +from algorithms.models import print_heap class MaxHeap: diff --git a/algorithms/c04_tree/redblack_tree.py b/algorithms/c02_tree/redblack_tree.py similarity index 99% rename from algorithms/c04_tree/redblack_tree.py rename to algorithms/c02_tree/redblack_tree.py index 6bb155c..281f937 100644 --- a/algorithms/c04_tree/redblack_tree.py +++ b/algorithms/c02_tree/redblack_tree.py @@ -10,7 +10,7 @@ 5,对每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点。 一个有n个内部结点的红黑树的高度最多为2lg(n+1) """ -from algorithms.c04_tree.bisearch_tree import treeMinimum +from algorithms.c02_tree.bisearch_tree import treeMinimum class RBTree(): diff --git a/algorithms/hello_algo/chapter08_heap/top_k.py b/algorithms/c02_tree/top_k.py similarity index 91% rename from algorithms/hello_algo/chapter08_heap/top_k.py rename to algorithms/c02_tree/top_k.py index 2de6220..9d4b468 100644 --- a/algorithms/hello_algo/chapter08_heap/top_k.py +++ b/algorithms/c02_tree/top_k.py @@ -1,14 +1,13 @@ """ File: top_k.py Created Time: 2023-06-10 -Author: Krahets (krahets@163.com) """ import sys from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import print_heap +from algorithms.models import print_heap import heapq diff --git a/algorithms/c05_graph/__init__.py b/algorithms/c03_graph/__init__.py similarity index 98% rename from algorithms/c05_graph/__init__.py rename to algorithms/c03_graph/__init__.py index f7745a6..7cc5861 100644 --- a/algorithms/c05_graph/__init__.py +++ b/algorithms/c03_graph/__init__.py @@ -2,4 +2,3 @@ """图算法 Some of description... """ - diff --git a/algorithms/hello_algo/chapter09_graph/graph_adjacency_list.py b/algorithms/c03_graph/graph_adjacency_list.py similarity index 96% rename from algorithms/hello_algo/chapter09_graph/graph_adjacency_list.py rename to algorithms/c03_graph/graph_adjacency_list.py index abff0b4..ff7f61f 100644 --- a/algorithms/hello_algo/chapter09_graph/graph_adjacency_list.py +++ b/algorithms/c03_graph/graph_adjacency_list.py @@ -1,14 +1,13 @@ """ File: graph_adjacency_list.py Created Time: 2023-02-23 -Author: Krahets (krahets@163.com) """ import sys from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import Vertex, vals_to_vets +from algorithms.models import Vertex, vals_to_vets class GraphAdjList: diff --git a/algorithms/hello_algo/chapter09_graph/graph_adjacency_matrix.py b/algorithms/c03_graph/graph_adjacency_matrix.py similarity index 97% rename from algorithms/hello_algo/chapter09_graph/graph_adjacency_matrix.py rename to algorithms/c03_graph/graph_adjacency_matrix.py index d2db803..d9afd01 100644 --- a/algorithms/hello_algo/chapter09_graph/graph_adjacency_matrix.py +++ b/algorithms/c03_graph/graph_adjacency_matrix.py @@ -1,14 +1,13 @@ """ File: graph_adjacency_matrix.py Created Time: 2023-02-23 -Author: Krahets (krahets@163.com) """ import sys from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import Vertex, print_matrix +from algorithms.models import print_matrix class GraphAdjMat: diff --git a/algorithms/hello_algo/chapter09_graph/graph_bfs.py b/algorithms/c03_graph/graph_bfs.py similarity index 94% rename from algorithms/hello_algo/chapter09_graph/graph_bfs.py rename to algorithms/c03_graph/graph_bfs.py index dffd532..2ff4281 100644 --- a/algorithms/hello_algo/chapter09_graph/graph_bfs.py +++ b/algorithms/c03_graph/graph_bfs.py @@ -1,14 +1,13 @@ """ File: graph_bfs.py Created Time: 2023-02-23 -Author: Krahets (krahets@163.com) """ import sys from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import Vertex, vals_to_vets, vets_to_vals +from algorithms.models import Vertex, vals_to_vets, vets_to_vals from collections import deque from graph_adjacency_list import GraphAdjList diff --git a/algorithms/hello_algo/chapter09_graph/graph_dfs.py b/algorithms/c03_graph/graph_dfs.py similarity index 93% rename from algorithms/hello_algo/chapter09_graph/graph_dfs.py rename to algorithms/c03_graph/graph_dfs.py index 43c5f4d..d455b37 100644 --- a/algorithms/hello_algo/chapter09_graph/graph_dfs.py +++ b/algorithms/c03_graph/graph_dfs.py @@ -1,14 +1,13 @@ """ File: graph_dfs.py Created Time: 2023-02-23 -Author: Krahets (krahets@163.com) """ import sys from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import Vertex, vets_to_vals, vals_to_vets +from algorithms.models import Vertex, vets_to_vals, vals_to_vets from graph_adjacency_list import GraphAdjList diff --git a/algorithms/c02_sort/__init__.py b/algorithms/c04_sort/__init__.py similarity index 100% rename from algorithms/c02_sort/__init__.py rename to algorithms/c04_sort/__init__.py diff --git a/algorithms/c02_sort/base/__init__.py b/algorithms/c04_sort/base/__init__.py similarity index 100% rename from algorithms/c02_sort/base/__init__.py rename to algorithms/c04_sort/base/__init__.py diff --git a/algorithms/c02_sort/base/sortutil.py b/algorithms/c04_sort/base/sortutil.py similarity index 100% rename from algorithms/c02_sort/base/sortutil.py rename to algorithms/c04_sort/base/sortutil.py diff --git a/algorithms/c02_sort/base/template.py b/algorithms/c04_sort/base/template.py similarity index 100% rename from algorithms/c02_sort/base/template.py rename to algorithms/c04_sort/base/template.py diff --git a/algorithms/hello_algo/chapter11_sorting/bubble_sort.py b/algorithms/c04_sort/bubble_sort.py similarity index 100% rename from algorithms/hello_algo/chapter11_sorting/bubble_sort.py rename to algorithms/c04_sort/bubble_sort.py diff --git a/algorithms/hello_algo/chapter11_sorting/bucket_sort.py b/algorithms/c04_sort/bucket_sort.py similarity index 96% rename from algorithms/hello_algo/chapter11_sorting/bucket_sort.py rename to algorithms/c04_sort/bucket_sort.py index 764a123..8ff7d79 100644 --- a/algorithms/hello_algo/chapter11_sorting/bucket_sort.py +++ b/algorithms/c04_sort/bucket_sort.py @@ -1,7 +1,6 @@ """ File: bucket_sort.py Created Time: 2023-03-30 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/chapter11_sorting/counting_sort.py b/algorithms/c04_sort/counting_sort.py similarity index 98% rename from algorithms/hello_algo/chapter11_sorting/counting_sort.py rename to algorithms/c04_sort/counting_sort.py index 8f249ac..ffe4159 100644 --- a/algorithms/hello_algo/chapter11_sorting/counting_sort.py +++ b/algorithms/c04_sort/counting_sort.py @@ -1,7 +1,6 @@ """ File: counting_sort.py Created Time: 2023-03-21 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/chapter11_sorting/heap_sort.py b/algorithms/c04_sort/heap_sort.py similarity index 97% rename from algorithms/hello_algo/chapter11_sorting/heap_sort.py rename to algorithms/c04_sort/heap_sort.py index 405d75f..bcfbdf7 100644 --- a/algorithms/hello_algo/chapter11_sorting/heap_sort.py +++ b/algorithms/c04_sort/heap_sort.py @@ -1,7 +1,6 @@ """ File: heap_sort.py Created Time: 2023-05-24 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/chapter11_sorting/insertion_sort.py b/algorithms/c04_sort/insertion_sort.py similarity index 100% rename from algorithms/hello_algo/chapter11_sorting/insertion_sort.py rename to algorithms/c04_sort/insertion_sort.py diff --git a/algorithms/c02_sort/m00_bubble_sort.py b/algorithms/c04_sort/m00_bubble_sort.py similarity index 93% rename from algorithms/c02_sort/m00_bubble_sort.py rename to algorithms/c04_sort/m00_bubble_sort.py index 516c0dd..866af42 100644 --- a/algorithms/c02_sort/m00_bubble_sort.py +++ b/algorithms/c04_sort/m00_bubble_sort.py @@ -6,7 +6,7 @@ 算法复杂度:N^2 稳定排序:重复元素排序完后仍然保持原来的相对位置。 """ -from algorithms.c02_sort.base.template import SortTemplate +from algorithms.c04_sort.base.template import SortTemplate class BubbleSort(SortTemplate): diff --git a/algorithms/c02_sort/m01_insert_sort.py b/algorithms/c04_sort/m01_insert_sort.py similarity index 91% rename from algorithms/c02_sort/m01_insert_sort.py rename to algorithms/c04_sort/m01_insert_sort.py index abb2428..2788c7b 100644 --- a/algorithms/c02_sort/m01_insert_sort.py +++ b/algorithms/c04_sort/m01_insert_sort.py @@ -14,8 +14,8 @@ 算法复杂度:N^2 稳定排序:重复元素排序完后仍然保持原来的相对位置。 """ -from algorithms.c02_sort.base.sortutil import insert_sort -from algorithms.c02_sort.base.template import SortTemplate +from algorithms.c04_sort.base.sortutil import insert_sort +from algorithms.c04_sort.base.template import SortTemplate class InsertSort(SortTemplate): diff --git a/algorithms/c02_sort/m02_select_sort.py b/algorithms/c04_sort/m02_select_sort.py similarity index 94% rename from algorithms/c02_sort/m02_select_sort.py rename to algorithms/c04_sort/m02_select_sort.py index 693b5b6..48ed271 100644 --- a/algorithms/c02_sort/m02_select_sort.py +++ b/algorithms/c04_sort/m02_select_sort.py @@ -8,7 +8,7 @@ 不稳定排序,使用场景少。 复杂度:O(N^2),大约需要N^2/2次比较和N次交换。 """ -from algorithms.c02_sort.base.template import SortTemplate +from algorithms.c04_sort.base.template import SortTemplate class SelectSort(SortTemplate): diff --git a/algorithms/c02_sort/m03_merge_sort.py b/algorithms/c04_sort/m03_merge_sort.py similarity index 97% rename from algorithms/c02_sort/m03_merge_sort.py rename to algorithms/c04_sort/m03_merge_sort.py index bf427ab..d358f32 100644 --- a/algorithms/c02_sort/m03_merge_sort.py +++ b/algorithms/c04_sort/m03_merge_sort.py @@ -10,7 +10,7 @@ 它有一个致命的“弱点”,那就是归并排序不是原地排序算法。 """ -from algorithms.c02_sort.base.template import SortTemplate +from algorithms.c04_sort.base.template import SortTemplate class MergeSort(SortTemplate): diff --git a/algorithms/c02_sort/m04_merge_insert_sort.py b/algorithms/c04_sort/m04_merge_insert_sort.py similarity index 96% rename from algorithms/c02_sort/m04_merge_insert_sort.py rename to algorithms/c04_sort/m04_merge_insert_sort.py index 03a453b..c245e28 100644 --- a/algorithms/c02_sort/m04_merge_insert_sort.py +++ b/algorithms/c04_sort/m04_merge_insert_sort.py @@ -20,8 +20,8 @@ """ from math import log -from algorithms.c02_sort.base.sortutil import insert_sort -from algorithms.c02_sort.base.template import SortTemplate +from algorithms.c04_sort.base.sortutil import insert_sort +from algorithms.c04_sort.base.template import SortTemplate class MergeAndInsertSort(SortTemplate): diff --git a/algorithms/c02_sort/m05_quick_sort.py b/algorithms/c04_sort/m05_quick_sort.py similarity index 97% rename from algorithms/c02_sort/m05_quick_sort.py rename to algorithms/c04_sort/m05_quick_sort.py index 0904519..fa677c1 100644 --- a/algorithms/c02_sort/m05_quick_sort.py +++ b/algorithms/c04_sort/m05_quick_sort.py @@ -17,7 +17,7 @@ """ from random import randint -from algorithms.c02_sort.base.template import SortTemplate +from algorithms.c04_sort.base.template import SortTemplate class QuickSort(SortTemplate): diff --git a/algorithms/c02_sort/m06_heap_sort.py b/algorithms/c04_sort/m06_heap_sort.py similarity index 97% rename from algorithms/c02_sort/m06_heap_sort.py rename to algorithms/c04_sort/m06_heap_sort.py index 2cf3eef..298222c 100644 --- a/algorithms/c02_sort/m06_heap_sort.py +++ b/algorithms/c04_sort/m06_heap_sort.py @@ -2,7 +2,7 @@ """使用二叉堆实现堆排序最优雅代码 原理:如果左右子树都已经是最大堆了,则通过下沉当前根节点操作即可重新构造为一个最大堆。 """ -from algorithms.c02_sort.base.template import SortTemplate +from algorithms.c04_sort.base.template import SortTemplate class HeapSort(SortTemplate): diff --git a/algorithms/c02_sort/m07_count_sort.py b/algorithms/c04_sort/m07_count_sort.py similarity index 100% rename from algorithms/c02_sort/m07_count_sort.py rename to algorithms/c04_sort/m07_count_sort.py diff --git a/algorithms/c02_sort/m08_radix_sort.py b/algorithms/c04_sort/m08_radix_sort.py similarity index 100% rename from algorithms/c02_sort/m08_radix_sort.py rename to algorithms/c04_sort/m08_radix_sort.py diff --git a/algorithms/c02_sort/m09_bucket_sort.py b/algorithms/c04_sort/m09_bucket_sort.py similarity index 94% rename from algorithms/c02_sort/m09_bucket_sort.py rename to algorithms/c04_sort/m09_bucket_sort.py index a5fcb1f..45dfaec 100644 --- a/algorithms/c02_sort/m09_bucket_sort.py +++ b/algorithms/c04_sort/m09_bucket_sort.py @@ -11,7 +11,7 @@ """ from math import floor -from algorithms.c02_sort.base.sortutil import insert_sort +from algorithms.c04_sort.base.sortutil import insert_sort def bucketSort(A): diff --git a/algorithms/c02_sort/m10_find_minmax.py b/algorithms/c04_sort/m10_find_minmax.py similarity index 100% rename from algorithms/c02_sort/m10_find_minmax.py rename to algorithms/c04_sort/m10_find_minmax.py diff --git a/algorithms/c02_sort/m11_imin_select.py b/algorithms/c04_sort/m11_imin_select.py similarity index 100% rename from algorithms/c02_sort/m11_imin_select.py rename to algorithms/c04_sort/m11_imin_select.py diff --git a/algorithms/c02_sort/m12_imin_select2.py b/algorithms/c04_sort/m12_imin_select2.py similarity index 97% rename from algorithms/c02_sort/m12_imin_select2.py rename to algorithms/c04_sort/m12_imin_select2.py index 727f120..3ffddfa 100644 --- a/algorithms/c02_sort/m12_imin_select2.py +++ b/algorithms/c04_sort/m12_imin_select2.py @@ -6,7 +6,7 @@ Desc : 顺序统计量的选择算法(最坏情况下O(n)) 利用中位数的中位数作为pivot划分数组 """ -from algorithms.c02_sort.base.sortutil import insert_sort +from algorithms.c04_sort.base.sortutil import insert_sort def iminSelect2(A, i): diff --git a/algorithms/c02_sort/m13_imin_list.py b/algorithms/c04_sort/m13_imin_list.py similarity index 94% rename from algorithms/c02_sort/m13_imin_list.py rename to algorithms/c04_sort/m13_imin_list.py index 1a04ac5..86cd86f 100644 --- a/algorithms/c02_sort/m13_imin_list.py +++ b/algorithms/c04_sort/m13_imin_list.py @@ -7,7 +7,7 @@ 先通过找到第i小的数,然后将这个数作为pivot去划分这个数组, 左边 + 这个pivot即是解 """ -from algorithms.c02_sort.m12_imin_select2 import iminSelect2 +from algorithms.c04_sort.m12_imin_select2 import iminSelect2 def iminList(A, i): diff --git a/algorithms/hello_algo/chapter11_sorting/merge_sort.py b/algorithms/c04_sort/merge_sort.py similarity index 96% rename from algorithms/hello_algo/chapter11_sorting/merge_sort.py rename to algorithms/c04_sort/merge_sort.py index 33dc93a..8fdf1be 100644 --- a/algorithms/hello_algo/chapter11_sorting/merge_sort.py +++ b/algorithms/c04_sort/merge_sort.py @@ -1,7 +1,6 @@ """ File: merge_sort.py Created Time: 2022-11-25 -Author: timi (xisunyy@163.com), Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/chapter11_sorting/quick_sort.py b/algorithms/c04_sort/quick_sort.py similarity index 100% rename from algorithms/hello_algo/chapter11_sorting/quick_sort.py rename to algorithms/c04_sort/quick_sort.py diff --git a/algorithms/hello_algo/chapter11_sorting/radix_sort.py b/algorithms/c04_sort/radix_sort.py similarity index 98% rename from algorithms/hello_algo/chapter11_sorting/radix_sort.py rename to algorithms/c04_sort/radix_sort.py index a3b534c..7ce90da 100644 --- a/algorithms/hello_algo/chapter11_sorting/radix_sort.py +++ b/algorithms/c04_sort/radix_sort.py @@ -1,7 +1,6 @@ """ File: radix_sort.py Created Time: 2023-03-26 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/chapter11_sorting/selection_sort.py b/algorithms/c04_sort/selection_sort.py similarity index 95% rename from algorithms/hello_algo/chapter11_sorting/selection_sort.py rename to algorithms/c04_sort/selection_sort.py index f4f8061..136832b 100644 --- a/algorithms/hello_algo/chapter11_sorting/selection_sort.py +++ b/algorithms/c04_sort/selection_sort.py @@ -1,7 +1,6 @@ """ File: selection_sort.py Created Time: 2023-05-22 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/c03_search/__init__.py b/algorithms/c05_search/__init__.py similarity index 100% rename from algorithms/c03_search/__init__.py rename to algorithms/c05_search/__init__.py diff --git a/algorithms/hello_algo/chapter10_searching/binary_search.py b/algorithms/c05_search/binary_search.py similarity index 100% rename from algorithms/hello_algo/chapter10_searching/binary_search.py rename to algorithms/c05_search/binary_search.py diff --git a/algorithms/hello_algo/chapter10_searching/binary_search_edge.py b/algorithms/c05_search/binary_search_edge.py similarity index 97% rename from algorithms/hello_algo/chapter10_searching/binary_search_edge.py rename to algorithms/c05_search/binary_search_edge.py index 5e4589a..da0cacc 100644 --- a/algorithms/hello_algo/chapter10_searching/binary_search_edge.py +++ b/algorithms/c05_search/binary_search_edge.py @@ -1,7 +1,6 @@ """ File: binary_search_edge.py Created Time: 2023-08-04 -Author: Krahets (krahets@163.com) """ import sys diff --git a/algorithms/hello_algo/chapter10_searching/binary_search_insertion.py b/algorithms/c05_search/binary_search_insertion.py similarity index 98% rename from algorithms/hello_algo/chapter10_searching/binary_search_insertion.py rename to algorithms/c05_search/binary_search_insertion.py index 3d0ef4d..abff2c5 100644 --- a/algorithms/hello_algo/chapter10_searching/binary_search_insertion.py +++ b/algorithms/c05_search/binary_search_insertion.py @@ -1,7 +1,6 @@ """ File: binary_search_insertion.py Created Time: 2023-08-04 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/chapter10_searching/hashing_search.py b/algorithms/c05_search/hashing_search.py similarity index 95% rename from algorithms/hello_algo/chapter10_searching/hashing_search.py rename to algorithms/c05_search/hashing_search.py index febc170..013c20c 100644 --- a/algorithms/hello_algo/chapter10_searching/hashing_search.py +++ b/algorithms/c05_search/hashing_search.py @@ -8,7 +8,7 @@ from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import ListNode, list_to_linked_list +from algorithms.models import ListNode, list_to_linked_list def hashing_search_array(hmap: dict[int, int], target: int) -> int: diff --git a/algorithms/hello_algo/chapter10_searching/linear_search.py b/algorithms/c05_search/linear_search.py similarity index 94% rename from algorithms/hello_algo/chapter10_searching/linear_search.py rename to algorithms/c05_search/linear_search.py index 8395204..f2e17f8 100644 --- a/algorithms/hello_algo/chapter10_searching/linear_search.py +++ b/algorithms/c05_search/linear_search.py @@ -8,7 +8,7 @@ from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import ListNode, list_to_linked_list +from algorithms.models import ListNode, list_to_linked_list def linear_search_array(nums: list[int], target: int) -> int: diff --git a/algorithms/hello_algo/chapter10_searching/two_sum.py b/algorithms/c05_search/two_sum.py similarity index 96% rename from algorithms/hello_algo/chapter10_searching/two_sum.py rename to algorithms/c05_search/two_sum.py index 994e305..8e09945 100644 --- a/algorithms/hello_algo/chapter10_searching/two_sum.py +++ b/algorithms/c05_search/two_sum.py @@ -1,7 +1,6 @@ """ File: two_sum.py Created Time: 2022-11-25 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/c06_string/__init__.py b/algorithms/c06_string/__init__.py index 826a90e..9cbff8c 100644 --- a/algorithms/c06_string/__init__.py +++ b/algorithms/c06_string/__init__.py @@ -2,4 +2,3 @@ """字符串相关算法 Some of description... """ - diff --git a/algorithms/c08_divide/__init__.py b/algorithms/c07_divide/__init__.py similarity index 100% rename from algorithms/c08_divide/__init__.py rename to algorithms/c07_divide/__init__.py diff --git a/algorithms/hello_algo/chapter12_divide_and_conquer/binary_search_recur.py b/algorithms/c07_divide/binary_search_recur.py similarity index 100% rename from algorithms/hello_algo/chapter12_divide_and_conquer/binary_search_recur.py rename to algorithms/c07_divide/binary_search_recur.py diff --git a/algorithms/hello_algo/chapter12_divide_and_conquer/build_tree.py b/algorithms/c07_divide/build_tree.py similarity index 93% rename from algorithms/hello_algo/chapter12_divide_and_conquer/build_tree.py rename to algorithms/c07_divide/build_tree.py index 3ec59c3..c8c9054 100644 --- a/algorithms/hello_algo/chapter12_divide_and_conquer/build_tree.py +++ b/algorithms/c07_divide/build_tree.py @@ -1,14 +1,13 @@ """ File: build_tree.py Created Time: 2023-07-15 -Author: Krahets (krahets@163.com) """ import sys from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import TreeNode, print_tree +from algorithms.models import TreeNode, print_tree def dfs( diff --git a/algorithms/hello_algo/chapter12_divide_and_conquer/hanota.py b/algorithms/c07_divide/hanota.py similarity index 97% rename from algorithms/hello_algo/chapter12_divide_and_conquer/hanota.py rename to algorithms/c07_divide/hanota.py index 34cfd93..bbaec2e 100644 --- a/algorithms/hello_algo/chapter12_divide_and_conquer/hanota.py +++ b/algorithms/c07_divide/hanota.py @@ -1,7 +1,6 @@ """ File: hanota.py Created Time: 2023-07-16 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/__init__.py b/algorithms/c08_backtrack/__init__.py similarity index 100% rename from algorithms/hello_algo/__init__.py rename to algorithms/c08_backtrack/__init__.py diff --git a/algorithms/c08_backtrack/backtrack.py b/algorithms/c08_backtrack/backtrack.py new file mode 100644 index 0000000..338e344 --- /dev/null +++ b/algorithms/c08_backtrack/backtrack.py @@ -0,0 +1,43 @@ +# -*- encoding: utf-8 -*- +""" +回溯法框架代码 +""" + + +def backtrack(state, choices, res): + # 判断是否为解 + if is_solution(state): + # 记录解 + record_solution(state, res) + # 不再继续搜索 + return + # 遍历所有选择 + for choice in choices: + # 剪枝 + if is_valid(state, choice): + # 尝试:做出选择,更新状态 + make_choice(state, choice) + # 使用新的状态继续寻找 + backtrack(state, choices, res) + # 回退:撤销选择,恢复到之前的状态 + undo_choice(state, choice) + + +def is_solution(state) -> bool: + return True + + +def record_solution(state, res): + pass + + +def is_valid(state, choice) -> bool: + return True + + +def make_choice(state, choice): + pass + + +def undo_choice(state, choice): + pass diff --git a/algorithms/hello_algo/chapter13_backtracking/n_queens.py b/algorithms/c08_backtrack/n_queens.py similarity index 98% rename from algorithms/hello_algo/chapter13_backtracking/n_queens.py rename to algorithms/c08_backtrack/n_queens.py index b8b1f11..9608347 100644 --- a/algorithms/hello_algo/chapter13_backtracking/n_queens.py +++ b/algorithms/c08_backtrack/n_queens.py @@ -1,7 +1,6 @@ """ File: n_queens.py Created Time: 2023-04-26 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/chapter13_backtracking/permutations_i.py b/algorithms/c08_backtrack/permutations_i.py similarity index 97% rename from algorithms/hello_algo/chapter13_backtracking/permutations_i.py rename to algorithms/c08_backtrack/permutations_i.py index 7e5d549..cee01c1 100644 --- a/algorithms/hello_algo/chapter13_backtracking/permutations_i.py +++ b/algorithms/c08_backtrack/permutations_i.py @@ -1,7 +1,6 @@ """ File: permutations_i.py Created Time: 2023-04-15 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/chapter13_backtracking/permutations_ii.py b/algorithms/c08_backtrack/permutations_ii.py similarity index 97% rename from algorithms/hello_algo/chapter13_backtracking/permutations_ii.py rename to algorithms/c08_backtrack/permutations_ii.py index d01b13e..ee1ad29 100644 --- a/algorithms/hello_algo/chapter13_backtracking/permutations_ii.py +++ b/algorithms/c08_backtrack/permutations_ii.py @@ -1,7 +1,6 @@ """ File: permutations_ii.py Created Time: 2023-04-15 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/chapter13_backtracking/preorder_traversal_i_compact.py b/algorithms/c08_backtrack/preorder_traversal_i_compact.py similarity index 86% rename from algorithms/hello_algo/chapter13_backtracking/preorder_traversal_i_compact.py rename to algorithms/c08_backtrack/preorder_traversal_i_compact.py index 5ab0de2..8f38204 100644 --- a/algorithms/hello_algo/chapter13_backtracking/preorder_traversal_i_compact.py +++ b/algorithms/c08_backtrack/preorder_traversal_i_compact.py @@ -1,14 +1,13 @@ """ File: preorder_traversal_i_compact.py Created Time: 2023-04-15 -Author: Krahets (krahets@163.com) """ import sys from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import TreeNode, print_tree, list_to_tree +from algorithms.models import TreeNode, print_tree, list_to_tree def pre_order(root: TreeNode): diff --git a/algorithms/hello_algo/chapter13_backtracking/preorder_traversal_ii_compact.py b/algorithms/c08_backtrack/preorder_traversal_ii_compact.py similarity index 88% rename from algorithms/hello_algo/chapter13_backtracking/preorder_traversal_ii_compact.py rename to algorithms/c08_backtrack/preorder_traversal_ii_compact.py index 960e293..57cf1a1 100644 --- a/algorithms/hello_algo/chapter13_backtracking/preorder_traversal_ii_compact.py +++ b/algorithms/c08_backtrack/preorder_traversal_ii_compact.py @@ -1,14 +1,13 @@ """ File: preorder_traversal_ii_compact.py Created Time: 2023-04-15 -Author: Krahets (krahets@163.com) """ import sys from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import TreeNode, print_tree, list_to_tree +from algorithms.models import TreeNode, print_tree, list_to_tree def pre_order(root: TreeNode): diff --git a/algorithms/hello_algo/chapter13_backtracking/preorder_traversal_iii_compact.py b/algorithms/c08_backtrack/preorder_traversal_iii_compact.py similarity index 88% rename from algorithms/hello_algo/chapter13_backtracking/preorder_traversal_iii_compact.py rename to algorithms/c08_backtrack/preorder_traversal_iii_compact.py index d3ca381..e10b0f2 100644 --- a/algorithms/hello_algo/chapter13_backtracking/preorder_traversal_iii_compact.py +++ b/algorithms/c08_backtrack/preorder_traversal_iii_compact.py @@ -1,14 +1,13 @@ """ File: preorder_traversal_iii_compact.py Created Time: 2023-04-15 -Author: Krahets (krahets@163.com) """ import sys from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import TreeNode, print_tree, list_to_tree +from algorithms.models import TreeNode, print_tree, list_to_tree def pre_order(root: TreeNode): diff --git a/algorithms/hello_algo/chapter13_backtracking/preorder_traversal_iii_template.py b/algorithms/c08_backtrack/preorder_traversal_iii_template.py similarity index 89% rename from algorithms/hello_algo/chapter13_backtracking/preorder_traversal_iii_template.py rename to algorithms/c08_backtrack/preorder_traversal_iii_template.py index f331685..cca84f4 100644 --- a/algorithms/hello_algo/chapter13_backtracking/preorder_traversal_iii_template.py +++ b/algorithms/c08_backtrack/preorder_traversal_iii_template.py @@ -1,14 +1,13 @@ """ File: preorder_traversal_iii_template.py Created Time: 2023-04-15 -Author: Krahets (krahets@163.com) """ import sys from pathlib import Path sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import TreeNode, print_tree, list_to_tree +from algorithms.models import TreeNode, print_tree, list_to_tree def is_solution(state: list[TreeNode]) -> bool: @@ -36,9 +35,7 @@ def undo_choice(state: list[TreeNode], choice: TreeNode): state.pop() -def backtrack( - state: list[TreeNode], choices: list[TreeNode], res: list[list[TreeNode]] -): +def backtrack(state: list[TreeNode], choices: list[TreeNode], res: list[list[TreeNode]]): """回溯算法:例题三""" # 检查是否为解 if is_solution(state): diff --git a/algorithms/c08_backtrack/search_node.py b/algorithms/c08_backtrack/search_node.py new file mode 100644 index 0000000..68d0518 --- /dev/null +++ b/algorithms/c08_backtrack/search_node.py @@ -0,0 +1,44 @@ +# -*- encoding: utf-8 -*- +""" +在二叉树中搜索所有值为的节点,请返回根节点到这些节点的路径。 +使用回溯框架代码实现 +""" + + +def backtrack(state: list[int], choices: list[int], res: list[list[int]]): + # 判断是否为解 + if is_solution(state): + # 记录解 + record_solution(state, res) + # 不再继续搜索 + return + # 遍历所有选择 + for choice in choices: + # 剪枝 + if is_valid(state, choice): + # 尝试:做出选择,更新状态 + make_choice(state, choice) + # 使用新的状态继续寻找 + backtrack(state, choices, res) + # 回退:撤销选择,恢复到之前的状态 + undo_choice(state, choice) + + +def is_solution(state: list[int]) -> bool: + return state[-1] == 7 + + +def record_solution(state, res): + pass + + +def is_valid(state, choice) -> bool: + return True + + +def make_choice(state, choice): + pass + + +def undo_choice(state, choice): + pass diff --git a/algorithms/hello_algo/chapter13_backtracking/subset_sum_i.py b/algorithms/c08_backtrack/subset_sum_i.py similarity index 97% rename from algorithms/hello_algo/chapter13_backtracking/subset_sum_i.py rename to algorithms/c08_backtrack/subset_sum_i.py index af5cd1a..97fe85b 100644 --- a/algorithms/hello_algo/chapter13_backtracking/subset_sum_i.py +++ b/algorithms/c08_backtrack/subset_sum_i.py @@ -1,7 +1,6 @@ """ File: subset_sum_i.py Created Time: 2023-06-17 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/chapter13_backtracking/subset_sum_i_naive.py b/algorithms/c08_backtrack/subset_sum_i_naive.py similarity index 97% rename from algorithms/hello_algo/chapter13_backtracking/subset_sum_i_naive.py rename to algorithms/c08_backtrack/subset_sum_i_naive.py index 917b877..116e420 100644 --- a/algorithms/hello_algo/chapter13_backtracking/subset_sum_i_naive.py +++ b/algorithms/c08_backtrack/subset_sum_i_naive.py @@ -1,7 +1,6 @@ """ File: subset_sum_i_naive.py Created Time: 2023-06-17 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/chapter13_backtracking/subset_sum_ii.py b/algorithms/c08_backtrack/subset_sum_ii.py similarity index 98% rename from algorithms/hello_algo/chapter13_backtracking/subset_sum_ii.py rename to algorithms/c08_backtrack/subset_sum_ii.py index 40b3150..104f06e 100644 --- a/algorithms/hello_algo/chapter13_backtracking/subset_sum_ii.py +++ b/algorithms/c08_backtrack/subset_sum_ii.py @@ -1,7 +1,6 @@ """ File: subset_sum_ii.py Created Time: 2023-06-17 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/c10_dynamic/__init__.py b/algorithms/c09_dynamic/__init__.py similarity index 100% rename from algorithms/c10_dynamic/__init__.py rename to algorithms/c09_dynamic/__init__.py diff --git a/algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_backtrack.py b/algorithms/c09_dynamic/climbing_stairs_backtrack.py similarity index 96% rename from algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_backtrack.py rename to algorithms/c09_dynamic/climbing_stairs_backtrack.py index 962df85..3ae7d79 100644 --- a/algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_backtrack.py +++ b/algorithms/c09_dynamic/climbing_stairs_backtrack.py @@ -1,7 +1,6 @@ """ File: climbing_stairs_backtrack.py Created Time: 2023-06-30 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_constraint_dp.py b/algorithms/c09_dynamic/climbing_stairs_constraint_dp.py similarity index 95% rename from algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_constraint_dp.py rename to algorithms/c09_dynamic/climbing_stairs_constraint_dp.py index 4c20d79..a85abfb 100644 --- a/algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_constraint_dp.py +++ b/algorithms/c09_dynamic/climbing_stairs_constraint_dp.py @@ -1,7 +1,6 @@ """ File: climbing_stairs_constraint_dp.py Created Time: 2023-06-30 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_dfs.py b/algorithms/c09_dynamic/climbing_stairs_dfs.py similarity index 93% rename from algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_dfs.py rename to algorithms/c09_dynamic/climbing_stairs_dfs.py index 5e93699..797aba6 100644 --- a/algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_dfs.py +++ b/algorithms/c09_dynamic/climbing_stairs_dfs.py @@ -1,7 +1,6 @@ """ File: climbing_stairs_dfs.py Created Time: 2023-06-30 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_dfs_mem.py b/algorithms/c09_dynamic/climbing_stairs_dfs_mem.py similarity index 95% rename from algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_dfs_mem.py rename to algorithms/c09_dynamic/climbing_stairs_dfs_mem.py index 6ee8836..a0ec9e8 100644 --- a/algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_dfs_mem.py +++ b/algorithms/c09_dynamic/climbing_stairs_dfs_mem.py @@ -1,7 +1,6 @@ """ File: climbing_stairs_dfs_mem.py Created Time: 2023-06-30 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_dp.py b/algorithms/c09_dynamic/climbing_stairs_dp.py similarity index 96% rename from algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_dp.py rename to algorithms/c09_dynamic/climbing_stairs_dp.py index e1f274d..22d9e38 100644 --- a/algorithms/hello_algo/chapter14_dynamic_programming/climbing_stairs_dp.py +++ b/algorithms/c09_dynamic/climbing_stairs_dp.py @@ -1,7 +1,6 @@ """ File: climbing_stairs_dp.py Created Time: 2023-06-30 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/chapter14_dynamic_programming/coin_change.py b/algorithms/c09_dynamic/coin_change.py similarity index 98% rename from algorithms/hello_algo/chapter14_dynamic_programming/coin_change.py rename to algorithms/c09_dynamic/coin_change.py index 2aef95b..dfd1abb 100644 --- a/algorithms/hello_algo/chapter14_dynamic_programming/coin_change.py +++ b/algorithms/c09_dynamic/coin_change.py @@ -1,7 +1,6 @@ """ File: coin_change.py Created Time: 2023-07-10 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/chapter14_dynamic_programming/coin_change_ii.py b/algorithms/c09_dynamic/coin_change_ii.py similarity index 97% rename from algorithms/hello_algo/chapter14_dynamic_programming/coin_change_ii.py rename to algorithms/c09_dynamic/coin_change_ii.py index abc3230..2c23b71 100644 --- a/algorithms/hello_algo/chapter14_dynamic_programming/coin_change_ii.py +++ b/algorithms/c09_dynamic/coin_change_ii.py @@ -1,7 +1,6 @@ """ File: coin_change_ii.py Created Time: 2023-07-10 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/chapter14_dynamic_programming/edit_distance.py b/algorithms/c09_dynamic/edit_distance.py similarity index 99% rename from algorithms/hello_algo/chapter14_dynamic_programming/edit_distance.py rename to algorithms/c09_dynamic/edit_distance.py index 1b405fe..7856509 100644 --- a/algorithms/hello_algo/chapter14_dynamic_programming/edit_distance.py +++ b/algorithms/c09_dynamic/edit_distance.py @@ -1,7 +1,6 @@ """ File: edit_distancde.py Created Time: 2023-07-04 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/chapter14_dynamic_programming/knapsack.py b/algorithms/c09_dynamic/knapsack.py similarity index 98% rename from algorithms/hello_algo/chapter14_dynamic_programming/knapsack.py rename to algorithms/c09_dynamic/knapsack.py index 2dd2d35..ad5c777 100644 --- a/algorithms/hello_algo/chapter14_dynamic_programming/knapsack.py +++ b/algorithms/c09_dynamic/knapsack.py @@ -1,7 +1,6 @@ """ File: knapsack.py Created Time: 2023-07-03 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/c10_dynamic/m01_cut_steel.py b/algorithms/c09_dynamic/m01_cut_steel.py similarity index 100% rename from algorithms/c10_dynamic/m01_cut_steel.py rename to algorithms/c09_dynamic/m01_cut_steel.py diff --git a/algorithms/c10_dynamic/m02_fibonacci.py b/algorithms/c09_dynamic/m02_fibonacci.py similarity index 100% rename from algorithms/c10_dynamic/m02_fibonacci.py rename to algorithms/c09_dynamic/m02_fibonacci.py diff --git a/algorithms/c10_dynamic/m03_matrix_chain.py b/algorithms/c09_dynamic/m03_matrix_chain.py similarity index 100% rename from algorithms/c10_dynamic/m03_matrix_chain.py rename to algorithms/c09_dynamic/m03_matrix_chain.py diff --git a/algorithms/c10_dynamic/m04_elevator.py b/algorithms/c09_dynamic/m04_elevator.py similarity index 100% rename from algorithms/c10_dynamic/m04_elevator.py rename to algorithms/c09_dynamic/m04_elevator.py diff --git a/algorithms/c10_dynamic/m05_subsequence.py b/algorithms/c09_dynamic/m05_subsequence.py similarity index 100% rename from algorithms/c10_dynamic/m05_subsequence.py rename to algorithms/c09_dynamic/m05_subsequence.py diff --git a/algorithms/c10_dynamic/m06_bag.py b/algorithms/c09_dynamic/m06_bag.py similarity index 100% rename from algorithms/c10_dynamic/m06_bag.py rename to algorithms/c09_dynamic/m06_bag.py diff --git a/algorithms/hello_algo/chapter14_dynamic_programming/min_cost_climbing_stairs_dp.py b/algorithms/c09_dynamic/min_cost_climbing_stairs_dp.py similarity index 97% rename from algorithms/hello_algo/chapter14_dynamic_programming/min_cost_climbing_stairs_dp.py rename to algorithms/c09_dynamic/min_cost_climbing_stairs_dp.py index 2e27481..082699a 100644 --- a/algorithms/hello_algo/chapter14_dynamic_programming/min_cost_climbing_stairs_dp.py +++ b/algorithms/c09_dynamic/min_cost_climbing_stairs_dp.py @@ -1,7 +1,6 @@ """ File: min_cost_climbing_stairs_dp.py Created Time: 2023-06-30 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/chapter14_dynamic_programming/min_path_sum.py b/algorithms/c09_dynamic/min_path_sum.py similarity index 98% rename from algorithms/hello_algo/chapter14_dynamic_programming/min_path_sum.py rename to algorithms/c09_dynamic/min_path_sum.py index 5192c84..d42866c 100644 --- a/algorithms/hello_algo/chapter14_dynamic_programming/min_path_sum.py +++ b/algorithms/c09_dynamic/min_path_sum.py @@ -1,7 +1,6 @@ """ File: min_path_sum.py Created Time: 2023-07-04 -Author: Krahets (krahets@163.com) """ from math import inf diff --git a/algorithms/hello_algo/chapter14_dynamic_programming/unbounded_knapsack.py b/algorithms/c09_dynamic/unbounded_knapsack.py similarity index 97% rename from algorithms/hello_algo/chapter14_dynamic_programming/unbounded_knapsack.py rename to algorithms/c09_dynamic/unbounded_knapsack.py index 20fb1a4..d393098 100644 --- a/algorithms/hello_algo/chapter14_dynamic_programming/unbounded_knapsack.py +++ b/algorithms/c09_dynamic/unbounded_knapsack.py @@ -1,7 +1,6 @@ """ File: unbounded_knapsack.py Created Time: 2023-07-10 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/c07_greedy/__init__.py b/algorithms/c10_greedy/__init__.py similarity index 97% rename from algorithms/c07_greedy/__init__.py rename to algorithms/c10_greedy/__init__.py index 44df38a..870df7d 100644 --- a/algorithms/c07_greedy/__init__.py +++ b/algorithms/c10_greedy/__init__.py @@ -2,4 +2,3 @@ """ 贪心算法 """ - diff --git a/algorithms/hello_algo/chapter15_greedy/coin_change_greedy.py b/algorithms/c10_greedy/coin_change_greedy.py similarity index 97% rename from algorithms/hello_algo/chapter15_greedy/coin_change_greedy.py rename to algorithms/c10_greedy/coin_change_greedy.py index f233acb..66a5d24 100644 --- a/algorithms/hello_algo/chapter15_greedy/coin_change_greedy.py +++ b/algorithms/c10_greedy/coin_change_greedy.py @@ -1,7 +1,6 @@ """ File: coin_change_greedy.py Created Time: 2023-07-18 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/chapter15_greedy/fractional_knapsack.py b/algorithms/c10_greedy/fractional_knapsack.py similarity index 97% rename from algorithms/hello_algo/chapter15_greedy/fractional_knapsack.py rename to algorithms/c10_greedy/fractional_knapsack.py index 0191bdb..fde8fc9 100644 --- a/algorithms/hello_algo/chapter15_greedy/fractional_knapsack.py +++ b/algorithms/c10_greedy/fractional_knapsack.py @@ -1,7 +1,6 @@ """ File: fractional_knapsack.py Created Time: 2023-07-19 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/c07_greedy/m01_activity.py b/algorithms/c10_greedy/m01_activity.py similarity index 100% rename from algorithms/c07_greedy/m01_activity.py rename to algorithms/c10_greedy/m01_activity.py diff --git a/algorithms/hello_algo/chapter15_greedy/max_capacity.py b/algorithms/c10_greedy/max_capacity.py similarity index 95% rename from algorithms/hello_algo/chapter15_greedy/max_capacity.py rename to algorithms/c10_greedy/max_capacity.py index 12377b4..706b60e 100644 --- a/algorithms/hello_algo/chapter15_greedy/max_capacity.py +++ b/algorithms/c10_greedy/max_capacity.py @@ -1,7 +1,6 @@ """ File: max_capacity.py Created Time: 2023-07-21 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/chapter15_greedy/max_product_cutting.py b/algorithms/c10_greedy/max_product_cutting.py similarity index 95% rename from algorithms/hello_algo/chapter15_greedy/max_product_cutting.py rename to algorithms/c10_greedy/max_product_cutting.py index 921a354..f6ed48c 100644 --- a/algorithms/hello_algo/chapter15_greedy/max_product_cutting.py +++ b/algorithms/c10_greedy/max_product_cutting.py @@ -1,7 +1,6 @@ """ File: max_product_cutting.py Created Time: 2023-07-21 -Author: Krahets (krahets@163.com) """ import math diff --git a/algorithms/c12_ai/basic/__init__.py b/algorithms/c12_ai/basic/__init__.py index 001044c..66995af 100644 --- a/algorithms/c12_ai/basic/__init__.py +++ b/algorithms/c12_ai/basic/__init__.py @@ -2,8 +2,3 @@ """ AI基础算法集合 """ - - - - - diff --git a/algorithms/c12_ai/basic/a01_maze_bfs.py b/algorithms/c12_ai/basic/a01_maze_bfs.py index 3a0e047..6f02bbb 100644 --- a/algorithms/c12_ai/basic/a01_maze_bfs.py +++ b/algorithms/c12_ai/basic/a01_maze_bfs.py @@ -3,8 +3,8 @@ 迷宫搜索:广度优先算法,通过队列来实现 """ -from algorithms.c01_linear.queue.linked_queue import LinkedQueue -from algorithms.c01_linear.stack.stack_linked_list import LinkedStack +from algorithms.c01_data_structure.queue.linked_queue import LinkedQueue +from algorithms.c01_data_structure.stack.stack_linked_list import LinkedStack class Point: diff --git a/algorithms/c12_ai/basic/a02_maze_dfs.py b/algorithms/c12_ai/basic/a02_maze_dfs.py index a27c8ec..3007604 100644 --- a/algorithms/c12_ai/basic/a02_maze_dfs.py +++ b/algorithms/c12_ai/basic/a02_maze_dfs.py @@ -3,7 +3,7 @@ 迷宫搜索:深度优先算法,通过栈来实现 """ -from algorithms.c01_linear.stack.stack_linked_list import LinkedStack +from algorithms.c01_data_structure.stack.stack_linked_list import LinkedStack class Point: @@ -45,7 +45,3 @@ def run_dfs(maze, root_point, visited_points): neighbor.parent = current_point s.push(neighbor) print('find no path') - - - - diff --git a/algorithms/c14_leetcode/__init__.py b/algorithms/c14_leetcode/__init__.py index 12f0bb3..c8dcb5a 100644 --- a/algorithms/c14_leetcode/__init__.py +++ b/algorithms/c14_leetcode/__init__.py @@ -3,4 +3,3 @@ """ LeeCode算法题库 """ - diff --git a/algorithms/c14_leetcode/p000/a19_remove_nth_node_from_end_of_list.py b/algorithms/c14_leetcode/p000/a19_remove_nth_node_from_end_of_list.py index 43362a7..4c58946 100644 --- a/algorithms/c14_leetcode/p000/a19_remove_nth_node_from_end_of_list.py +++ b/algorithms/c14_leetcode/p000/a19_remove_nth_node_from_end_of_list.py @@ -57,5 +57,3 @@ def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode: res = solution.removeNthFromEnd(head, 5) print() # output - - diff --git a/algorithms/c14_leetcode/p000/a20_valid_parentheses.py b/algorithms/c14_leetcode/p000/a20_valid_parentheses.py index 46ef4cc..a3cd5e9 100644 --- a/algorithms/c14_leetcode/p000/a20_valid_parentheses.py +++ b/algorithms/c14_leetcode/p000/a20_valid_parentheses.py @@ -23,7 +23,7 @@ 算法思路:栈的最简单的应用。左括号入栈,右括号出栈+对比匹配。不匹配则False,最后栈空则True """ -from algorithms.c01_linear.stack.stack_linked_list import LinkedStack +from algorithms.c01_data_structure.stack.stack_linked_list import LinkedStack class Solution: diff --git a/algorithms/c14_leetcode/p000/a21_merge_two_sorted_lists.py b/algorithms/c14_leetcode/p000/a21_merge_two_sorted_lists.py index 71b9df4..14b341c 100644 --- a/algorithms/c14_leetcode/p000/a21_merge_two_sorted_lists.py +++ b/algorithms/c14_leetcode/p000/a21_merge_two_sorted_lists.py @@ -43,6 +43,7 @@ def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> food = temp_food # 将原来剩余的蛇身变成食物。这样完成了蛇身和食物的交换。 return result + if __name__ == '__main__': a = ListNode(1) b = ListNode(2) diff --git a/algorithms/c14_leetcode/p000/a23_merge_k_sorted_lists.py b/algorithms/c14_leetcode/p000/a23_merge_k_sorted_lists.py index f13d795..27aed33 100644 --- a/algorithms/c14_leetcode/p000/a23_merge_k_sorted_lists.py +++ b/algorithms/c14_leetcode/p000/a23_merge_k_sorted_lists.py @@ -10,7 +10,7 @@ """ from typing import List, Optional -from algorithms.c01_linear.linkedlist import ListNode +from algorithms.c01_data_structure.linkedlist import ListNode from queue import PriorityQueue diff --git a/algorithms/c14_leetcode/p000/a70_climbing_stairs.py b/algorithms/c14_leetcode/p000/a70_climbing_stairs.py index 07aa6ef..83663eb 100644 --- a/algorithms/c14_leetcode/p000/a70_climbing_stairs.py +++ b/algorithms/c14_leetcode/p000/a70_climbing_stairs.py @@ -22,6 +22,7 @@ def climb_stairs(self, n: int) -> int: if __name__ == '__main__': import sys + while True: line = sys.stdin.readline().strip() if line == '': diff --git a/algorithms/c14_leetcode/p000/a86_partition_list.py b/algorithms/c14_leetcode/p000/a86_partition_list.py index 0db7a94..f8537c6 100644 --- a/algorithms/c14_leetcode/p000/a86_partition_list.py +++ b/algorithms/c14_leetcode/p000/a86_partition_list.py @@ -12,7 +12,7 @@ """ from typing import Optional -from algorithms.c01_linear.linkedlist import ListNode +from algorithms.c01_data_structure.linkedlist import ListNode class Solution: diff --git a/algorithms/c14_leetcode/p100/a142_linked_list_cycle_ii.py b/algorithms/c14_leetcode/p100/a142_linked_list_cycle_ii.py index 65151de..c4b45d4 100644 --- a/algorithms/c14_leetcode/p100/a142_linked_list_cycle_ii.py +++ b/algorithms/c14_leetcode/p100/a142_linked_list_cycle_ii.py @@ -16,7 +16,7 @@ """ from typing import Optional -from algorithms.c01_linear.linkedlist import ListNode +from algorithms.c01_data_structure.linkedlist import ListNode class Solution: diff --git a/algorithms/c14_leetcode/p100/a155_min_stack.py b/algorithms/c14_leetcode/p100/a155_min_stack.py index d08c4a2..a2203ce 100644 --- a/algorithms/c14_leetcode/p100/a155_min_stack.py +++ b/algorithms/c14_leetcode/p100/a155_min_stack.py @@ -15,7 +15,7 @@ 通过空间换时间的方法。将每次入栈的节点包装成一个对象,存储两个信息,一个是节点值,一个是当前栈的最小值。 这样获取栈顶元素就同时能获取到这两个值了。 """ -from algorithms.c01_linear import Node +from algorithms.c01_data_structure import Node class MinStack: @@ -32,13 +32,11 @@ def pop(self) -> None: if self.first: self.first = self.first.next - def top(self) -> int: if not self.first: return None return self.first.data[0] - def getMin(self) -> int: if not self.first: return None diff --git a/algorithms/c14_leetcode/p100/a160_intersection_of_two_linked_lists.py b/algorithms/c14_leetcode/p100/a160_intersection_of_two_linked_lists.py index 344c084..36db51f 100644 --- a/algorithms/c14_leetcode/p100/a160_intersection_of_two_linked_lists.py +++ b/algorithms/c14_leetcode/p100/a160_intersection_of_two_linked_lists.py @@ -14,7 +14,7 @@ """ from typing import Optional -from algorithms.c01_linear.linkedlist import ListNode +from algorithms.c01_data_structure.linkedlist import ListNode class Solution: diff --git a/algorithms/c14_leetcode/p200/a206_reverse_linked_list.py b/algorithms/c14_leetcode/p200/a206_reverse_linked_list.py index 0d0fab4..54a5eb9 100644 --- a/algorithms/c14_leetcode/p200/a206_reverse_linked_list.py +++ b/algorithms/c14_leetcode/p200/a206_reverse_linked_list.py @@ -33,10 +33,10 @@ def reverseList(self, head: ListNode) -> ListNode: snake = None while food: - apple = food # 取下糖葫芦第一个苹果 - food = food.next # 糖葫芦减掉一个 + apple = food # 取下糖葫芦第一个苹果 + food = food.next # 糖葫芦减掉一个 apple.next = snake # 吞掉一个苹果 - snake = apple # 调整蛇的头部指向这个苹果 + snake = apple # 调整蛇的头部指向这个苹果 return snake @@ -55,5 +55,3 @@ def reverseList(self, head: ListNode) -> ListNode: res = solution.reverseList(head) print() # output - - diff --git a/algorithms/c14_leetcode/p800/a876_middle_of_the_linked_list.py b/algorithms/c14_leetcode/p800/a876_middle_of_the_linked_list.py index 936fbea..bff832a 100644 --- a/algorithms/c14_leetcode/p800/a876_middle_of_the_linked_list.py +++ b/algorithms/c14_leetcode/p800/a876_middle_of_the_linked_list.py @@ -36,6 +36,7 @@ def __iter__(self): yield node.val node = node.next + class Solution: def middleNode(self, head: ListNode) -> ListNode: if not head: @@ -64,5 +65,3 @@ def middleNode(self, head: ListNode) -> ListNode: res = solution.middleNode(head) # output print(list(res)) - - diff --git a/algorithms/hello_algo/chapter02_computational_complexity/iteration.py b/algorithms/hello_algo/chapter02_computational_complexity/iteration.py deleted file mode 100644 index 2f83398..0000000 --- a/algorithms/hello_algo/chapter02_computational_complexity/iteration.py +++ /dev/null @@ -1,65 +0,0 @@ -""" -File: iteration.py -Created Time: 2023-08-24 -Author: Krahets (krahets@163.com) -""" - - -def for_loop(n: int) -> int: - """for 循环""" - res = 0 - # 循环求和 1, 2, ..., n-1, n - for i in range(1, n + 1): - res += i - return res - - -def while_loop(n: int) -> int: - """while 循环""" - res = 0 - i = 1 # 初始化条件变量 - # 循环求和 1, 2, ..., n-1, n - while i <= n: - res += i - i += 1 # 更新条件变量 - return res - - -def while_loop_ii(n: int) -> int: - """while 循环(两次更新)""" - res = 0 - i = 1 # 初始化条件变量 - # 循环求和 1, 4, ... - while i <= n: - res += i - # 更新条件变量 - i += 1 - i *= 2 - return res - - -def nested_for_loop(n: int) -> str: - """双层 for 循环""" - res = "" - # 循环 i = 1, 2, ..., n-1, n - for i in range(1, n + 1): - # 循环 j = 1, 2, ..., n-1, n - for j in range(1, n + 1): - res += f"({i}, {j}), " - return res - - -"""Driver Code""" -if __name__ == "__main__": - n = 5 - res = for_loop(n) - print(f"\nfor 循环的求和结果 res = {res}") - - res = while_loop(n) - print(f"\nwhile 循环的求和结果 res = {res}") - - res = while_loop_ii(n) - print(f"\nwhile 循环(两次更新)求和结果 res = {res}") - - res = nested_for_loop(n) - print(f"\n双层 for 循环的遍历结果 {res}") diff --git a/algorithms/hello_algo/chapter02_computational_complexity/recursion.py b/algorithms/hello_algo/chapter02_computational_complexity/recursion.py deleted file mode 100644 index c44064e..0000000 --- a/algorithms/hello_algo/chapter02_computational_complexity/recursion.py +++ /dev/null @@ -1,69 +0,0 @@ -""" -File: recursion.py -Created Time: 2023-08-24 -Author: Krahets (krahets@163.com) -""" - - -def recur(n: int) -> int: - """递归""" - # 终止条件 - if n == 1: - return 1 - # 递:递归调用 - res = recur(n - 1) - # 归:返回结果 - return n + res - - -def for_loop_recur(n: int) -> int: - """使用迭代模拟递归""" - # 使用一个显式的栈来模拟系统调用栈 - stack = [] - res = 0 - # 递:递归调用 - for i in range(n, 0, -1): - # 通过“入栈操作”模拟“递” - stack.append(i) - # 归:返回结果 - while stack: - # 通过“出栈操作”模拟“归” - res += stack.pop() - # res = 1+2+3+...+n - return res - - -def tail_recur(n, res): - """尾递归""" - # 终止条件 - if n == 0: - return res - # 尾递归调用 - return tail_recur(n - 1, res + n) - - -def fib(n: int) -> int: - """斐波那契数列:递归""" - # 终止条件 f(1) = 0, f(2) = 1 - if n == 1 or n == 2: - return n - 1 - # 递归调用 f(n) = f(n-1) + f(n-2) - res = fib(n - 1) + fib(n - 2) - # 返回结果 f(n) - return res - - -"""Driver Code""" -if __name__ == "__main__": - n = 5 - res = recur(n) - print(f"\n递归函数的求和结果 res = {res}") - - res = for_loop_recur(n) - print(f"\n使用迭代模拟递归求和结果 res = {res}") - - res = tail_recur(n, 0) - print(f"\n尾递归函数的求和结果 res = {res}") - - res = fib(n) - print(f"\n斐波那契数列的第 {n} 项为 {res}") diff --git a/algorithms/hello_algo/chapter02_computational_complexity/space_complexity.py b/algorithms/hello_algo/chapter02_computational_complexity/space_complexity.py deleted file mode 100644 index be91c2a..0000000 --- a/algorithms/hello_algo/chapter02_computational_complexity/space_complexity.py +++ /dev/null @@ -1,90 +0,0 @@ -""" -File: space_complexity.py -Created Time: 2022-11-25 -Author: Krahets (krahets@163.com) -""" - -import sys -from pathlib import Path - -sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import ListNode, TreeNode, print_tree - - -def function() -> int: - """函数""" - # 执行某些操作 - return 0 - - -def constant(n: int): - """常数阶""" - # 常量、变量、对象占用 O(1) 空间 - a = 0 - nums = [0] * 10000 - node = ListNode(0) - # 循环中的变量占用 O(1) 空间 - for _ in range(n): - c = 0 - # 循环中的函数占用 O(1) 空间 - for _ in range(n): - function() - - -def linear(n: int): - """线性阶""" - # 长度为 n 的列表占用 O(n) 空间 - nums = [0] * n - # 长度为 n 的哈希表占用 O(n) 空间 - hmap = dict[int, str]() - for i in range(n): - hmap[i] = str(i) - - -def linear_recur(n: int): - """线性阶(递归实现)""" - print("递归 n =", n) - if n == 1: - return - linear_recur(n - 1) - - -def quadratic(n: int): - """平方阶""" - # 二维列表占用 O(n^2) 空间 - num_matrix = [[0] * n for _ in range(n)] - - -def quadratic_recur(n: int) -> int: - """平方阶(递归实现)""" - if n <= 0: - return 0 - # 数组 nums 长度为 n, n-1, ..., 2, 1 - nums = [0] * n - return quadratic_recur(n - 1) - - -def build_tree(n: int) -> TreeNode | None: - """指数阶(建立满二叉树)""" - if n == 0: - return None - root = TreeNode(0) - root.left = build_tree(n - 1) - root.right = build_tree(n - 1) - return root - - -"""Driver Code""" -if __name__ == "__main__": - n = 5 - # 常数阶 - constant(n) - # 线性阶 - linear(n) - linear_recur(n) - # 平方阶 - quadratic(n) - quadratic_recur(n) - # 指数阶 - root = build_tree(n) - print_tree(root) diff --git a/algorithms/hello_algo/chapter02_computational_complexity/time_complexity.py b/algorithms/hello_algo/chapter02_computational_complexity/time_complexity.py deleted file mode 100644 index 79240e0..0000000 --- a/algorithms/hello_algo/chapter02_computational_complexity/time_complexity.py +++ /dev/null @@ -1,151 +0,0 @@ -""" -File: time_complexity.py -Created Time: 2022-11-25 -Author: Krahets (krahets@163.com) -""" - - -def constant(n: int) -> int: - """常数阶""" - count = 0 - size = 100000 - for _ in range(size): - count += 1 - return count - - -def linear(n: int) -> int: - """线性阶""" - count = 0 - for _ in range(n): - count += 1 - return count - - -def array_traversal(nums: list[int]) -> int: - """线性阶(遍历数组)""" - count = 0 - # 循环次数与数组长度成正比 - for num in nums: - count += 1 - return count - - -def quadratic(n: int) -> int: - """平方阶""" - count = 0 - # 循环次数与数组长度成平方关系 - for i in range(n): - for j in range(n): - count += 1 - return count - - -def bubble_sort(nums: list[int]) -> int: - """平方阶(冒泡排序)""" - count = 0 # 计数器 - # 外循环:未排序区间为 [0, i] - for i in range(len(nums) - 1, 0, -1): - # 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端 - for j in range(i): - if nums[j] > nums[j + 1]: - # 交换 nums[j] 与 nums[j + 1] - tmp: int = nums[j] - nums[j] = nums[j + 1] - nums[j + 1] = tmp - count += 3 # 元素交换包含 3 个单元操作 - return count - - -def exponential(n: int) -> int: - """指数阶(循环实现)""" - count = 0 - base = 1 - # 细胞每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1) - for _ in range(n): - for _ in range(base): - count += 1 - base *= 2 - # count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1 - return count - - -def exp_recur(n: int) -> int: - """指数阶(递归实现)""" - if n == 1: - return 1 - return exp_recur(n - 1) + exp_recur(n - 1) + 1 - - -def logarithmic(n: float) -> int: - """对数阶(循环实现)""" - count = 0 - while n > 1: - n = n / 2 - count += 1 - return count - - -def log_recur(n: float) -> int: - """对数阶(递归实现)""" - if n <= 1: - return 0 - return log_recur(n / 2) + 1 - - -def linear_log_recur(n: float) -> int: - """线性对数阶""" - if n <= 1: - return 1 - count: int = linear_log_recur(n // 2) + linear_log_recur(n // 2) - for _ in range(n): - count += 1 - return count - - -def factorial_recur(n: int) -> int: - """阶乘阶(递归实现)""" - if n == 0: - return 1 - count = 0 - # 从 1 个分裂出 n 个 - for _ in range(n): - count += factorial_recur(n - 1) - return count - - -"""Driver Code""" -if __name__ == "__main__": - # 可以修改 n 运行,体会一下各种复杂度的操作数量变化趋势 - n = 8 - print("输入数据大小 n =", n) - - count: int = constant(n) - print("常数阶的操作数量 =", count) - - count: int = linear(n) - print("线性阶的操作数量 =", count) - count: int = array_traversal([0] * n) - print("线性阶(遍历数组)的操作数量 =", count) - - count: int = quadratic(n) - print("平方阶的操作数量 =", count) - nums = [i for i in range(n, 0, -1)] # [n, n-1, ..., 2, 1] - count: int = bubble_sort(nums) - print("平方阶(冒泡排序)的操作数量 =", count) - - count: int = exponential(n) - print("指数阶(循环实现)的操作数量 =", count) - count: int = exp_recur(n) - print("指数阶(递归实现)的操作数量 =", count) - - count: int = logarithmic(n) - print("对数阶(循环实现)的操作数量 =", count) - count: int = log_recur(n) - print("对数阶(递归实现)的操作数量 =", count) - - count: int = linear_log_recur(n) - print("线性对数阶(递归实现)的操作数量 =", count) - - count: int = factorial_recur(n) - print("阶乘阶(递归实现)的操作数量 =", count) diff --git a/algorithms/hello_algo/chapter02_computational_complexity/worst_best_time_complexity.py b/algorithms/hello_algo/chapter02_computational_complexity/worst_best_time_complexity.py deleted file mode 100644 index 6c2ebee..0000000 --- a/algorithms/hello_algo/chapter02_computational_complexity/worst_best_time_complexity.py +++ /dev/null @@ -1,36 +0,0 @@ -""" -File: worst_best_time_complexity.py -Created Time: 2022-11-25 -Author: Krahets (krahets@163.com) -""" - -import random - - -def random_numbers(n: int) -> list[int]: - """生成一个数组,元素为: 1, 2, ..., n ,顺序被打乱""" - # 生成数组 nums =: 1, 2, 3, ..., n - nums = [i for i in range(1, n + 1)] - # 随机打乱数组元素 - random.shuffle(nums) - return nums - - -def find_one(nums: list[int]) -> int: - """查找数组 nums 中数字 1 所在索引""" - for i in range(len(nums)): - # 当元素 1 在数组头部时,达到最佳时间复杂度 O(1) - # 当元素 1 在数组尾部时,达到最差时间复杂度 O(n) - if nums[i] == 1: - return i - return -1 - - -"""Driver Code""" -if __name__ == "__main__": - for i in range(10): - n = 100 - nums: list[int] = random_numbers(n) - index: int = find_one(nums) - print("\n数组 [ 1, 2, ..., n ] 被打乱后 =", nums) - print("数字 1 的索引为", index) diff --git a/algorithms/hello_algo/chapter04_array_and_linkedlist/array.py b/algorithms/hello_algo/chapter04_array_and_linkedlist/array.py deleted file mode 100644 index 0b917e7..0000000 --- a/algorithms/hello_algo/chapter04_array_and_linkedlist/array.py +++ /dev/null @@ -1,99 +0,0 @@ -""" -File: array.py -Created Time: 2022-11-25 -Author: Krahets (krahets@163.com) -""" - -import random - - -def random_access(nums: list[int]) -> int: - """随机访问元素""" - # 在区间 [0, len(nums)-1] 中随机抽取一个数字 - random_index = random.randint(0, len(nums) - 1) - # 获取并返回随机元素 - random_num = nums[random_index] - return random_num - - -# 请注意,Python 的 list 是动态数组,可以直接扩展 -# 为了方便学习,本函数将 list 看作是长度不可变的数组 -def extend(nums: list[int], enlarge: int) -> list[int]: - """扩展数组长度""" - # 初始化一个扩展长度后的数组 - res = [0] * (len(nums) + enlarge) - # 将原数组中的所有元素复制到新数组 - for i in range(len(nums)): - res[i] = nums[i] - # 返回扩展后的新数组 - return res - - -def insert(nums: list[int], num: int, index: int): - """在数组的索引 index 处插入元素 num""" - # 把索引 index 以及之后的所有元素向后移动一位 - for i in range(len(nums) - 1, index, -1): - nums[i] = nums[i - 1] - # 将 num 赋给 index 处元素 - nums[index] = num - - -def remove(nums: list[int], index: int): - """删除索引 index 处元素""" - # 把索引 index 之后的所有元素向前移动一位 - for i in range(index, len(nums) - 1): - nums[i] = nums[i + 1] - - -def traverse(nums: list[int]): - """遍历数组""" - count = 0 - # 通过索引遍历数组 - for i in range(len(nums)): - count += 1 - # 直接遍历数组 - for num in nums: - count += 1 - # 同时遍历数据索引和元素 - for i, num in enumerate(nums): - count += 1 - - -def find(nums: list[int], target: int) -> int: - """在数组中查找指定元素""" - for i in range(len(nums)): - if nums[i] == target: - return i - return -1 - - -"""Driver Code""" -if __name__ == "__main__": - # 初始化数组 - arr = [0] * 5 - print("数组 arr =", arr) - nums = [1, 3, 2, 5, 4] - print("数组 nums =", nums) - - # 随机访问 - random_num: int = random_access(nums) - print("在 nums 中获取随机元素", random_num) - - # 长度扩展 - nums: list[int] = extend(nums, 3) - print("将数组长度扩展至 8 ,得到 nums =", nums) - - # 插入元素 - insert(nums, 6, 3) - print("在索引 3 处插入数字 6 ,得到 nums =", nums) - - # 删除元素 - remove(nums, 2) - print("删除索引 2 处的元素,得到 nums =", nums) - - # 遍历数组 - traverse(nums) - - # 查找元素 - index: int = find(nums, 3) - print("在 nums 中查找元素 3 ,得到索引 =", index) diff --git a/algorithms/hello_algo/chapter04_array_and_linkedlist/linked_list.py b/algorithms/hello_algo/chapter04_array_and_linkedlist/linked_list.py deleted file mode 100644 index a513642..0000000 --- a/algorithms/hello_algo/chapter04_array_and_linkedlist/linked_list.py +++ /dev/null @@ -1,84 +0,0 @@ -""" -File: linked_list.py -Created Time: 2022-11-25 -Author: Krahets (krahets@163.com) -""" - -import sys -from pathlib import Path - -sys.path.append(str(Path(__file__).parent.parent)) -from algorithms.hello_algo.modules import ListNode, print_linked_list - - -def insert(n0: ListNode, P: ListNode): - """在链表的节点 n0 之后插入节点 P""" - n1 = n0.next - P.next = n1 - n0.next = P - - -def remove(n0: ListNode): - """删除链表的节点 n0 之后的首个节点""" - if not n0.next: - return - # n0 -> P -> n1 - P = n0.next - n1 = P.next - n0.next = n1 - - -def access(head: ListNode, index: int) -> ListNode | None: - """访问链表中索引为 index 的节点""" - for _ in range(index): - if not head: - return None - head = head.next - return head - - -def find(head: ListNode, target: int) -> int: - """在链表中查找值为 target 的首个节点""" - index = 0 - while head: - if head.val == target: - return index - head = head.next - index += 1 - return -1 - - -"""Driver Code""" -if __name__ == "__main__": - # 初始化链表 - # 初始化各个节点 - n0 = ListNode(1) - n1 = ListNode(3) - n2 = ListNode(2) - n3 = ListNode(5) - n4 = ListNode(4) - # 构建引用指向 - n0.next = n1 - n1.next = n2 - n2.next = n3 - n3.next = n4 - print("初始化的链表为") - print_linked_list(n0) - - # 插入节点 - insert(n0, ListNode(0)) - print("插入节点后的链表为") - print_linked_list(n0) - - # 删除节点 - remove(n0) - print("删除节点后的链表为") - print_linked_list(n0) - - # 访问节点 - node: ListNode = access(n0, 3) - print("链表中索引 3 处的节点的值 = {}".format(node.val)) - - # 查找节点 - index: int = find(n0, 2) - print("链表中值为 2 的节点的索引 = {}".format(index)) diff --git a/algorithms/hello_algo/chapter04_array_and_linkedlist/list.py b/algorithms/hello_algo/chapter04_array_and_linkedlist/list.py deleted file mode 100644 index b9ad6d3..0000000 --- a/algorithms/hello_algo/chapter04_array_and_linkedlist/list.py +++ /dev/null @@ -1,59 +0,0 @@ -""" -File: list.py -Created Time: 2022-11-25 -Author: Krahets (krahets@163.com) -""" - -"""Driver Code""" -if __name__ == "__main__": - # 初始化列表 - nums: list[int] = [1, 3, 2, 5, 4] - print("\n列表 nums =", nums) - - # 访问元素 - x: int = nums[1] - print("\n访问索引 1 处的元素,得到 x =", x) - - # 更新元素 - nums[1] = 0 - print("\n将索引 1 处的元素更新为 0 ,得到 nums =", nums) - - # 清空列表 - nums.clear() - print("\n清空列表后 nums =", nums) - - # 尾部添加元素 - nums.append(1) - nums.append(3) - nums.append(2) - nums.append(5) - nums.append(4) - print("\n添加元素后 nums =", nums) - - # 中间插入元素 - nums.insert(3, 6) - print("\n在索引 3 处插入数字 6 ,得到 nums =", nums) - - # 删除元素 - nums.pop(3) - print("\n删除索引 3 处的元素,得到 nums =", nums) - - # 遍历列表 - tmp = [] - for i in range(len(nums)): - tmp.append(nums[i]) - print(f"\n通过索引遍历列表得到 tmp = {tmp}") - - tmp.clear() - for num in nums: - tmp.append(num) - print(f"\n直接遍历列表元素得到 tmp = {tmp}") - - # 拼接两个列表 - nums1 = [6, 8, 7, 10, 9] - nums += nums1 - print("\n将列表 nums1 拼接到 nums 之后,得到 nums =", nums) - - # 排序列表 - nums.sort() - print("\n排序列表后 nums =", nums) diff --git a/algorithms/hello_algo/chapter04_array_and_linkedlist/my_list.py b/algorithms/hello_algo/chapter04_array_and_linkedlist/my_list.py deleted file mode 100644 index c78ac43..0000000 --- a/algorithms/hello_algo/chapter04_array_and_linkedlist/my_list.py +++ /dev/null @@ -1,118 +0,0 @@ -""" -File: my_list.py -Created Time: 2022-11-25 -Author: Krahets (krahets@163.com) -""" - - -class MyList: - """列表类简易实现""" - - def __init__(self): - """构造方法""" - self._capacity: int = 10 # 列表容量 - self._arr: list[int] = [0] * self._capacity # 数组(存储列表元素) - self._size: int = 0 # 列表长度(即当前元素数量) - self._extend_ratio: int = 2 # 每次列表扩容的倍数 - - def size(self) -> int: - """获取列表长度(即当前元素数量)""" - return self._size - - def capacity(self) -> int: - """获取列表容量""" - return self._capacity - - def get(self, index: int) -> int: - """访问元素""" - # 索引如果越界则抛出异常,下同 - if index < 0 or index >= self._size: - raise IndexError("索引越界") - return self._arr[index] - - def set(self, num: int, index: int): - """更新元素""" - if index < 0 or index >= self._size: - raise IndexError("索引越界") - self._arr[index] = num - - def add(self, num: int): - """尾部添加元素""" - # 元素数量超出容量时,触发扩容机制 - if self.size() == self.capacity(): - self.extend_capacity() - self._arr[self._size] = num - self._size += 1 - - def insert(self, num: int, index: int): - """中间插入元素""" - if index < 0 or index >= self._size: - raise IndexError("索引越界") - # 元素数量超出容量时,触发扩容机制 - if self._size == self.capacity(): - self.extend_capacity() - # 将索引 index 以及之后的元素都向后移动一位 - for j in range(self._size - 1, index - 1, -1): - self._arr[j + 1] = self._arr[j] - self._arr[index] = num - # 更新元素数量 - self._size += 1 - - def remove(self, index: int) -> int: - """删除元素""" - if index < 0 or index >= self._size: - raise IndexError("索引越界") - num = self._arr[index] - # 索引 i 之后的元素都向前移动一位 - for j in range(index, self._size - 1): - self._arr[j] = self._arr[j + 1] - # 更新元素数量 - self._size -= 1 - # 返回被删除元素 - return num - - def extend_capacity(self): - """列表扩容""" - # 新建一个长度为原数组 __extend_ratio 倍的新数组,并将原数组拷贝到新数组 - self._arr = self._arr + [0] * self.capacity() * (self._extend_ratio - 1) - # 更新列表容量 - self._capacity = len(self._arr) - - def to_array(self) -> list[int]: - """返回有效长度的列表""" - return self._arr[: self._size] - - -"""Driver Code""" -if __name__ == "__main__": - # 初始化列表 - nums = MyList() - # 尾部添加元素 - nums.add(1) - nums.add(3) - nums.add(2) - nums.add(5) - nums.add(4) - print(f"列表 nums = {nums.to_array()} ,容量 = {nums.capacity()} ,长度 = {nums.size()}") - - # 中间插入元素 - nums.insert(6, index=3) - print("在索引 3 处插入数字 6 ,得到 nums =", nums.to_array()) - - # 删除元素 - nums.remove(3) - print("删除索引 3 处的元素,得到 nums =", nums.to_array()) - - # 访问元素 - num = nums.get(1) - print("访问索引 1 处的元素,得到 num =", num) - - # 更新元素 - nums.set(0, 1) - print("将索引 1 处的元素更新为 0 ,得到 nums =", nums.to_array()) - - # 测试扩容机制 - for i in range(10): - # 在 i = 5 时,列表长度将超出列表容量,此时触发扩容机制 - nums.add(i) - print(f"扩容后的列表 {nums.to_array()} ,容量 = {nums.capacity()} ,长度 = {nums.size()}") diff --git a/algorithms/hello_algo/modules/__init__.py b/algorithms/models/__init__.py similarity index 100% rename from algorithms/hello_algo/modules/__init__.py rename to algorithms/models/__init__.py diff --git a/algorithms/hello_algo/modules/list_node.py b/algorithms/models/list_node.py similarity index 96% rename from algorithms/hello_algo/modules/list_node.py rename to algorithms/models/list_node.py index 8baca16..fe0fed0 100644 --- a/algorithms/hello_algo/modules/list_node.py +++ b/algorithms/models/list_node.py @@ -1,7 +1,6 @@ """ File: list_node.py Created Time: 2021-12-11 -Author: Krahets (krahets@163.com) """ diff --git a/algorithms/hello_algo/modules/print_util.py b/algorithms/models/print_util.py similarity index 96% rename from algorithms/hello_algo/modules/print_util.py rename to algorithms/models/print_util.py index b210db3..793f2b0 100644 --- a/algorithms/hello_algo/modules/print_util.py +++ b/algorithms/models/print_util.py @@ -1,7 +1,6 @@ """ File: print_util.py Created Time: 2021-12-11 -Author: Krahets (krahets@163.com), msk397 (machangxinq@gmail.com) """ from .tree_node import TreeNode, list_to_tree diff --git a/algorithms/hello_algo/modules/tree_node.py b/algorithms/models/tree_node.py similarity index 98% rename from algorithms/hello_algo/modules/tree_node.py rename to algorithms/models/tree_node.py index 4aebcd9..4f0fe0e 100644 --- a/algorithms/hello_algo/modules/tree_node.py +++ b/algorithms/models/tree_node.py @@ -1,7 +1,6 @@ """ File: tree_node.py Created Time: 2021-12-11 -Author: Krahets (krahets@163.com) """ from collections import deque diff --git a/algorithms/hello_algo/modules/vertex.py b/algorithms/models/vertex.py similarity index 92% rename from algorithms/hello_algo/modules/vertex.py rename to algorithms/models/vertex.py index 012115d..b34168c 100644 --- a/algorithms/hello_algo/modules/vertex.py +++ b/algorithms/models/vertex.py @@ -1,7 +1,6 @@ # File: vertex.py # Created Time: 2023-02-23 -# Author: Krahets (krahets@163.com) - +# class Vertex: """顶点类""" diff --git a/algorithms/test.py b/algorithms/test.py deleted file mode 100644 index 3095b32..0000000 --- a/algorithms/test.py +++ /dev/null @@ -1,11 +0,0 @@ -class Father: - def __init__(self, choose_dir): - print(choose_dir) - self.choose_dir = choose_dir - - -if __name__ == '__main__': - import re - ss = re.split(r'([()+*/])|((?<=\d)-)', '(-12+(4+5+2)-3)+(-6+8)') - s = [s for s in ss if s] - print(s) diff --git a/algorithms/hello_algo/test_all.py b/algorithms/test_all.py similarity index 100% rename from algorithms/hello_algo/test_all.py rename to algorithms/test_all.py From ab94ddb5c9b6b51c7ef31081742755583c040a37 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Sat, 19 Apr 2025 10:36:13 +0800 Subject: [PATCH 53/54] update category --- README.md | 7 +++---- algorithms/{c14_leetcode => c13_leetcode}/__init__.py | 0 algorithms/{c14_leetcode => c13_leetcode}/p000/__init__.py | 0 .../p000/a05_longest_palindromic_substring.py | 0 .../p000/a19_remove_nth_node_from_end_of_list.py | 0 .../p000/a20_valid_parentheses.py | 0 .../p000/a21_merge_two_sorted_lists.py | 0 .../p000/a23_merge_k_sorted_lists.py | 0 .../p000/a70_climbing_stairs.py | 0 .../p000/a86_partition_list.py | 0 algorithms/{c14_leetcode => c13_leetcode}/p100/__init__.py | 0 .../p100/a141_linked_list_cycle.py | 0 .../p100/a142_linked_list_cycle_ii.py | 0 .../{c14_leetcode => c13_leetcode}/p100/a155_min_stack.py | 0 .../p100/a160_intersection_of_two_linked_lists.py | 0 .../p100/a167_two_sum_ii_input_array_is_sorted.py | 0 .../{c14_leetcode => c13_leetcode}/p1000/__init__.py | 0 .../{c14_leetcode => c13_leetcode}/p1100/__init__.py | 0 .../{c14_leetcode => c13_leetcode}/p1200/__init__.py | 0 .../{c14_leetcode => c13_leetcode}/p1300/__init__.py | 0 .../{c14_leetcode => c13_leetcode}/p1400/__init__.py | 0 .../{c14_leetcode => c13_leetcode}/p1500/__init__.py | 0 .../{c14_leetcode => c13_leetcode}/p1600/__init__.py | 0 .../{c14_leetcode => c13_leetcode}/p1700/__init__.py | 0 .../{c14_leetcode => c13_leetcode}/p1800/__init__.py | 0 .../{c14_leetcode => c13_leetcode}/p1900/__init__.py | 0 algorithms/{c14_leetcode => c13_leetcode}/p200/__init__.py | 0 .../p200/a206_reverse_linked_list.py | 0 .../p200/a215_kth_largest_element_in_an_array.py | 0 .../p200/a224_basic_calculator.py | 0 .../p200/a232_implement_queue_using_stacks.py | 0 .../p200/a283_move_zeroes.py | 0 .../{c14_leetcode => c13_leetcode}/p2000/__init__.py | 0 .../{c14_leetcode => c13_leetcode}/p2100/__init__.py | 0 .../{c14_leetcode => c13_leetcode}/p2200/__init__.py | 0 algorithms/{c14_leetcode => c13_leetcode}/p300/__init__.py | 0 .../p300/a392_is_subsequence.py | 0 algorithms/{c14_leetcode => c13_leetcode}/p400/__init__.py | 0 .../p400/a496_next_greater_element.py | 0 algorithms/{c14_leetcode => c13_leetcode}/p500/__init__.py | 0 algorithms/{c14_leetcode => c13_leetcode}/p600/__init__.py | 0 .../p600/a682_baseball_game.py | 0 algorithms/{c14_leetcode => c13_leetcode}/p700/__init__.py | 0 algorithms/{c14_leetcode => c13_leetcode}/p800/__init__.py | 0 .../p800/a844_backspace_string_compare.py | 0 .../p800/a876_middle_of_the_linked_list.py | 0 algorithms/{c14_leetcode => c13_leetcode}/p900/__init__.py | 0 algorithms/{c13_sample => c14_sample}/__init__.py | 0 algorithms/{c13_sample => c14_sample}/m01_math.py | 0 algorithms/{c13_sample => c14_sample}/m02_triangle_str.py | 0 .../{c13_sample => c14_sample}/m03_duplicate_words.py | 0 algorithms/{c13_sample => c14_sample}/m04_binary_add.py | 0 algorithms/{c13_sample => c14_sample}/m05_nine_number.py | 0 algorithms/{c13_sample => c14_sample}/m06_hornerpoly.py | 0 algorithms/{c13_sample => c14_sample}/m07_max_subarr.py | 0 algorithms/{c13_sample => c14_sample}/m08_max_subarr2.py | 0 algorithms/{c13_sample => c14_sample}/m09_max_subarr3.py | 0 algorithms/{c13_sample => c14_sample}/m10_code_funny.py | 0 algorithms/{c13_sample => c14_sample}/m11_rand_permute.py | 0 algorithms/{c13_sample => c14_sample}/m12_right_shift.py | 0 algorithms/{c13_sample => c14_sample}/m13_sin_cpu.py | 0 algorithms/{c13_sample => c14_sample}/m14_bestsinger.py | 0 algorithms/{c13_sample => c14_sample}/m15_bracket_match.py | 0 algorithms/{c13_sample => c14_sample}/m16_circle_queue.py | 0 64 files changed, 3 insertions(+), 4 deletions(-) rename algorithms/{c14_leetcode => c13_leetcode}/__init__.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p000/__init__.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p000/a05_longest_palindromic_substring.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p000/a19_remove_nth_node_from_end_of_list.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p000/a20_valid_parentheses.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p000/a21_merge_two_sorted_lists.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p000/a23_merge_k_sorted_lists.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p000/a70_climbing_stairs.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p000/a86_partition_list.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p100/__init__.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p100/a141_linked_list_cycle.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p100/a142_linked_list_cycle_ii.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p100/a155_min_stack.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p100/a160_intersection_of_two_linked_lists.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p100/a167_two_sum_ii_input_array_is_sorted.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p1000/__init__.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p1100/__init__.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p1200/__init__.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p1300/__init__.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p1400/__init__.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p1500/__init__.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p1600/__init__.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p1700/__init__.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p1800/__init__.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p1900/__init__.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p200/__init__.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p200/a206_reverse_linked_list.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p200/a215_kth_largest_element_in_an_array.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p200/a224_basic_calculator.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p200/a232_implement_queue_using_stacks.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p200/a283_move_zeroes.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p2000/__init__.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p2100/__init__.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p2200/__init__.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p300/__init__.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p300/a392_is_subsequence.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p400/__init__.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p400/a496_next_greater_element.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p500/__init__.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p600/__init__.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p600/a682_baseball_game.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p700/__init__.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p800/__init__.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p800/a844_backspace_string_compare.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p800/a876_middle_of_the_linked_list.py (100%) rename algorithms/{c14_leetcode => c13_leetcode}/p900/__init__.py (100%) rename algorithms/{c13_sample => c14_sample}/__init__.py (100%) rename algorithms/{c13_sample => c14_sample}/m01_math.py (100%) rename algorithms/{c13_sample => c14_sample}/m02_triangle_str.py (100%) rename algorithms/{c13_sample => c14_sample}/m03_duplicate_words.py (100%) rename algorithms/{c13_sample => c14_sample}/m04_binary_add.py (100%) rename algorithms/{c13_sample => c14_sample}/m05_nine_number.py (100%) rename algorithms/{c13_sample => c14_sample}/m06_hornerpoly.py (100%) rename algorithms/{c13_sample => c14_sample}/m07_max_subarr.py (100%) rename algorithms/{c13_sample => c14_sample}/m08_max_subarr2.py (100%) rename algorithms/{c13_sample => c14_sample}/m09_max_subarr3.py (100%) rename algorithms/{c13_sample => c14_sample}/m10_code_funny.py (100%) rename algorithms/{c13_sample => c14_sample}/m11_rand_permute.py (100%) rename algorithms/{c13_sample => c14_sample}/m12_right_shift.py (100%) rename algorithms/{c13_sample => c14_sample}/m13_sin_cpu.py (100%) rename algorithms/{c13_sample => c14_sample}/m14_bestsinger.py (100%) rename algorithms/{c13_sample => c14_sample}/m15_bracket_match.py (100%) rename algorithms/{c13_sample => c14_sample}/m16_circle_queue.py (100%) diff --git a/README.md b/README.md index 07adfed..cec741f 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,6 @@ * 《啊哈算法》 * 《算法导论》 * 《labuladong的算法小抄》 -* 《人工智能算法图解》 ## 章节说明 @@ -23,8 +22,8 @@ 10. 【第十章】贪心算法 11. 【第十一章】高级数据结构和算法 12. 【第十二章】AI算法 -13. 【第十三章】算法示例程序 -14. 【第十四章】LeetCode刷题记录 +13. 【第十三章】LeetCode刷题 +14. 【第十四章】算法小抄 ## 作者的话 @@ -56,7 +55,7 @@ You are welcome to contribute to the project as follow * commit new feature * add testcase -Meanwhile you'd better follow the rules below +Meanwhile, you'd better follow the rules below * It's *NOT* recommended to submit a pull request directly to `master` branch. `develop` branch is more appropriate * Follow common Python coding conventions diff --git a/algorithms/c14_leetcode/__init__.py b/algorithms/c13_leetcode/__init__.py similarity index 100% rename from algorithms/c14_leetcode/__init__.py rename to algorithms/c13_leetcode/__init__.py diff --git a/algorithms/c14_leetcode/p000/__init__.py b/algorithms/c13_leetcode/p000/__init__.py similarity index 100% rename from algorithms/c14_leetcode/p000/__init__.py rename to algorithms/c13_leetcode/p000/__init__.py diff --git a/algorithms/c14_leetcode/p000/a05_longest_palindromic_substring.py b/algorithms/c13_leetcode/p000/a05_longest_palindromic_substring.py similarity index 100% rename from algorithms/c14_leetcode/p000/a05_longest_palindromic_substring.py rename to algorithms/c13_leetcode/p000/a05_longest_palindromic_substring.py diff --git a/algorithms/c14_leetcode/p000/a19_remove_nth_node_from_end_of_list.py b/algorithms/c13_leetcode/p000/a19_remove_nth_node_from_end_of_list.py similarity index 100% rename from algorithms/c14_leetcode/p000/a19_remove_nth_node_from_end_of_list.py rename to algorithms/c13_leetcode/p000/a19_remove_nth_node_from_end_of_list.py diff --git a/algorithms/c14_leetcode/p000/a20_valid_parentheses.py b/algorithms/c13_leetcode/p000/a20_valid_parentheses.py similarity index 100% rename from algorithms/c14_leetcode/p000/a20_valid_parentheses.py rename to algorithms/c13_leetcode/p000/a20_valid_parentheses.py diff --git a/algorithms/c14_leetcode/p000/a21_merge_two_sorted_lists.py b/algorithms/c13_leetcode/p000/a21_merge_two_sorted_lists.py similarity index 100% rename from algorithms/c14_leetcode/p000/a21_merge_two_sorted_lists.py rename to algorithms/c13_leetcode/p000/a21_merge_two_sorted_lists.py diff --git a/algorithms/c14_leetcode/p000/a23_merge_k_sorted_lists.py b/algorithms/c13_leetcode/p000/a23_merge_k_sorted_lists.py similarity index 100% rename from algorithms/c14_leetcode/p000/a23_merge_k_sorted_lists.py rename to algorithms/c13_leetcode/p000/a23_merge_k_sorted_lists.py diff --git a/algorithms/c14_leetcode/p000/a70_climbing_stairs.py b/algorithms/c13_leetcode/p000/a70_climbing_stairs.py similarity index 100% rename from algorithms/c14_leetcode/p000/a70_climbing_stairs.py rename to algorithms/c13_leetcode/p000/a70_climbing_stairs.py diff --git a/algorithms/c14_leetcode/p000/a86_partition_list.py b/algorithms/c13_leetcode/p000/a86_partition_list.py similarity index 100% rename from algorithms/c14_leetcode/p000/a86_partition_list.py rename to algorithms/c13_leetcode/p000/a86_partition_list.py diff --git a/algorithms/c14_leetcode/p100/__init__.py b/algorithms/c13_leetcode/p100/__init__.py similarity index 100% rename from algorithms/c14_leetcode/p100/__init__.py rename to algorithms/c13_leetcode/p100/__init__.py diff --git a/algorithms/c14_leetcode/p100/a141_linked_list_cycle.py b/algorithms/c13_leetcode/p100/a141_linked_list_cycle.py similarity index 100% rename from algorithms/c14_leetcode/p100/a141_linked_list_cycle.py rename to algorithms/c13_leetcode/p100/a141_linked_list_cycle.py diff --git a/algorithms/c14_leetcode/p100/a142_linked_list_cycle_ii.py b/algorithms/c13_leetcode/p100/a142_linked_list_cycle_ii.py similarity index 100% rename from algorithms/c14_leetcode/p100/a142_linked_list_cycle_ii.py rename to algorithms/c13_leetcode/p100/a142_linked_list_cycle_ii.py diff --git a/algorithms/c14_leetcode/p100/a155_min_stack.py b/algorithms/c13_leetcode/p100/a155_min_stack.py similarity index 100% rename from algorithms/c14_leetcode/p100/a155_min_stack.py rename to algorithms/c13_leetcode/p100/a155_min_stack.py diff --git a/algorithms/c14_leetcode/p100/a160_intersection_of_two_linked_lists.py b/algorithms/c13_leetcode/p100/a160_intersection_of_two_linked_lists.py similarity index 100% rename from algorithms/c14_leetcode/p100/a160_intersection_of_two_linked_lists.py rename to algorithms/c13_leetcode/p100/a160_intersection_of_two_linked_lists.py diff --git a/algorithms/c14_leetcode/p100/a167_two_sum_ii_input_array_is_sorted.py b/algorithms/c13_leetcode/p100/a167_two_sum_ii_input_array_is_sorted.py similarity index 100% rename from algorithms/c14_leetcode/p100/a167_two_sum_ii_input_array_is_sorted.py rename to algorithms/c13_leetcode/p100/a167_two_sum_ii_input_array_is_sorted.py diff --git a/algorithms/c14_leetcode/p1000/__init__.py b/algorithms/c13_leetcode/p1000/__init__.py similarity index 100% rename from algorithms/c14_leetcode/p1000/__init__.py rename to algorithms/c13_leetcode/p1000/__init__.py diff --git a/algorithms/c14_leetcode/p1100/__init__.py b/algorithms/c13_leetcode/p1100/__init__.py similarity index 100% rename from algorithms/c14_leetcode/p1100/__init__.py rename to algorithms/c13_leetcode/p1100/__init__.py diff --git a/algorithms/c14_leetcode/p1200/__init__.py b/algorithms/c13_leetcode/p1200/__init__.py similarity index 100% rename from algorithms/c14_leetcode/p1200/__init__.py rename to algorithms/c13_leetcode/p1200/__init__.py diff --git a/algorithms/c14_leetcode/p1300/__init__.py b/algorithms/c13_leetcode/p1300/__init__.py similarity index 100% rename from algorithms/c14_leetcode/p1300/__init__.py rename to algorithms/c13_leetcode/p1300/__init__.py diff --git a/algorithms/c14_leetcode/p1400/__init__.py b/algorithms/c13_leetcode/p1400/__init__.py similarity index 100% rename from algorithms/c14_leetcode/p1400/__init__.py rename to algorithms/c13_leetcode/p1400/__init__.py diff --git a/algorithms/c14_leetcode/p1500/__init__.py b/algorithms/c13_leetcode/p1500/__init__.py similarity index 100% rename from algorithms/c14_leetcode/p1500/__init__.py rename to algorithms/c13_leetcode/p1500/__init__.py diff --git a/algorithms/c14_leetcode/p1600/__init__.py b/algorithms/c13_leetcode/p1600/__init__.py similarity index 100% rename from algorithms/c14_leetcode/p1600/__init__.py rename to algorithms/c13_leetcode/p1600/__init__.py diff --git a/algorithms/c14_leetcode/p1700/__init__.py b/algorithms/c13_leetcode/p1700/__init__.py similarity index 100% rename from algorithms/c14_leetcode/p1700/__init__.py rename to algorithms/c13_leetcode/p1700/__init__.py diff --git a/algorithms/c14_leetcode/p1800/__init__.py b/algorithms/c13_leetcode/p1800/__init__.py similarity index 100% rename from algorithms/c14_leetcode/p1800/__init__.py rename to algorithms/c13_leetcode/p1800/__init__.py diff --git a/algorithms/c14_leetcode/p1900/__init__.py b/algorithms/c13_leetcode/p1900/__init__.py similarity index 100% rename from algorithms/c14_leetcode/p1900/__init__.py rename to algorithms/c13_leetcode/p1900/__init__.py diff --git a/algorithms/c14_leetcode/p200/__init__.py b/algorithms/c13_leetcode/p200/__init__.py similarity index 100% rename from algorithms/c14_leetcode/p200/__init__.py rename to algorithms/c13_leetcode/p200/__init__.py diff --git a/algorithms/c14_leetcode/p200/a206_reverse_linked_list.py b/algorithms/c13_leetcode/p200/a206_reverse_linked_list.py similarity index 100% rename from algorithms/c14_leetcode/p200/a206_reverse_linked_list.py rename to algorithms/c13_leetcode/p200/a206_reverse_linked_list.py diff --git a/algorithms/c14_leetcode/p200/a215_kth_largest_element_in_an_array.py b/algorithms/c13_leetcode/p200/a215_kth_largest_element_in_an_array.py similarity index 100% rename from algorithms/c14_leetcode/p200/a215_kth_largest_element_in_an_array.py rename to algorithms/c13_leetcode/p200/a215_kth_largest_element_in_an_array.py diff --git a/algorithms/c14_leetcode/p200/a224_basic_calculator.py b/algorithms/c13_leetcode/p200/a224_basic_calculator.py similarity index 100% rename from algorithms/c14_leetcode/p200/a224_basic_calculator.py rename to algorithms/c13_leetcode/p200/a224_basic_calculator.py diff --git a/algorithms/c14_leetcode/p200/a232_implement_queue_using_stacks.py b/algorithms/c13_leetcode/p200/a232_implement_queue_using_stacks.py similarity index 100% rename from algorithms/c14_leetcode/p200/a232_implement_queue_using_stacks.py rename to algorithms/c13_leetcode/p200/a232_implement_queue_using_stacks.py diff --git a/algorithms/c14_leetcode/p200/a283_move_zeroes.py b/algorithms/c13_leetcode/p200/a283_move_zeroes.py similarity index 100% rename from algorithms/c14_leetcode/p200/a283_move_zeroes.py rename to algorithms/c13_leetcode/p200/a283_move_zeroes.py diff --git a/algorithms/c14_leetcode/p2000/__init__.py b/algorithms/c13_leetcode/p2000/__init__.py similarity index 100% rename from algorithms/c14_leetcode/p2000/__init__.py rename to algorithms/c13_leetcode/p2000/__init__.py diff --git a/algorithms/c14_leetcode/p2100/__init__.py b/algorithms/c13_leetcode/p2100/__init__.py similarity index 100% rename from algorithms/c14_leetcode/p2100/__init__.py rename to algorithms/c13_leetcode/p2100/__init__.py diff --git a/algorithms/c14_leetcode/p2200/__init__.py b/algorithms/c13_leetcode/p2200/__init__.py similarity index 100% rename from algorithms/c14_leetcode/p2200/__init__.py rename to algorithms/c13_leetcode/p2200/__init__.py diff --git a/algorithms/c14_leetcode/p300/__init__.py b/algorithms/c13_leetcode/p300/__init__.py similarity index 100% rename from algorithms/c14_leetcode/p300/__init__.py rename to algorithms/c13_leetcode/p300/__init__.py diff --git a/algorithms/c14_leetcode/p300/a392_is_subsequence.py b/algorithms/c13_leetcode/p300/a392_is_subsequence.py similarity index 100% rename from algorithms/c14_leetcode/p300/a392_is_subsequence.py rename to algorithms/c13_leetcode/p300/a392_is_subsequence.py diff --git a/algorithms/c14_leetcode/p400/__init__.py b/algorithms/c13_leetcode/p400/__init__.py similarity index 100% rename from algorithms/c14_leetcode/p400/__init__.py rename to algorithms/c13_leetcode/p400/__init__.py diff --git a/algorithms/c14_leetcode/p400/a496_next_greater_element.py b/algorithms/c13_leetcode/p400/a496_next_greater_element.py similarity index 100% rename from algorithms/c14_leetcode/p400/a496_next_greater_element.py rename to algorithms/c13_leetcode/p400/a496_next_greater_element.py diff --git a/algorithms/c14_leetcode/p500/__init__.py b/algorithms/c13_leetcode/p500/__init__.py similarity index 100% rename from algorithms/c14_leetcode/p500/__init__.py rename to algorithms/c13_leetcode/p500/__init__.py diff --git a/algorithms/c14_leetcode/p600/__init__.py b/algorithms/c13_leetcode/p600/__init__.py similarity index 100% rename from algorithms/c14_leetcode/p600/__init__.py rename to algorithms/c13_leetcode/p600/__init__.py diff --git a/algorithms/c14_leetcode/p600/a682_baseball_game.py b/algorithms/c13_leetcode/p600/a682_baseball_game.py similarity index 100% rename from algorithms/c14_leetcode/p600/a682_baseball_game.py rename to algorithms/c13_leetcode/p600/a682_baseball_game.py diff --git a/algorithms/c14_leetcode/p700/__init__.py b/algorithms/c13_leetcode/p700/__init__.py similarity index 100% rename from algorithms/c14_leetcode/p700/__init__.py rename to algorithms/c13_leetcode/p700/__init__.py diff --git a/algorithms/c14_leetcode/p800/__init__.py b/algorithms/c13_leetcode/p800/__init__.py similarity index 100% rename from algorithms/c14_leetcode/p800/__init__.py rename to algorithms/c13_leetcode/p800/__init__.py diff --git a/algorithms/c14_leetcode/p800/a844_backspace_string_compare.py b/algorithms/c13_leetcode/p800/a844_backspace_string_compare.py similarity index 100% rename from algorithms/c14_leetcode/p800/a844_backspace_string_compare.py rename to algorithms/c13_leetcode/p800/a844_backspace_string_compare.py diff --git a/algorithms/c14_leetcode/p800/a876_middle_of_the_linked_list.py b/algorithms/c13_leetcode/p800/a876_middle_of_the_linked_list.py similarity index 100% rename from algorithms/c14_leetcode/p800/a876_middle_of_the_linked_list.py rename to algorithms/c13_leetcode/p800/a876_middle_of_the_linked_list.py diff --git a/algorithms/c14_leetcode/p900/__init__.py b/algorithms/c13_leetcode/p900/__init__.py similarity index 100% rename from algorithms/c14_leetcode/p900/__init__.py rename to algorithms/c13_leetcode/p900/__init__.py diff --git a/algorithms/c13_sample/__init__.py b/algorithms/c14_sample/__init__.py similarity index 100% rename from algorithms/c13_sample/__init__.py rename to algorithms/c14_sample/__init__.py diff --git a/algorithms/c13_sample/m01_math.py b/algorithms/c14_sample/m01_math.py similarity index 100% rename from algorithms/c13_sample/m01_math.py rename to algorithms/c14_sample/m01_math.py diff --git a/algorithms/c13_sample/m02_triangle_str.py b/algorithms/c14_sample/m02_triangle_str.py similarity index 100% rename from algorithms/c13_sample/m02_triangle_str.py rename to algorithms/c14_sample/m02_triangle_str.py diff --git a/algorithms/c13_sample/m03_duplicate_words.py b/algorithms/c14_sample/m03_duplicate_words.py similarity index 100% rename from algorithms/c13_sample/m03_duplicate_words.py rename to algorithms/c14_sample/m03_duplicate_words.py diff --git a/algorithms/c13_sample/m04_binary_add.py b/algorithms/c14_sample/m04_binary_add.py similarity index 100% rename from algorithms/c13_sample/m04_binary_add.py rename to algorithms/c14_sample/m04_binary_add.py diff --git a/algorithms/c13_sample/m05_nine_number.py b/algorithms/c14_sample/m05_nine_number.py similarity index 100% rename from algorithms/c13_sample/m05_nine_number.py rename to algorithms/c14_sample/m05_nine_number.py diff --git a/algorithms/c13_sample/m06_hornerpoly.py b/algorithms/c14_sample/m06_hornerpoly.py similarity index 100% rename from algorithms/c13_sample/m06_hornerpoly.py rename to algorithms/c14_sample/m06_hornerpoly.py diff --git a/algorithms/c13_sample/m07_max_subarr.py b/algorithms/c14_sample/m07_max_subarr.py similarity index 100% rename from algorithms/c13_sample/m07_max_subarr.py rename to algorithms/c14_sample/m07_max_subarr.py diff --git a/algorithms/c13_sample/m08_max_subarr2.py b/algorithms/c14_sample/m08_max_subarr2.py similarity index 100% rename from algorithms/c13_sample/m08_max_subarr2.py rename to algorithms/c14_sample/m08_max_subarr2.py diff --git a/algorithms/c13_sample/m09_max_subarr3.py b/algorithms/c14_sample/m09_max_subarr3.py similarity index 100% rename from algorithms/c13_sample/m09_max_subarr3.py rename to algorithms/c14_sample/m09_max_subarr3.py diff --git a/algorithms/c13_sample/m10_code_funny.py b/algorithms/c14_sample/m10_code_funny.py similarity index 100% rename from algorithms/c13_sample/m10_code_funny.py rename to algorithms/c14_sample/m10_code_funny.py diff --git a/algorithms/c13_sample/m11_rand_permute.py b/algorithms/c14_sample/m11_rand_permute.py similarity index 100% rename from algorithms/c13_sample/m11_rand_permute.py rename to algorithms/c14_sample/m11_rand_permute.py diff --git a/algorithms/c13_sample/m12_right_shift.py b/algorithms/c14_sample/m12_right_shift.py similarity index 100% rename from algorithms/c13_sample/m12_right_shift.py rename to algorithms/c14_sample/m12_right_shift.py diff --git a/algorithms/c13_sample/m13_sin_cpu.py b/algorithms/c14_sample/m13_sin_cpu.py similarity index 100% rename from algorithms/c13_sample/m13_sin_cpu.py rename to algorithms/c14_sample/m13_sin_cpu.py diff --git a/algorithms/c13_sample/m14_bestsinger.py b/algorithms/c14_sample/m14_bestsinger.py similarity index 100% rename from algorithms/c13_sample/m14_bestsinger.py rename to algorithms/c14_sample/m14_bestsinger.py diff --git a/algorithms/c13_sample/m15_bracket_match.py b/algorithms/c14_sample/m15_bracket_match.py similarity index 100% rename from algorithms/c13_sample/m15_bracket_match.py rename to algorithms/c14_sample/m15_bracket_match.py diff --git a/algorithms/c13_sample/m16_circle_queue.py b/algorithms/c14_sample/m16_circle_queue.py similarity index 100% rename from algorithms/c13_sample/m16_circle_queue.py rename to algorithms/c14_sample/m16_circle_queue.py From adb52092f0b7fdfb98cb3bc4f98fecbf83771260 Mon Sep 17 00:00:00 2001 From: xiongneng Date: Sun, 20 Jul 2025 16:08:00 +0800 Subject: [PATCH 54/54] update category --- README.md | 8 ++++---- algorithms/{c13_leetcode => c12_leetcode}/__init__.py | 0 algorithms/{c12_ai => c12_leetcode/p000}/__init__.py | 0 .../p000/a05_longest_palindromic_substring.py | 0 .../p000/a19_remove_nth_node_from_end_of_list.py | 0 .../p000/a20_valid_parentheses.py | 0 .../p000/a21_merge_two_sorted_lists.py | 0 .../p000/a23_merge_k_sorted_lists.py | 0 .../p000/a70_climbing_stairs.py | 0 .../p000/a86_partition_list.py | 0 .../{c13_leetcode/p000 => c12_leetcode/p100}/__init__.py | 0 .../p100/a141_linked_list_cycle.py | 0 .../p100/a142_linked_list_cycle_ii.py | 0 .../{c13_leetcode => c12_leetcode}/p100/a155_min_stack.py | 0 .../p100/a160_intersection_of_two_linked_lists.py | 0 .../p100/a167_two_sum_ii_input_array_is_sorted.py | 0 .../{c13_leetcode/p100 => c12_leetcode/p1000}/__init__.py | 0 .../p1000 => c12_leetcode/p1100}/__init__.py | 0 .../p1100 => c12_leetcode/p1200}/__init__.py | 0 .../p1200 => c12_leetcode/p1300}/__init__.py | 0 .../p1300 => c12_leetcode/p1400}/__init__.py | 0 .../p1400 => c12_leetcode/p1500}/__init__.py | 0 .../p1500 => c12_leetcode/p1600}/__init__.py | 0 .../p1600 => c12_leetcode/p1700}/__init__.py | 0 .../p1700 => c12_leetcode/p1800}/__init__.py | 0 .../p1800 => c12_leetcode/p1900}/__init__.py | 0 .../{c13_leetcode/p1900 => c12_leetcode/p200}/__init__.py | 0 .../p200/a206_reverse_linked_list.py | 0 .../p200/a215_kth_largest_element_in_an_array.py | 0 .../p200/a224_basic_calculator.py | 0 .../p200/a232_implement_queue_using_stacks.py | 0 .../p200/a283_move_zeroes.py | 0 .../{c13_leetcode/p200 => c12_leetcode/p2000}/__init__.py | 0 .../p2000 => c12_leetcode/p2100}/__init__.py | 0 .../p2100 => c12_leetcode/p2200}/__init__.py | 0 .../{c13_leetcode/p2200 => c12_leetcode/p300}/__init__.py | 0 .../p300/a392_is_subsequence.py | 0 .../{c13_leetcode/p300 => c12_leetcode/p400}/__init__.py | 0 .../p400/a496_next_greater_element.py | 0 .../{c13_leetcode/p400 => c12_leetcode/p500}/__init__.py | 0 .../{c13_leetcode/p500 => c12_leetcode/p600}/__init__.py | 0 .../p600/a682_baseball_game.py | 0 .../{c13_leetcode/p600 => c12_leetcode/p700}/__init__.py | 0 .../{c13_leetcode/p700 => c12_leetcode/p800}/__init__.py | 0 .../p800/a844_backspace_string_compare.py | 0 .../p800/a876_middle_of_the_linked_list.py | 0 .../{c13_leetcode/p800 => c12_leetcode/p900}/__init__.py | 0 algorithms/{c13_leetcode/p900 => c13_ai}/__init__.py | 0 algorithms/{c12_ai => c13_ai}/basic/__init__.py | 0 algorithms/{c12_ai => c13_ai}/basic/a01_maze_bfs.py | 0 algorithms/{c12_ai => c13_ai}/basic/a02_maze_dfs.py | 0 51 files changed, 4 insertions(+), 4 deletions(-) rename algorithms/{c13_leetcode => c12_leetcode}/__init__.py (100%) rename algorithms/{c12_ai => c12_leetcode/p000}/__init__.py (100%) rename algorithms/{c13_leetcode => c12_leetcode}/p000/a05_longest_palindromic_substring.py (100%) rename algorithms/{c13_leetcode => c12_leetcode}/p000/a19_remove_nth_node_from_end_of_list.py (100%) rename algorithms/{c13_leetcode => c12_leetcode}/p000/a20_valid_parentheses.py (100%) rename algorithms/{c13_leetcode => c12_leetcode}/p000/a21_merge_two_sorted_lists.py (100%) rename algorithms/{c13_leetcode => c12_leetcode}/p000/a23_merge_k_sorted_lists.py (100%) rename algorithms/{c13_leetcode => c12_leetcode}/p000/a70_climbing_stairs.py (100%) rename algorithms/{c13_leetcode => c12_leetcode}/p000/a86_partition_list.py (100%) rename algorithms/{c13_leetcode/p000 => c12_leetcode/p100}/__init__.py (100%) rename algorithms/{c13_leetcode => c12_leetcode}/p100/a141_linked_list_cycle.py (100%) rename algorithms/{c13_leetcode => c12_leetcode}/p100/a142_linked_list_cycle_ii.py (100%) rename algorithms/{c13_leetcode => c12_leetcode}/p100/a155_min_stack.py (100%) rename algorithms/{c13_leetcode => c12_leetcode}/p100/a160_intersection_of_two_linked_lists.py (100%) rename algorithms/{c13_leetcode => c12_leetcode}/p100/a167_two_sum_ii_input_array_is_sorted.py (100%) rename algorithms/{c13_leetcode/p100 => c12_leetcode/p1000}/__init__.py (100%) rename algorithms/{c13_leetcode/p1000 => c12_leetcode/p1100}/__init__.py (100%) rename algorithms/{c13_leetcode/p1100 => c12_leetcode/p1200}/__init__.py (100%) rename algorithms/{c13_leetcode/p1200 => c12_leetcode/p1300}/__init__.py (100%) rename algorithms/{c13_leetcode/p1300 => c12_leetcode/p1400}/__init__.py (100%) rename algorithms/{c13_leetcode/p1400 => c12_leetcode/p1500}/__init__.py (100%) rename algorithms/{c13_leetcode/p1500 => c12_leetcode/p1600}/__init__.py (100%) rename algorithms/{c13_leetcode/p1600 => c12_leetcode/p1700}/__init__.py (100%) rename algorithms/{c13_leetcode/p1700 => c12_leetcode/p1800}/__init__.py (100%) rename algorithms/{c13_leetcode/p1800 => c12_leetcode/p1900}/__init__.py (100%) rename algorithms/{c13_leetcode/p1900 => c12_leetcode/p200}/__init__.py (100%) rename algorithms/{c13_leetcode => c12_leetcode}/p200/a206_reverse_linked_list.py (100%) rename algorithms/{c13_leetcode => c12_leetcode}/p200/a215_kth_largest_element_in_an_array.py (100%) rename algorithms/{c13_leetcode => c12_leetcode}/p200/a224_basic_calculator.py (100%) rename algorithms/{c13_leetcode => c12_leetcode}/p200/a232_implement_queue_using_stacks.py (100%) rename algorithms/{c13_leetcode => c12_leetcode}/p200/a283_move_zeroes.py (100%) rename algorithms/{c13_leetcode/p200 => c12_leetcode/p2000}/__init__.py (100%) rename algorithms/{c13_leetcode/p2000 => c12_leetcode/p2100}/__init__.py (100%) rename algorithms/{c13_leetcode/p2100 => c12_leetcode/p2200}/__init__.py (100%) rename algorithms/{c13_leetcode/p2200 => c12_leetcode/p300}/__init__.py (100%) rename algorithms/{c13_leetcode => c12_leetcode}/p300/a392_is_subsequence.py (100%) rename algorithms/{c13_leetcode/p300 => c12_leetcode/p400}/__init__.py (100%) rename algorithms/{c13_leetcode => c12_leetcode}/p400/a496_next_greater_element.py (100%) rename algorithms/{c13_leetcode/p400 => c12_leetcode/p500}/__init__.py (100%) rename algorithms/{c13_leetcode/p500 => c12_leetcode/p600}/__init__.py (100%) rename algorithms/{c13_leetcode => c12_leetcode}/p600/a682_baseball_game.py (100%) rename algorithms/{c13_leetcode/p600 => c12_leetcode/p700}/__init__.py (100%) rename algorithms/{c13_leetcode/p700 => c12_leetcode/p800}/__init__.py (100%) rename algorithms/{c13_leetcode => c12_leetcode}/p800/a844_backspace_string_compare.py (100%) rename algorithms/{c13_leetcode => c12_leetcode}/p800/a876_middle_of_the_linked_list.py (100%) rename algorithms/{c13_leetcode/p800 => c12_leetcode/p900}/__init__.py (100%) rename algorithms/{c13_leetcode/p900 => c13_ai}/__init__.py (100%) rename algorithms/{c12_ai => c13_ai}/basic/__init__.py (100%) rename algorithms/{c12_ai => c13_ai}/basic/a01_maze_bfs.py (100%) rename algorithms/{c12_ai => c13_ai}/basic/a02_maze_dfs.py (100%) diff --git a/README.md b/README.md index cec741f..4900804 100644 --- a/README.md +++ b/README.md @@ -21,16 +21,16 @@ 9. 【第九章】动态规划算法 10. 【第十章】贪心算法 11. 【第十一章】高级数据结构和算法 -12. 【第十二章】AI算法 -13. 【第十三章】LeetCode刷题 +12. 【第十三章】LeetCode刷题 +13. 【第十二章】AI算法 14. 【第十四章】算法小抄 ## 作者的话 书中经典的算法示例使用python3语言实现。 -整个工程分为三个部分。第一部分是阅读经典算法书籍后自己的总结,作为基础算法部分。 -第二部分是人工智能AI算法示例,第三部分是自己在LeetCode上面的刷题总结。 +整个工程分为三个部分。第一部分是阅读经典算法书籍后自己的总结,作为基础算法部分。 +第二部分是自己在LeetCode上面的刷题总结,第三部分是人工智能AI算法示例。 从2013年就开始写这个系列,写到动态规划后就停了,那段时间实在是太懒了。 今年2020年开始决定继续把之前的捡起来,重新更新这个系列,做事情得有始有终,希望能把这个系列坚持写完。 diff --git a/algorithms/c13_leetcode/__init__.py b/algorithms/c12_leetcode/__init__.py similarity index 100% rename from algorithms/c13_leetcode/__init__.py rename to algorithms/c12_leetcode/__init__.py diff --git a/algorithms/c12_ai/__init__.py b/algorithms/c12_leetcode/p000/__init__.py similarity index 100% rename from algorithms/c12_ai/__init__.py rename to algorithms/c12_leetcode/p000/__init__.py diff --git a/algorithms/c13_leetcode/p000/a05_longest_palindromic_substring.py b/algorithms/c12_leetcode/p000/a05_longest_palindromic_substring.py similarity index 100% rename from algorithms/c13_leetcode/p000/a05_longest_palindromic_substring.py rename to algorithms/c12_leetcode/p000/a05_longest_palindromic_substring.py diff --git a/algorithms/c13_leetcode/p000/a19_remove_nth_node_from_end_of_list.py b/algorithms/c12_leetcode/p000/a19_remove_nth_node_from_end_of_list.py similarity index 100% rename from algorithms/c13_leetcode/p000/a19_remove_nth_node_from_end_of_list.py rename to algorithms/c12_leetcode/p000/a19_remove_nth_node_from_end_of_list.py diff --git a/algorithms/c13_leetcode/p000/a20_valid_parentheses.py b/algorithms/c12_leetcode/p000/a20_valid_parentheses.py similarity index 100% rename from algorithms/c13_leetcode/p000/a20_valid_parentheses.py rename to algorithms/c12_leetcode/p000/a20_valid_parentheses.py diff --git a/algorithms/c13_leetcode/p000/a21_merge_two_sorted_lists.py b/algorithms/c12_leetcode/p000/a21_merge_two_sorted_lists.py similarity index 100% rename from algorithms/c13_leetcode/p000/a21_merge_two_sorted_lists.py rename to algorithms/c12_leetcode/p000/a21_merge_two_sorted_lists.py diff --git a/algorithms/c13_leetcode/p000/a23_merge_k_sorted_lists.py b/algorithms/c12_leetcode/p000/a23_merge_k_sorted_lists.py similarity index 100% rename from algorithms/c13_leetcode/p000/a23_merge_k_sorted_lists.py rename to algorithms/c12_leetcode/p000/a23_merge_k_sorted_lists.py diff --git a/algorithms/c13_leetcode/p000/a70_climbing_stairs.py b/algorithms/c12_leetcode/p000/a70_climbing_stairs.py similarity index 100% rename from algorithms/c13_leetcode/p000/a70_climbing_stairs.py rename to algorithms/c12_leetcode/p000/a70_climbing_stairs.py diff --git a/algorithms/c13_leetcode/p000/a86_partition_list.py b/algorithms/c12_leetcode/p000/a86_partition_list.py similarity index 100% rename from algorithms/c13_leetcode/p000/a86_partition_list.py rename to algorithms/c12_leetcode/p000/a86_partition_list.py diff --git a/algorithms/c13_leetcode/p000/__init__.py b/algorithms/c12_leetcode/p100/__init__.py similarity index 100% rename from algorithms/c13_leetcode/p000/__init__.py rename to algorithms/c12_leetcode/p100/__init__.py diff --git a/algorithms/c13_leetcode/p100/a141_linked_list_cycle.py b/algorithms/c12_leetcode/p100/a141_linked_list_cycle.py similarity index 100% rename from algorithms/c13_leetcode/p100/a141_linked_list_cycle.py rename to algorithms/c12_leetcode/p100/a141_linked_list_cycle.py diff --git a/algorithms/c13_leetcode/p100/a142_linked_list_cycle_ii.py b/algorithms/c12_leetcode/p100/a142_linked_list_cycle_ii.py similarity index 100% rename from algorithms/c13_leetcode/p100/a142_linked_list_cycle_ii.py rename to algorithms/c12_leetcode/p100/a142_linked_list_cycle_ii.py diff --git a/algorithms/c13_leetcode/p100/a155_min_stack.py b/algorithms/c12_leetcode/p100/a155_min_stack.py similarity index 100% rename from algorithms/c13_leetcode/p100/a155_min_stack.py rename to algorithms/c12_leetcode/p100/a155_min_stack.py diff --git a/algorithms/c13_leetcode/p100/a160_intersection_of_two_linked_lists.py b/algorithms/c12_leetcode/p100/a160_intersection_of_two_linked_lists.py similarity index 100% rename from algorithms/c13_leetcode/p100/a160_intersection_of_two_linked_lists.py rename to algorithms/c12_leetcode/p100/a160_intersection_of_two_linked_lists.py diff --git a/algorithms/c13_leetcode/p100/a167_two_sum_ii_input_array_is_sorted.py b/algorithms/c12_leetcode/p100/a167_two_sum_ii_input_array_is_sorted.py similarity index 100% rename from algorithms/c13_leetcode/p100/a167_two_sum_ii_input_array_is_sorted.py rename to algorithms/c12_leetcode/p100/a167_two_sum_ii_input_array_is_sorted.py diff --git a/algorithms/c13_leetcode/p100/__init__.py b/algorithms/c12_leetcode/p1000/__init__.py similarity index 100% rename from algorithms/c13_leetcode/p100/__init__.py rename to algorithms/c12_leetcode/p1000/__init__.py diff --git a/algorithms/c13_leetcode/p1000/__init__.py b/algorithms/c12_leetcode/p1100/__init__.py similarity index 100% rename from algorithms/c13_leetcode/p1000/__init__.py rename to algorithms/c12_leetcode/p1100/__init__.py diff --git a/algorithms/c13_leetcode/p1100/__init__.py b/algorithms/c12_leetcode/p1200/__init__.py similarity index 100% rename from algorithms/c13_leetcode/p1100/__init__.py rename to algorithms/c12_leetcode/p1200/__init__.py diff --git a/algorithms/c13_leetcode/p1200/__init__.py b/algorithms/c12_leetcode/p1300/__init__.py similarity index 100% rename from algorithms/c13_leetcode/p1200/__init__.py rename to algorithms/c12_leetcode/p1300/__init__.py diff --git a/algorithms/c13_leetcode/p1300/__init__.py b/algorithms/c12_leetcode/p1400/__init__.py similarity index 100% rename from algorithms/c13_leetcode/p1300/__init__.py rename to algorithms/c12_leetcode/p1400/__init__.py diff --git a/algorithms/c13_leetcode/p1400/__init__.py b/algorithms/c12_leetcode/p1500/__init__.py similarity index 100% rename from algorithms/c13_leetcode/p1400/__init__.py rename to algorithms/c12_leetcode/p1500/__init__.py diff --git a/algorithms/c13_leetcode/p1500/__init__.py b/algorithms/c12_leetcode/p1600/__init__.py similarity index 100% rename from algorithms/c13_leetcode/p1500/__init__.py rename to algorithms/c12_leetcode/p1600/__init__.py diff --git a/algorithms/c13_leetcode/p1600/__init__.py b/algorithms/c12_leetcode/p1700/__init__.py similarity index 100% rename from algorithms/c13_leetcode/p1600/__init__.py rename to algorithms/c12_leetcode/p1700/__init__.py diff --git a/algorithms/c13_leetcode/p1700/__init__.py b/algorithms/c12_leetcode/p1800/__init__.py similarity index 100% rename from algorithms/c13_leetcode/p1700/__init__.py rename to algorithms/c12_leetcode/p1800/__init__.py diff --git a/algorithms/c13_leetcode/p1800/__init__.py b/algorithms/c12_leetcode/p1900/__init__.py similarity index 100% rename from algorithms/c13_leetcode/p1800/__init__.py rename to algorithms/c12_leetcode/p1900/__init__.py diff --git a/algorithms/c13_leetcode/p1900/__init__.py b/algorithms/c12_leetcode/p200/__init__.py similarity index 100% rename from algorithms/c13_leetcode/p1900/__init__.py rename to algorithms/c12_leetcode/p200/__init__.py diff --git a/algorithms/c13_leetcode/p200/a206_reverse_linked_list.py b/algorithms/c12_leetcode/p200/a206_reverse_linked_list.py similarity index 100% rename from algorithms/c13_leetcode/p200/a206_reverse_linked_list.py rename to algorithms/c12_leetcode/p200/a206_reverse_linked_list.py diff --git a/algorithms/c13_leetcode/p200/a215_kth_largest_element_in_an_array.py b/algorithms/c12_leetcode/p200/a215_kth_largest_element_in_an_array.py similarity index 100% rename from algorithms/c13_leetcode/p200/a215_kth_largest_element_in_an_array.py rename to algorithms/c12_leetcode/p200/a215_kth_largest_element_in_an_array.py diff --git a/algorithms/c13_leetcode/p200/a224_basic_calculator.py b/algorithms/c12_leetcode/p200/a224_basic_calculator.py similarity index 100% rename from algorithms/c13_leetcode/p200/a224_basic_calculator.py rename to algorithms/c12_leetcode/p200/a224_basic_calculator.py diff --git a/algorithms/c13_leetcode/p200/a232_implement_queue_using_stacks.py b/algorithms/c12_leetcode/p200/a232_implement_queue_using_stacks.py similarity index 100% rename from algorithms/c13_leetcode/p200/a232_implement_queue_using_stacks.py rename to algorithms/c12_leetcode/p200/a232_implement_queue_using_stacks.py diff --git a/algorithms/c13_leetcode/p200/a283_move_zeroes.py b/algorithms/c12_leetcode/p200/a283_move_zeroes.py similarity index 100% rename from algorithms/c13_leetcode/p200/a283_move_zeroes.py rename to algorithms/c12_leetcode/p200/a283_move_zeroes.py diff --git a/algorithms/c13_leetcode/p200/__init__.py b/algorithms/c12_leetcode/p2000/__init__.py similarity index 100% rename from algorithms/c13_leetcode/p200/__init__.py rename to algorithms/c12_leetcode/p2000/__init__.py diff --git a/algorithms/c13_leetcode/p2000/__init__.py b/algorithms/c12_leetcode/p2100/__init__.py similarity index 100% rename from algorithms/c13_leetcode/p2000/__init__.py rename to algorithms/c12_leetcode/p2100/__init__.py diff --git a/algorithms/c13_leetcode/p2100/__init__.py b/algorithms/c12_leetcode/p2200/__init__.py similarity index 100% rename from algorithms/c13_leetcode/p2100/__init__.py rename to algorithms/c12_leetcode/p2200/__init__.py diff --git a/algorithms/c13_leetcode/p2200/__init__.py b/algorithms/c12_leetcode/p300/__init__.py similarity index 100% rename from algorithms/c13_leetcode/p2200/__init__.py rename to algorithms/c12_leetcode/p300/__init__.py diff --git a/algorithms/c13_leetcode/p300/a392_is_subsequence.py b/algorithms/c12_leetcode/p300/a392_is_subsequence.py similarity index 100% rename from algorithms/c13_leetcode/p300/a392_is_subsequence.py rename to algorithms/c12_leetcode/p300/a392_is_subsequence.py diff --git a/algorithms/c13_leetcode/p300/__init__.py b/algorithms/c12_leetcode/p400/__init__.py similarity index 100% rename from algorithms/c13_leetcode/p300/__init__.py rename to algorithms/c12_leetcode/p400/__init__.py diff --git a/algorithms/c13_leetcode/p400/a496_next_greater_element.py b/algorithms/c12_leetcode/p400/a496_next_greater_element.py similarity index 100% rename from algorithms/c13_leetcode/p400/a496_next_greater_element.py rename to algorithms/c12_leetcode/p400/a496_next_greater_element.py diff --git a/algorithms/c13_leetcode/p400/__init__.py b/algorithms/c12_leetcode/p500/__init__.py similarity index 100% rename from algorithms/c13_leetcode/p400/__init__.py rename to algorithms/c12_leetcode/p500/__init__.py diff --git a/algorithms/c13_leetcode/p500/__init__.py b/algorithms/c12_leetcode/p600/__init__.py similarity index 100% rename from algorithms/c13_leetcode/p500/__init__.py rename to algorithms/c12_leetcode/p600/__init__.py diff --git a/algorithms/c13_leetcode/p600/a682_baseball_game.py b/algorithms/c12_leetcode/p600/a682_baseball_game.py similarity index 100% rename from algorithms/c13_leetcode/p600/a682_baseball_game.py rename to algorithms/c12_leetcode/p600/a682_baseball_game.py diff --git a/algorithms/c13_leetcode/p600/__init__.py b/algorithms/c12_leetcode/p700/__init__.py similarity index 100% rename from algorithms/c13_leetcode/p600/__init__.py rename to algorithms/c12_leetcode/p700/__init__.py diff --git a/algorithms/c13_leetcode/p700/__init__.py b/algorithms/c12_leetcode/p800/__init__.py similarity index 100% rename from algorithms/c13_leetcode/p700/__init__.py rename to algorithms/c12_leetcode/p800/__init__.py diff --git a/algorithms/c13_leetcode/p800/a844_backspace_string_compare.py b/algorithms/c12_leetcode/p800/a844_backspace_string_compare.py similarity index 100% rename from algorithms/c13_leetcode/p800/a844_backspace_string_compare.py rename to algorithms/c12_leetcode/p800/a844_backspace_string_compare.py diff --git a/algorithms/c13_leetcode/p800/a876_middle_of_the_linked_list.py b/algorithms/c12_leetcode/p800/a876_middle_of_the_linked_list.py similarity index 100% rename from algorithms/c13_leetcode/p800/a876_middle_of_the_linked_list.py rename to algorithms/c12_leetcode/p800/a876_middle_of_the_linked_list.py diff --git a/algorithms/c13_leetcode/p800/__init__.py b/algorithms/c12_leetcode/p900/__init__.py similarity index 100% rename from algorithms/c13_leetcode/p800/__init__.py rename to algorithms/c12_leetcode/p900/__init__.py diff --git a/algorithms/c13_leetcode/p900/__init__.py b/algorithms/c13_ai/__init__.py similarity index 100% rename from algorithms/c13_leetcode/p900/__init__.py rename to algorithms/c13_ai/__init__.py diff --git a/algorithms/c12_ai/basic/__init__.py b/algorithms/c13_ai/basic/__init__.py similarity index 100% rename from algorithms/c12_ai/basic/__init__.py rename to algorithms/c13_ai/basic/__init__.py diff --git a/algorithms/c12_ai/basic/a01_maze_bfs.py b/algorithms/c13_ai/basic/a01_maze_bfs.py similarity index 100% rename from algorithms/c12_ai/basic/a01_maze_bfs.py rename to algorithms/c13_ai/basic/a01_maze_bfs.py diff --git a/algorithms/c12_ai/basic/a02_maze_dfs.py b/algorithms/c13_ai/basic/a02_maze_dfs.py similarity index 100% rename from algorithms/c12_ai/basic/a02_maze_dfs.py rename to algorithms/c13_ai/basic/a02_maze_dfs.py