Leetcode
python 数据结构与算法 leetcode 算法题与书籍 刷算法全靠套路与总结!Crack LeetCode, not only how, but also why.
Install / Use
/learn @ls1248659692/LeetcodeREADME
Leetcode -- 一步一步成为 offer 收割机 (算法全都是套路,牢记算法模板,offer拿到手软)
作者: Jam
算法有三种:面试算法,竞赛算法和工程算法, 针对不同的类型需要采取不一样的策略和系统性练习,本仓库主要针对面试算法。
竞赛算法追求的是在一定的时间内,实现一定的算法和数据结构,以解决某一特定的、可能并不具有现实意义的问题,主要用于培养算法思维。
工程算法追求的是实现一定的算法和数据结构以解决某一特定的具有实际现实意义的问题,对运行速度有极致的追求会直接影响用户体验。
个人简介: 化工行业转行计算机全靠自学,目前在国内大厂工作,在力扣上传了数百道问题的解法,本仓库主要是为了总结算法套路与帮助和我一样转行,以及想深入学习算法有大厂梦的兄弟和姐妹们。
刷题写代码环境, IDE选用 Pycharm 配置几个必要写代码插件 Pycharm 写代码插件 ,并配置 leetcode 刷题插件 方便直接拉取 Leetcode-cn 算法题,直接在IDE 里面写代码和套用算法模板,提高刷题效率,选用 Python 作为刷算法题语言,主要原因也是刷题效率。
算法题分类思维导图:

- 本仓库的 spider 文件夹下 spider/problems 都是基于 LeetCode 的题目和解法,已经爬取了Leetcode-cn 的全部算法练习题,已经按照不同类型分类规整整理,方便后续算法题对比与总结 。有助于帮助大家做到同类型题 举一反三,一通百通
- 本仓库的 book 文件夹下 算法体系化学习书籍和面试题有相关算法系统学习书籍和题目推荐, 主要是针对算法入门的小伙伴参考。
- 做算法常用 Python 的标准库中有很多内置函数,它们的运行效率都很高,因为很多标准库是使用 C 语言编写的,不要重复造轮子,不要重复造轮子,不要重复造轮子。

Leetcode 科学刷题总结
- 职业训练:拆分知识点、刻意练习、总结
- 五步刷题法(五毒神掌)
- 做算法的最大误区:只刷一遍
- 新手建议先从简单题开始刷起,从30min/题 提升到 5min/题 就可以开始挑战刷中等难度题
- 大厂面试只要你能不看答案刷中等难度题,基本国内大厂随便进(能够讲出如何优化算法并实现,提高算法时间效率一般面试官会给比较好的评价)
- 始终保持匀速前进,既不松懈倦怠,亦不急于求成,定时归纳总结, 按类训练,深度理解人的记忆规律,高频率高效复习
- 拥抱孤独, 过滤外界杂音, 平稳心态
面试技巧:
- 确定和面试官沟通的是否一致,问清楚,题目要看清楚
- 想所有可能的解法,找时间最优解法
- coding(多写)
- test cases(测试样例)
五毒神掌内功心法
第一遍:
- 读题:5分钟读题+思考
- 自己暴力破解并对暴力破解方法进行优化
- 优化后看解法(理解多个解法)比较自己和高赞题解的区别并学习
- 根据别人的题解思路背诵默写
第二遍:
- 马上自己写,提交lc(leetcode),代码要简洁与优美,完全按照pep8规范
- 多种解法比较,体会 -> 优化(执行时间和ac)
第三遍:(24小时之后)
- 过了一天再重复做题
- 不同熟悉的解法程度->专项训练
第四遍:(1周后)
- 过了一周:再反复练习相同题目
- 专项训练
第五遍:(面试前一周)
- 面试前一周恢复训练
- 面试前一周复习算法模板与相应分类出现的题目
理解人的记忆规律,高频率高效复习
- 短期记忆: 持续若干天或者一两周的记忆
- 中期记忆: 持续数周或者几个月的记忆
- 长期记忆: 持续数年甚至永世不会消逝的记忆
形成长期记忆的方法其实非常简单,即频繁且有效的重复刺激
德国的心理学家艾宾浩斯告诉我们,人对于知识的遗忘速度遵循 "先快后慢" 的原则。学得的知识在一天后,如不抓紧复习,很快就只剩下原来的 25%。而随着时间的推移,遗忘的速度会减慢,遗忘的数量也就减少。去有效抵抗这种遗忘现象,最好的办法就是进行有规律的复习 (每 5 分钟,30分钟,12小时,1天,2天,4天,7天,15天,1个月,3个月,6个月)
算法题汇总
20 个最常用的、最基础数据结构与算法,都已经总结在 算法题模板分类
10 个必考数据结构模板:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树。
10 个必会算法模板:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法。
不同算法类型
题型汇总
1. 滑动窗口
- 大小为 K 的子数组的最大和
- Best Time to Buy and Sell Stock
- Longest Substring Without Repeating Characters
- Sliding Window Maximum
- 剑指 Offer 57 - II. 和为s的连续正数序列
# Sliding windows code template is most used in substring match or maximum/minimum problems.
# It uses two-pointer as boundary of sliding window to traverse, and use a counter(dict) maintain current state,
# and a count as condition checker, update it when trigger some key changes.
#
# Time: O(n)
# Space: O(k) k = len(set(p))
from collections import Counter
# s - target sequence, p - pattern or restrict sequence
def sliding_window_template_with_examples(s, p):
# initialize the hash map here
# counter is used to record current state, could use defaultdict in some situation, for example, no p restrict
counter = Counter(p)
# two pointers, boundary of sliding window
start, end = 0, 0
# condition checker, update it when trigger some key changes, init value depend on your situation
count = 0
# result, return int(such as max or min) or list(such as all index)
res = 0
# loop the source string from begin to end
while end < len(s):
counter[s[end]] += 1
# update count based on some condition
if counter[s[end]] > 1:
count += 1
end += 1
# count condition here
while count > 0:
'''
update res here if finding minimum
'''
# increase start to make it invalid or valid again
counter[s[start]] -= 1
# update count based on some condition
if counter[s[start]] > 0:
count -= 1
start += 1
'''
update res here if finding maximum
'''
res = max(res, end - start)
return res
# refer to https://leetcode.com/problems/minimum-window-substring/discuss/26808/here-is-a-10-line-template-that-can-solve-most-substring-problems
2. 双指针
双指针通常用在排好序的数组或是链表中寻找对子, 或者是merge 或者是排序,或者去除element,反正一般都是头尾各一个指针,然后根据条件移动。
- Two Sum(# 也可以用map的方式做)
- Two Sum II - Input array is sorted
- Squares of a Sorted Array (很像merge sort里的merge)
- Move Zeroes
- Remove Element
- Remove Duplicates from Sorted Array
- 3Sum Closest
- 4Sum
- Partition List
- Container With Most Water
- Trapping Rain Water
- Sort Colors
- 剑指 Offer 04. 二维数组中的查找
- 剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
# two pointers scenario, famous applications such as binary search, quick sort and sliding window.
'''
Classification:
1. old & new state: old, new = new, cur_result
2. slow & fast runner: slow-> fast->->
3. left & right boundary or index: left-> <-right
4. p1 & p2 from two sequences: p1-> p2->
5. start & end sliding window boundary: start-> end->
'''
# old & new state: old, new = new, cur_result
def old_new_state(self, seq):
# initialize state
old, new = default_val1, default_val2
for element in seq:
'''
process current element with old state
'''
old, new = new, self.process_logic(element, old)
# slow & fast runner: slow-> fast->->
def slow_fast_runner(self, seq):
# initialize slow runner
slow = seq[0] # for index: slow = 0
# fast-runner grows each iteration generally
for fast in range(seq): # for index: range(len(seq))
'''
slow-runner grows with some restrictions
'''
if self.slow_condition(slow):
slow = slow.next # for index: slow += 1
'''
process logic before or after pointers movement
'''
self.process_logic(slow, fast)
# left & right boundary or index: left-> <-right
def left_right_boundary(self, seq):
left, right = 0, len(seq) - 1
while left < right:
'''
left index moves when satisfy the condition
'''
if self.left_condition(left):
left += 1
'''
right index move when satisfy the condition
'''
if self.right_condition(right):
right -= 1
'''
process logic before or after pointers movement
'''
self.process_logic(left, right)
# p1 & p2 from two sequences: p1-> p2->
def pointers_from_two_seq(self, seq1, seq2):
# init pointers
p1, p2 = 0, 0 # or seq1[0], seq2[0]
# or other condition
while p1 < len(seq1) and p2 < len(seq2):
'''
p1 index moves when satisfy the condition
'''
if self.p1_condition(p1):
p1 += 1 # or p1 = next(seq1)
'''
p2 index move when satisfy the condition
'''
if self.p2_condition(p2):
p2 += 1 # or p2 = next(seq2)
'''
pro
