算法导论-初涉

1. 对字典的value做排序,同时输出字典的key

fre_dict = dict()
sorted(fre_dict.items(), key = lambda x: x[1])

sorted(fre_dict.keys(), key=lambda x:(fre_dict[x],x))

2. 统计一个列表里各个元素的出现次数 O(n)

from collections import Counter
Counter(a)

3. 堆。取一个列表前n的数

heapq.nlargest(k, nums)[-1]

插入排序

存储在一个数组里,每看一个新的数,从原数组最后一位开始看,如果大于新数,就往后存一位,直到新数小于等于数组中某个数。最后空出一格,把新数填入。

希尔排序 shell

对n间隔做插入排序,n递减。

增量序列 2^k-1,保证相邻元素互质

选择排序

从后面n个元素中找最小元,并把最小元换到有序部分的最后位置。

堆排序 (对选择排序的改进

把数们都弄成一个堆,然后依次弹出最小值。

快速排序

选择一个主元pivot,左边是小于pivot的,右边。。。然后递归。

如何选pivot?1. 取头中尾三个数的中位数

归并排序(排两个已排序序列

类似分而治之。

冒泡排序

  • 针对问题:

数据的顺序排好之后,冒泡算法仍然会继续进行下一轮的比较,直到arr.length-1次,后面的比较没有意义的。

  • 方案:

设置标志位flag,如果发生了交换flag设置为true;如果没有交换就设置为false。这样当一轮比较结束后如果flag仍为false,即:这一轮没有发生交换,说明数据的顺序已经排好,没有必要继续进行下去。

表排序 table sort

只移动指针,原数组不变。

基数排序

* 桶排序

* 最大、最小

最大子数组问题

矩阵乘法的Strassen算法

Leetcode刷题记录

1. Two Sum


2. Add Two Numbers
3. Longest Substring Without Repeating Characters
4. Median of Two Sorted Arrays
5. Longest Palindromic Substring

这一题dp的想法是自然而然的。但是如何bottom up?秘诀在于第一个point从后往前移动,第二个point从第一个point往后移动。

研究一下Manacher's Algorithm

6. ZigZag Conversion
7. Reverse Integer
8. String to Integer (atoi)
9. Palindrome Number
10. Regular Expression Matching

正则表达式中*和.的匹配。是个递归问题。如果不带*,那么就第一个字符匹配上,第二个字符开始和pattern的第二个字符开始匹配上。如果带*,两种情况,0个*,就是字符和pattern的第二个字符起匹配上,如果不是0个*,就是第一个匹配上,字符第一个开始和pattern匹配上。(特别慢)

DP算法,保存recursive的中间结果,可以加速。

11. Container With Most Water
12. Integer to Roman
13. Roman to Integer
14. Longest Common Prefix
15. 3Sum

用2sum来解决。遍历3Sum的nums list,然后找2sum,使用dict。注意运算的时候去重来提速。


16. 3Sum Closest

值得二刷的题。one pass,然后两边逼近找最接近的和。

17. Letter Combinations of a Phone Number

很简单。最后注意把空值删去即可。
18. 4Sum
19. Remove Nth Node From End of List
20. Valid Parentheses

建立一个栈。如果括号是前括号就append,否则就pop对比。注意stack为空的情况。
21. Merge Two Sorted Lists

非常easy。新建一个链表,按把两列表的头依次插入。直到某个列表空了,再把非空列表直接贴进去。

22. Generate Parentheses

这道题是用backtracking。关键点在于搞清楚backtracking的内在逻辑。

23. Merge k Sorted Lists
24. Swap Nodes in Pairs

比较简单,常规题。注意空列表。
25. Reverse Nodes in k-Group
26. Remove Duplicates from Sorted Array

双指针。比较简单。不能用超过O1的extra memory。一个指针正常往后,遇到不同的,另一个指针上加数字。
27. Remove Element
28. Implement strStr()
29. Divide Two Integers
30. Substring with Concatenation of All Words
31. Next Permutation
32. Longest Valid Parentheses

这题真的是太难太绝望了。先想出了一个n2的dp,发现超时。看到答案里有个n的dp。逻辑还是有点复杂的。大概就是dp[i]代表截止到i的最长长度。

33. Search in Rotated Sorted Array

是个典型的二分法变种。关键是搞清楚二分法的一些细节。

34. Find First and Last Position of Element in Sorted Array

一个二分查找找左右边界的问题。要搞清楚左右边界的更新方式的不同。建议直接记忆。

35. Search Insert Position

比较简单。二分查找。

36. Valid Sudoku
37. Sudoku Solver
38. Count and Say
39. Combination Sum
40. Combination Sum II
41. First Missing Positive
42. Trapping Rain Water

这题自己用brutu force做完的。答案最好再斟酌一下。

43. Multiply Strings

看了别人的提交才做出来。思路不复杂。建立一个list,然后两个数每个位相乘,放进list对应位置,再从后往前扫描,做进位。最后略去leading zeros然后生成最后的str。
44. Wildcard Matching

非常复杂了,是HARD。自己写了DP top down,时间挺长的,最后用了一个小trick,把pattern里的*进行压缩。

45. Jump Game II

这一题我先尝试使用dp bottom-up,结果一个case超时。看了别人的discuss,是greedy,顺序执行,记录当前最大跨度。

对greedy不是很熟悉,今天又学习了一下别人的做法。这道题值得三刷

class Solution:
    def jump(self, nums: List[int]) -> int:
        
        size = len(nums)
        
        # destination is last index
        destination = size - 1
        
        # record of current coverage, record of last jump index
        cur_coverage, last_jump_index = 0, 0
        
        # counter for jump
        times_of_jump = 0
        
         # Quick response if start index == destination index == 0
        if size == 1:
            return 0
        
        # Greedy strategy: extend coverage as long as possible with lazy jump
        for i in range(size):
            
            # extend current coverage as further as possible
            cur_coverage = max( cur_coverage, i + nums[i] )
            
            # print(i, cur_coverage)

            # forced to jump (by lazy jump) to extend coverage  
            if i == last_jump_index:
            
                # update last jump index
                last_jump_index = cur_coverage
                
                # update counter of jump by +1
                times_of_jump += 1
                
                # check if reached destination already
                if cur_coverage >= destination:
                        return times_of_jump
                
        return times_of_jump

46. Permutations

backtracking. 遍历元素作为第一个元素,剩下元素做permute。
47. Permutations II

类似上一题,但是在backtracking的时候,对于重复元素,只捞出来一个往前放。
48. Rotate Image

90度顺时针转动matrix等同于把matrix翻两次。

49. Group Anagrams

50. Pow(x, n)

计算x^n,用类似二分的方式做recursion,计算x^2。这样效率更高。

51. N-Queens

熟悉了之后就不是很难了。注意皇后的规则。是任一斜线上不能有重复的。

52. N-Queens II
53. Maximum Subarray

一道经典的分治问题。但是自己对分治不太熟悉。需要再看视频熟悉一下

54. Spiral Matrix
55. Jump Game

这一题的solution写的特别好。解答了我对backtracking DP top-down和DP bottom-up的联系。

不过用greedy会更好。建议这题常常温故知新。

56. Merge Intervals
57. Insert Interval
58. Length of Last Word
59. Spiral Matrix II
60. Permutation Sequence
61. Rotate List

比较简单。但是要考虑边界情况:list是空或者长度为1,k=0和k=cnt
62. Unique Paths
63. Unique Paths II
64. Minimum Path Sum
65. Valid Number

一道没有什么意义的题。考正则表达式。

66. Plus One

细节问题。先往列表前面放一个0,然后做进位,最后把第一个零(如果还在的话)删去。
67. Add Binary

比较简单,从最后一位一次相加,记录carry
68. Text Justification
69. Sqrt(x)

先写了一个从1开始查找,速度较慢。看了discuss发现二分查找是logn复杂度,会更快。
70. Climbing Stairs
71. Simplify Path
72. Edit Distance

一道dp,关键在于想清楚dp推导式。还有就是极端情况,其中一个是空字符串。

73. Set Matrix Zeroes
74. Search a 2D Matrix
75. Sort Colors

这个题one pass还是挺难的。最后抄了答案。

76. Minimum Window Substring
77. Combinations
78. Subsets

遍历每个元素,加入原result中。
79. Word Search

标准的backtracking。不过我自己在做的时候粗心了,下一个搜索从对角线开始了。
80. Remove Duplicates from Sorted Array II
81. Search in Rotated Sorted Array II

也是二分查找。抄了答案。建议二刷。

82. Remove Duplicates from Sorted List II

注意边界。写好之后,用不同例子模拟几次。
83. Remove Duplicates from Sorted List

84. Largest Rectangle in Histogram

太难了。待研究。

https://leetcode-cn.com/problems/largest-rectangle-in-histogram/solution/zhu-zhuang-tu-zhong-zui-da-de-ju-xing-by-leetcode/

答案很详细。建议多次温习。

85. Maximal Rectangle

是上一题的拓展版。

86. Partition List
87. Scramble String

是一道dp解法。dp的推导式不是很明显。存储memo的时候,存储的不是位置,而是字符串。

还有一点

88. Merge Sorted Array

89. Gray Code

这题是用backtracking方法,关键在于backtracking的逻辑很巧妙。

90. Subsets II
91. Decode Ways
92. Reverse Linked List II
93. Restore IP Addresses
94. Binary Tree Inorder Traversal
95. Unique Binary Search Trees II

也是标准的dfs,用上memo后速度很快。

96. Unique Binary Search Trees

这题也是一道标准的backtracking和dp算法的问题。
97. Interleaving String
98. Validate Binary Search Tree
99. Recover Binary Search Tree

比较简单,先把序列拉出来,然后找到不对的地方改正。
100. Same Tree

recursive method. check whether the node val, the left tree and the right tree are the same.

108. Convert Sorted Array to Binary Search Tree

这题比较简单,用递归,每次中间那个作为root,左边右边生成子树。

109. Convert Sorted List to Binary Search Tree

solution 3 is amazing. 可以再学习一下。

121. Best Time to Buy and Sell Stock

这题one pass就可以解决。one pass的时候,记录当前最小值和当前最大差值。

123. Best Time to Buy and Sell Stock III

一道名副其实的hard,值得二刷。

124. Binary Tree Maximum Path Sum

还可以。dfs,考虑清楚max的计算方法。注意空节点的话max用float('-inf')取代。不要用0,要考虑全树都是负数的情况。

128. Longest Consecutive Sequence

这题抄了答案。自己想出了nlogn的方法,要求是n,运用set即可。

144. Binary Tree Preorder Traversal

前中后序遍历如何用循环解决。

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        if root is None:
            return []
        output = []
        stack = [(root, False)]
        while stack:
            node, visited = stack.pop()
            if node:
                if visited:
                    output.append(node.val)
                else:
                    stack.append((node.right, False))
                    stack.append((node.left, False))
                    stack.append((node, True))
        return output

155. Min Stack

这题比较简单。但是看了别人的答案后,大受启发。

定义的时候:self.stack = [(None, float('inf'))],将当前最小值跟着当前值记录起来。

167. Two Sum II - Input array is sorted

双指针,一头一尾,如果加和等于target,返回结果即可,如果大于,右指针向左移,如果小于,左指针向右移。

179. Largest Number    

这题挺简单的,关键是搞清楚排序逻辑。答案写得挺好的。用了我不会的东西。待研究。

class LargerNumKey(str):
    def __lt__(x, y):
        return x+y > y+x
        
class Solution:
    def largestNumber(self, nums):
        largest_num = ''.join(sorted(map(str, nums), key=LargerNumKey))
        return '0' if largest_num[0] == '0' else largest_num

188. Best Time to Buy and Sell Stock IV

参考了123的答案,对其做了扩展。但是会出现memory超。

208. Implement Trie (Prefix Tree)

212. Word Search II

非常好的题。结合了trie。

215. Kth Largest Element in an Array

最大堆的问题。注意到有堆相关的包可以直接解决。heapq.nlargest(k, nums)[-1]

224. Basic Calculator

典型的stack

227. Basic Calculator II

抄了答案啊。比前一题更难一些。

260. Single Number III

是个位运算的题目。抄了答案。注意一个trick:a^(-a)得到的是最右边的1位。先遍历循环得到目标两数的并操作。然后通过trick得到最右边位。然后再遍历,当最右边位和遍历数的并不为零时,求这些数的异或。这个异或就是其中一个要找的数。

313. Super Ugly Number

最大堆的应用。抄了答案。

373. Find K Pairs with Smallest Sums

也是堆,使用堆的想法很巧妙。抄了答案,建议二刷。

1311. Get Watched Videos by Your Friends

一道基本的bfs。但是自己对于一些逻辑术语掌握不足。比如[i for j in bfs for i in friends[j] if i not in visited]多层for循环;visited|=bfs,set集取并集;sorted(fre_dict.keys(), key=lambda x:(fre_dict[x],x)),对字典里的值排序;collections.Counter([j for i in bfs for j in watchedVideos[i]]),Counter的应用。

1312. Minimum Insertion Steps to Make a String Palindrome

这道dp挺难的。关键在于找出dp的逻辑关系。

1325. Delete Leaves With a Given Value

这是一道非常好的dfs,先做左右两颗子树,再做自己。

1326. Minimum Number of Taps to Open to Water a Garden

待做。这题与jump game ii是一个意思,都是greedy。greedy类型的题还需要再熟悉一下。

1334. Find the City With the Smallest Number of Neighbors at a Threshold Distance

这题是典型的图上求距离。请熟悉floyd算法。

1335. Minimum Difficulty of a Job Schedule

这题hard我第一次做就tle了。后来经过优化。在dp的时候,算max可以做缓存,而不是每一次max重新计算。

1352. Product of the Last K Numbers

用的是prefix product。是从来没有看见过的算法。涨姿势了。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值