Skip to content

cpeixin/algorithm010

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

切题四件套

  • Clarification
  • Possible solutions
  • compare (time/space)
  • optimal(加强)
  • Coding(多写)
  • Test cases

五毒练习法

  • 刷题第一遍 5 分钟:读题 + 思考(最多不要超过 15 分钟),直接看解决:注意!多解法,比较解法优劣(如何 15 分钟后依旧没思路的情况下) 背诵、默写好的解法(这一步很重要)
  • 刷题第二遍 将每种解法写一遍(闭卷),反复 Debug,直到代码在 LeetCode 上执行通过,对多种解法之间的优劣进行体会、优化.总结及反思自己写的时候遇到的一些问题
  • 刷题第三遍 时隔一天后,再重复做题,对于不同解法的熟练程度进行专项练习
  • 刷题第四遍:时隔一周后,反复回来练习相同的题目
  • 刷题第五遍:面试前一周进行恢复性训练

刷题核心思想和误区

  • 思想 重复刷题至少刷 5 遍
  • 优化方法:空间换时间、升维(二维)
  • 误区:做题只做一遍

时间复杂度

20180928135003419.png

数据结构时间复杂度

1592554431322-a01740ce-a5e4-4496-b2a0-a7130a6f607c.jpeg

递归时间复杂度

v2-6b854efd30ba33dbd1d758605fbf7c44_1440w.jpg

题型总结

团灭买卖股票问题(python)实现
团灭二分查找

刷题列表

题目 首刷时间 最近刷时间 毒*n 复杂度 代码片段
前 K 个高频元素 2020-06-16 2020-07-07 ✅✅ heapq.heappush(heap, (-dict[key], key))
数对和 2020-06-23 2020-07-07 ✅✅ if dict.get(target-num, 0) == 0
dict[num]+=1
两两交换链表中的节点 2020-06-07 2020-07-07 ✅✅ first_node.next = self.swapPair(second_node.next)
两数之和 2020-06-06 2020-07-06 ✅✅✅ dict
旋转数组 2020-06-12 2020-07-06 ✅✅✅ k = k%len(nums)
三段翻转
杨辉三角 II 2020-06-06 2020-07-06 ✅✅ 貌似正解是利用动态规划来实现
杨辉三角 2020-06-06 2020-07-06 ✅✅  递归递归
res.append([1]+[res[-1][i-1]+res[-1][i] for i in range(1, numRows-1)]+[1])
反转字符串 2020-02-07 2020-07-06 ✅✅✅ 递归,双指针。要求空间复杂度为O(1),则只能用双指针实现
验证回文串 2020-06-20 2020-07-07 ✅✅  "".join(char.lower() for char in s if char.isalnum())
二叉树的前序遍历 2020-06-06 2020-07-07 ✅✅ 
二叉树的中序遍历 2020-06-06 2020-07-07
二叉树的后序遍历 2020-06-06 2020-07-06 ✅✅  涉及到打印,所以引入辅助函数helper(root, res)
N叉树的后序遍历 2020-06-15 2020-07-07 ✅✅✅ 时间复杂度:O(n)
空间复杂度:O(n)
for child in root.children:
     self.helper(root, res)
N叉树的前序遍历 2020-06-15 2020-07-11 ✅✅✅✅ 时间复杂度:O(n)
空间复杂度:O(n)
class Solution:
    def preorder(self, root: 'Node') -> List[int]:
        if not root: return []
        res, queue = [], [root]
        while queue:
            node = queue.pop()
            res.append(node.val)
            for child in node.children[::-1]:
                queue.append(child)
        return res
N叉树的最大深度 2020-06-25 2020-07-11 ✅✅  时间复杂度:O(n)
空间复杂度:O(n)
if not root: return 0
if not root.children: return 1
return max(self.func(node) for node in root.children) + 1
从中序与后序遍历序列构造二叉树
2020-06-10 2020-07-10 ✅✅✅ 时间复杂度:O(n^2), index() 操作复杂度为O(n),遍历二叉树是O(n) 的。
空间复杂度:O(n),要存储整棵树
if not inorder or not postorder: return None
root = TreeNode(postorder[-1])
root_index=inorder.index(postorder[-1])
root.left = self.fun(inorder[:root_index], postorder[:root_index])
root.right = self.fun(inorder[root_index+1:], postorder[root_index:-1])
从前序与中序遍历序列构造二叉树 2020-06-10 2020-07-10 ✅✅✅ 时间复杂度:O(n^2), index() 操作复杂度为O(n),遍历二叉树是O(n) 的。
空间复杂度:O(n),要存储整棵树
root.left = self.fun(preorder[1:root_index+1], inorder[:root_index])
root.right = self.fun(preorder[root_index+1], inorder[root_index+1:])
最大二叉树 2020-06-15 2020-07-07 ✅✅✅ python数组边界[ :max_num] [max_num+1: ]
左叶子之和 2020-06-15 2020-07-07 ✅✅✅ if root.left and not root.left.left and not root.left.right:
return root.left.val+self.func(root.right)
翻转二叉树 2020-06-20 2020-07-11 ✅✅✅✅ 时间复杂度:O(n) ,每个树节点只访问一次
空间复杂度:O(n),调用栈n次
if not root: return None
root.left, root.right = root.right, root.left
self.func(root.left)
self.func(root.right)
return root
对称二叉树 2020-06-11 2020-07-11 ✅✅✅✅ 时间复杂度:O(n) ,每个树节点只访问一次
空间复杂度:O(n),调用栈n次
if not root: return True
def recur(left, right):
      if not left and not right: return True
      if not left or not right: return False
      if left.val != right.val: return False
      return self.recur(left.left, right.right) and self.recur(left.right, right.left)
return (root.left, root.right)
路径总和 2020-06-07 2020-07-07 ✅✅✅ if not root: return False
sum -= root.val
if not root.left and not root.right: return sum == 0
return self.haspath(root.left,sum) or self.haspath(root.right, sum)
二叉树的最大深度 2020-06-07 2020-07-10 ✅✅✅✅✅ 时间复杂度:O(n)
空间复杂度:最糟糕的情况下是二叉树不平衡,退化成一个链表,则调用栈的存储为O(n),最好的情况下,二叉树是平衡二叉树,树的高度是log(N)的,所以此时空复为O(logN)
二叉树的最小深度 2020-06-16 2020-07-11 ✅✅✅✅✅✅✅ 时间复杂度:O(n)
空间复杂度:O(n)
if  not root:return 0
if not root.left or not root.right:
return self.func(root.left)+self.func(root.right)+1
return min(self.func(root.left), self.func(root.right))+1
从上到下打印二叉树 II 2020-06-07 2020-07-10 ✅✅✅ 时间复杂度:O(n)
空间复杂度:O(n)
BFS
res, queue = [], [root]
while queue:
tmp = []
for _ in range(len(queue)):
node = queue.pop(0)
tmp.append(node.val)
if node.left: queue.append(node.left)
if node.right:queue.append(node.right)
注意:pop() 默认弹出最后一个元素,pop(0)弹出第一个
二叉树的序列化与反序列化 2020-06-23 2020-07-11 ✅✅✅✅ 时间复杂度:O(n) ,每个树节点只访问一次
空间复杂度:O(n),调用栈n次
def deserialize(self, data):
           nodes = iter(data.split(','))
def recur():
node = next(nodes)
if node == '#':return None
else:
root = TreeNode(int(node))
root.left = recur()
root.right = recur()
return root
return recur()
交换和 2020-07-06 2020-07-06
分发饼干 2020-07-02 2020-07-02
买卖股票的最佳时机 2020-07-03 2020-07-04 ✅✅
验证二叉搜索树 2020-06-26  2020-07-03 ✅✅✅✅✅
二叉树的最近公共祖先 2020-06-26  2020-07-03 ✅✅✅✅✅✅✅ 时间:O(n)
空间:O(n)
if not root or root==p or root == q: return root
left = self.func(root.left,p,q)
right = self.func(root.right,p,q)
if not left:return right
if not right: return left 
二叉搜索树的最近公共祖先 2020-06-20 2020-07-11 ✅✅✅✅ 时间:O(n)
空间:O(n)
if p.val > root.val and q.val > root.val
elif p.val < root.val and q.val < root.val
return root
买卖股票的最佳时机 II 2020-07-03 2020-07-03 ✅✅
买卖股票的最佳时机 III 2020-07-03 2020-07-03 ✅✅
最佳买卖股票时机含冷冻期 2020-07-04 2020-07-10 ✅✅ 时间复杂度:prices数组长度为n,所以为O(n)时间复杂度
空间复杂度:如果使用二维数组的话,则为O(n),但是存在优化的空间,就是使用变量代替二维数组,可以优化到O(1)
dp = [[None, None] for _ in range(n)]
dp[0][0] = 0
dp[0][1] = -price[0]
dp[1][0] = max()
dp[1][1] = max()
for i in range(2, n):
...............
买卖股票的最佳时机含手续费 2020-07-04 2020-07-04
买卖股票的最佳时机 IV 2020-07-04 2020-07-04
x 的平方根 2020-07-05 2020-07-05
有效的完全平方数 2020-07-05 2020-07-05 ✅✅
搜索旋转排序数组 2020-07-06 2020-07-06
删除排序数组中的重复项 2020-06-10 2020-07-07 ✅✅✅ if nums[slow] != nums[fast]:
slow+=1
nums[slow] = nums[fast]
合并两个有序数组 2020-06-13 2020-07-07 ✅✅✅ while num1_index>0 and num2_index>0
num1[:nums2_index+1] = nums2[:nums2_index+1]
合并两个有序链表 2020-03-02 2020-07-08 ✅✅✅✅ if not l1: return l2
if not l2: return l1
部分排序 2020-07-06 2020-07-06
最小栈 2020-06-06 2020-07-07 ✅✅✅ if not min_stack or self.min_stack[1] >= x:
self.min_stack.apped(x)
柱状图中最大的矩形 2020-06-08 2020-07-08 ✅✅✅✅ heights.append(0)
stack = [-1]
are = 0
for index in range(len(heights)):
    while heights[index] < heights[stack[-1]]
丑数 II 2020-06-22 2020-07-08 ✅✅✅ 堆实现和动态规划实现
环形链表 2020-02-04 2020-07-09 ✅✅✅✅ 两种情况:存在环和不存在环
不存在环:快指针遍历数组长度n结束,则O(N)
存在环:快指针遍历数组长度n进入环,快慢指针差速长度K,则O(N+K),K为常数,则O(N)
空间复杂度:只使用了快慢指针,所以O(1)
if not head or not head.next:return False
slow, fast = head, head.next
while slow!=fast:
if not fast or not fast.next:
..........
环形链表 II 2020-06-07 2020-07-10 ✅✅✅ 时间:O(n)
空间:O(n)
if not head or not head.next:return 
slow, fast = head, head
        while True: 
            if not fast or not fast.next: return None
            slow, fast = slow.next, fast.next.next
            if slow == fast: break
fast = head
while slow != fast:
.....................
有效的括号 2020-02-04 2020-07-10 ✅✅✅✅ 时间复杂度:O(n)
空间复杂度:O(n)
子集 2020-06-25 2020-07-11 ✅✅ 时间复杂度:O(n2^n)
空间复杂度:O(n
2^n)
def backtrack(index, tmp):
      res.append(tmp)
      for i in range(index, n):
          backtrack(i+1, tmp+[nums[i]])
backtrack(0, [])
return res
子集 II 2020-06-25 2020-07-11 ✅✅ 时间复杂度:O(n2^n)
空间复杂度:O(n
2^n)

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Python 100.0%