更新中…

文章目录

  • 一、Sort
    • 1. Bubble Sort
    • 2. Quick Sort
    • 3. Heap Sort
  • 二、Tree
    • 1. Traversal
    • 2. 前序中序 --> 构建树/求后序
    • 3. 公共祖先 lowest common ancestor (LCA)
  • 三、Graph
    • 1. 搜索路径问题 & 遍历
  • 四、LinkList
    • 1. 反转链表
    • 2. Entry of Loop
  • 五、Dynamic Programming
    • 1. 凑硬币问题
    • 2. 硬币组合数量问题
    • 3. 编辑距离 / 最长公共字串 / 最长公共子序列
    • 4.
  • 六、String
    • 1. Permutation
    • 2. Combinations
    • 3. Josephus
  • 七、面试题
    • 1. leetcode470 -- rand7生成rand10
    • 2. leecode273 -- 非负整数转换为其对应的英文表示
    • 3. leetcode207 -- 拓扑排序检测有向无环图
    • 4. 最小删减构造回文串(最长公共子序列思想)(dp问题)
    • 5. leetcode300 -- 最长上升子序列(dp问题)
    • 6. 剑指Offer 14 -- 剪绳子最大乘积(dp问题)
    • 7. 最多有多少不重叠的非空区间,使得每个区间内数字的 xor等于0(dp问题)
    • 8. 给定一个正数n,求裂开的方法数(dp问题)
    • 9. 消消乐问题(dp问题)
    • 10. 企鹅合体问题(dp问题)
    • 11. leetcode845 -- 最长山脉问题(dp问题)
    • 12. 分隔数组以得到最大和 (dp问题)
    • 13. leetcode221 -- 最大正方形(dp问题)
    • 14. 最后剩一块石头重量(dp问题)
    • 15. 最长等差序列(dp问题)
    • 16. leetcoe115 -- 不同的子序列(dp问题)
    • 17. leetcoe279 -- 完全平方数(dp问题)
    • 21. 数据流求中位数(大根堆问题)
    • 22. 判断矩阵中是否存在指定路径(递归)
    • 23. sqrt
    • 24. 约瑟夫环
    • 25. 2sum 3sum
    • 26. leetcode40 -- 和为target的组合(递归)
    • 27. leetcode372 -- 超级次方 (power的复杂度是log(n))
    • 28. leetcode668 -- 给定高度m 、宽度n 的一张 m * n的乘法表,以及正整数k,你需要返回表中第k 小的数字(二分查找,逆向思维)

一、Sort

1. Bubble Sort

时间复杂度O(n^2)

def bubble_sort(arr):length = len(arr)if length < 2:return arrfor i in range(length):for j in range(i, length):if arr[j] < arr[i]:arr[j], arr[i] = arr[i], arr[j]return arr

2. Quick Sort

时间复杂度O(nlogn), 最差O(n^2)(如何避免最差?最差是因为每次递归没能平均二分,那么需要选定合适的pivot,使得每次递归尽量二分,可以采取random方式)
空间复杂度O(nlogn)

quick_sort_lam = lambda array: array if len(array) <= 1 else \quick_sort_lam([item for item in array[1:] if item <= array[0]]) \+ [array[0]] + \quick_sort_lam([item for item in array[1:] if item > array[0]])def quick_sort(array, left, right):if left >= right:returnlow = lefthigh = rightkey = array[low]while left < right:while left < right and array[right] >= key:right -= 1array[left], array[right] = array[right], array[left]while left < right and array[left] <= key:left += 1array[right], array[left] = array[left], array[right]quick_sort(array, low, left - 1)quick_sort(array, left + 1, high)

3. Heap Sort

堆调整时间复杂度O(logn)
堆排序时间复杂度O(nlogn)
应用1: 大数据区topk
应用2: 数据流求中位数

"""
堆排序算法的步骤:
1. 把无序数组构建成二叉堆。
2. 循环删除堆顶元素,移到集合尾部,调节堆产生新的堆顶。大根堆
"""
def downAdjustBig(array, parentIndex, length):temp = array[parentIndex]childIndex = 2 * parentIndex + 1while (childIndex < length):if childIndex + 1 < length and array[childIndex + 1] > array[childIndex]:childIndex += 1if temp >= array[childIndex]:breakarray[parentIndex] = array[childIndex]parentIndex = childIndexchildIndex = 2 * childIndex + 1array[parentIndex] = tempdef heapSort(array):# 1.构建二叉堆for i in range(int(len(array) / 2))[::-1]:downAdjustBig(array, i, len(array))print(array)# 2.循环删除堆顶元素,移到集合尾部,调节堆产生新的堆顶for i in range(len(array))[::-1]:array[i], array[0] = array[0], array[i]downAdjustBig(array, 0, i)print(array)

二、Tree

1. Traversal

广度 & 深度

# 广度优先遍历算法
def tree_level_traversal(root):if root is None:returnmy_queue = collections.deque()node = rootmy_queue.append(node)while my_queue:node = my_queue.popleft()print(node.val)if node.left:my_queue.append(node.left)if node.right:my_queue.append(node.right)# 深度优先遍历算法
def tree_dfs_traversal(tree_node):if tree_node:print(tree_node.val)if tree_node.left:tree_dfs_traversal(tree_node.left)if tree_node.right:tree_dfs_traversal(tree_node.right)

二叉树 的 三种遍历方式(前中后) 的 非递归解法


"""
当前结点curr不为None时,每一次循环将当前结点curr入栈;
当前结点curr为None时,则出栈一个结点,且打印出栈结点的value值。
整个循环在stack和curr皆为None的时候结束。
"""def inorderTraversal(root):stack = []res = []curr = rootwhile stack or curr:if curr:stack.append(curr)curr = curr.leftelse:curr = stack.pop()res.append(curr.val)curr = curr.rightreturn res"""
由于前序遍历的顺序是中左右,所以我们每次先打印当前结点curr,并将右子结点push到栈中,然后将左子结点设为当前结点。
入栈和出栈条件(当前结点curr不为None时,每一次循环将当前结点curr入栈;
当前结点curr为None时,则出栈一个结点)以及循环结束条件
(整个循环在stack和curr皆为None的时候结束)与中序遍历一模一样。
"""def preorderTraversal(root):  ## 前序遍历stack = []res = []curr = rootwhile stack or curr:if curr:res.append(curr.val)stack.append(curr.right)curr = curr.leftelse:curr = stack.pop()return res"""
代码的主体部分基本就是.right和.left交换了顺序,
且后序遍历在最后输出的时候进行了反向(因为要从 中右左 变为 左右中 )
"""def postorderTraversal(root):  ## 后序遍历stack = []res = []curr = rootwhile stack or curr:if curr:res.append(curr.val)stack.append(curr.left)curr = curr.rightelse:curr = stack.pop()return res[::-1]

2. 前序中序 --> 构建树/求后序

# 前序 中序 构建树
def getTreeFromPreMid(pre, mid):if len(pre) == 0:return Noneif len(pre) == 1:return TreeNode(pre[0])root = TreeNode(pre[0])root_index = mid.index(pre[0])root.left = getTreeFromPreMid(pre[1:root_index + 1], mid[:root_index])root.right = getTreeFromPreMid(pre[root_index + 1:], mid[root_index + 1:])return root# 前序 中序 构建后序
def getAfterFromPreMid(pre, mid, res):if len(pre) == 0:returnif len(pre) == 1:res.append(pre[0])returnroot = pre[0]root_index = mid.index(root)getAfterFromPreMid(pre[1:root_index + 1], mid[:root_index], res)getAfterFromPreMid(pre[root_index + 1:], mid[root_index + 1:], res)res.append(root)return res

3. 公共祖先 lowest common ancestor (LCA)

lowest common ancestor (LCA)

def lca(root, p, q):if p is None or q is None:return root# dfs查找根节点到两个节点的路径def dfs(node, visited, res):if node is None:returnpath = visited + [node.val]if node == p or node == q:res.append(path)dfs(node.left, path, res)dfs(node.right, path, res)res = []visited = []dfs(root, visited, res)# 得到两条路径 --> res[0] res[1], 找最近的公共父节点i = 0for i in range(min(len(res[0]), len(res[1]))):if res[0][i] == res[1][i]:i += 1else:return res[0][i-1]return res[0][i-1]

BST的LCA


"""
Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST._______6______/              \___2__          ___8__/      \        /      \0      _4       7       9/  \3   5
For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition."""
"""
注意这里是一个二叉搜索树,根结点的右子树上所有的点的值都比根结点大,左子树上所有点的值都比根结点的值小
因此分为四种情况,
1、如果两个节点一个值比根节点大,一个比根节点小,那么二者的公共节点肯定是根结点,
2、如果两个节点中有一个与根结点的值同样大,那么二者的公共节点同样是根结点
3、如果两个节点的值都比根结点小,那么二者的公共节点出现在根结点的左子树中,递归查询
4、如果两个节点的值都比根结点大,那么二者的公共节点出现在根结点的右子树中,递归查询
"""def lowestCommonAncestor_BST(root, p, q):""":type root: TreeNode:type p: TreeNode:type q: TreeNode:rtype: TreeNode"""if (p.val - root.val) * (q.val - root.val) <= 0:return rootif p.val < root.val and q.val < root.val:return lowestCommonAncestor_BST(root.left, p, q)if p.val > root.val and q.val > root.val:return lowestCommonAncestor_BST(root.right, p, q)

三、Graph

1. 搜索路径问题 & 遍历

给定 起止节点 求搜索路径问题 & Graph的遍历

# -*- coding:UTF-8 -*-def find_all_paths_dfs(graph, start, end, path=[]):"""返回所有路径DFS:param graph::param start::param end::param path::return:"""path = path + [start]if start == end:return [path]if start not in graph:return []paths = []for node in graph[start]:if node not in path:newpaths = find_all_paths_dfs(graph, node, end, path)for newpath in newpaths:paths.append(newpath)return pathsdef find_all_paths_bfs(graph, start, end):"""返回所有路径BFS:param graph::param start::param end::return:"""paths = []todo = [[start, [start]]]while 0 < len(todo):(node, path) = todo.pop(0)for next_node in graph[node]:if next_node in path:continueelif next_node == end:paths.append(path + [next_node])else:todo.append([next_node, path + [next_node]])return pathsdef recursive_dfs(graph, start, path=[]):"""dfs遍历 递归形式:param graph::param start::param path::return:"""path = path + [start]for node in graph[start]:if not node in path:path = recursive_dfs(graph, node, path)return pathdef iterative_dfs(graph, start, path=[]):'''dfs遍历 非递归形式:param graph::param start::param path::return:'''q = [start]while q:v = q.pop(0)if v not in path:path = path + [v]q = graph[v] + qreturn pathdef iterative_bfs(graph, start, path=[]):'''bfs遍历 非递归形式:param graph::param start::param path::return:'''q = [start]while q:v = q.pop(0)if not v in path:path = path + [v]q = q + graph[v]return pathif __name__ == '__main__':'''+---- A|   /   \|  B--D--C|   \ | /+---- E'''graph = {'A': ['B', 'C'],'B': ['D', 'E'],'C': ['D', 'E'],'D': ['E'],'E': ['A']}print('recursive dfs: ', recursive_dfs(graph, 'A'))print('iterative dfs: ', iterative_dfs(graph, 'A'))print('iterative bfs: ', iterative_bfs(graph, 'A'))print("##" * 20)print('find_all_paths: ', find_all_paths_dfs(graph, 'A', 'E'))print("##" * 20)for path in find_all_paths_bfs(graph, 'A', 'E'):print(path)

四、LinkList


1. 反转链表

class ListNode(object):def __init__(self, x):self.val = xself.next = None
class Solution(object):def reverseList(self, head):""":type head: ListNode:rtype: ListNode"""if not head:return Nonep = headq = head.nextwhile q:head.next = q.nextq.next = pp = qq = head.nextreturn p
if __name__ == '__main__':head = ListNode(0)node1 = ListNode(1)node2 = ListNode(2)node3 = ListNode(3)node4 = ListNode(4)node5 = ListNode(5)node6 = ListNode(6)head.next = node1node1.next = node2node2.next = node3node3.next = node4node4.next = node5node5.next = node6p = Solution().reverseList(head)while p:print(p.val)p = p.next

2. Entry of Loop

    """第一步,找环中相汇点。分别用p1,p2指向链表头部,p1每次走一步,p2每次走二步,直到p1==p2找到在环中的相汇点。第二步,找环的入口。接上步,当p1==p2时,p2所经过节点数为2x,p1所经过节点数为x,设环中有n个节点,p2比p1多走一圈有2x=n+x; n=x;可以看出p1实际走了一个环的步数,再让p2指向链表头部,p1位置不变,p1,p2每次走一步直到p1==p2; 此时p1指向环的入口。"""def EntryNodeOfLoop(self, pHead):# write code hereif pHead is None:return NonepLeft = pHeadpRight = pHeadcircle_cnt = 0while pRight and pRight.next:pLeft = pLeft.nextpRight = pRight.next.nextcircle_cnt += 1if pLeft.val == pRight.val:pRight = pHeadleft_cnt = 0while pLeft != pRight:pLeft = pLeft.nextpRight = pRight.nextleft_cnt += 1if pLeft == pRight:return pLeft, circle_cnt, left_cntreturn None

五、Dynamic Programming


动态规划

  • 自底向上
    就是已经知道了所有递归边界,把所有可能的状态都算出来。
    从初始已知的状态出发,向外拓展,最后到达目标状态。
  • 自顶向下(“记忆化搜索”)
    从最终状态开始,找到可以到达当前状态的状态,如果该状态还没处理,就先处理该状态。
    自顶向下通常使用递归实现
  • 总结
    自顶向下,自底向上,只是动态规划实现的套路而已。复杂度并没有多大的变化。
    事实上大多时候用自顶向下复杂度会更低,因为可以过滤掉更多无用的状态;
    不过自底向上可以避免爆栈问题,而且实现往往实现更为简单。

1. 凑硬币问题

def coins_min_combine(arr, target):if target <= 0 or target > 1024:raise ValueErrordp = [0 for i in range(target + 1)]for i in range(1, target + 1):c = sys.maxsizefor coin in arr:if i - coin >= 0:c = min(c, dp[i - coin] + 1)dp[i] = creturn dp[-1]print(coins_min_combine([1, 5, 11], 15))

2. 硬币组合数量问题

def coin_ways(arr, target):"""给定一个正数数组arr,arr[i]表示第i种货币的面值,可以使用任意张。给定一个正 target,返回组成aim的方法数有多少种?动态规划优化状态依赖的技巧:return:"""if len(arr) < 1 or target < 0:return 0return process(arr, 0, target)def process(arr, index, target):res = 0if index == len(arr):res = 1 if target == 0 else 0else:i = 0while arr[index] * i <= target:res += process(arr, index + 1, target - arr[index] * i)i += 1return resdef coin_ways_dp_compress(arr, target):"""给定一个正数数组arr,arr[i]表示第i种货币的面值,可以使用任意张。给定一个正 target,返回组成aim的方法数有多少种?动态规划优化状态依赖的技巧:return:"""if len(arr) < 1 or target < 0:return 0dp = [0 for i in range(target + 1)]j = 0while arr[0] * j <= target:dp[arr[0] * j] = 1j += 1for i in range(1, len(arr)):for j in range(1, target + 1):dp[j] += dp[j - arr[i]] if j - arr[i] >= 0 else 0print(dp)return dp[target]

3. 编辑距离 / 最长公共字串 / 最长公共子序列

# 编辑距离
def levenshtein_distance_dp(input_x, input_y):xlen = len(input_x) + 1ylen = len(input_y) + 1# 此处需要多开辟一个元素存储最后一轮的计算结果dp = [[0 for i in range(xlen)] for j in range(ylen)]for i in range(xlen):dp[i][0] = ifor j in range(ylen):dp[0][j] = jfor i in range(1, xlen):for j in range(1, ylen):if input_x[i - 1] == input_y[j - 1]:dp[i][j] = dp[i - 1][j - 1]else:dp[i][j] = 1 + min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1])return dp[xlen - 1][ylen - 1]# 最长公共子串
def longest_common_substr_dp(str1, str2):xlen = len(str1) + 1ylen = len(str2) + 1record = [[0 for i in range(ylen)] for j in range(xlen)]maxNum = 0  # 最长匹配长度p = 0  # 匹配的起始位for i in range(1, xlen):for j in range(1, ylen):if str1[i - 1] == str2[j - 1]:# 相同则累加record[i][j] = record[i - 1][j - 1] + 1if record[i][j] > maxNum:# 获取最大匹配长度maxNum = record[i][j]# 记录最大匹配长度的终止位置p = ifor i in record:print(i)return str1[p - maxNum:p], maxNum# 最长公共子序列
def longest_common_sequence(input_x, input_y):lcsequence_mat, flag = longest_common_sequence_dp(input_x, input_y)i = len(input_x)j = len(input_y)lcs = []get_lcs(input_x, input_y, i, j, flag, lcs)print((lcsequence_mat[-1][-1], lcs))def longest_common_sequence_dp(input_x, input_y):xlen = len(input_x) + 1ylen = len(input_y) + 1dp = [([0] * ylen) for i in range(xlen)]flag = [([0] * ylen) for i in range(xlen)]for i in range(1, xlen):for j in range(1, ylen):if input_x[i - 1] == input_y[j - 1]:  # 不在边界上,相等就加一dp[i][j] = dp[i - 1][j - 1] + 1flag[i][j] = 0elif dp[i - 1][j] > dp[i][j - 1]:  # 不相等dp[i][j] = dp[i - 1][j]flag[i][j] = 1else:dp[i][j] = dp[i][j - 1]flag[i][j] = -1for dp_line in dp:print(dp_line)return dp, flagdef get_lcs(input_x, input_y, i, j, flag, lcs):if (i == 0 or j == 0):returnif flag[i][j] == 0:get_lcs(input_x, input_y, i - 1, j - 1, flag, lcs)lcs.append(input_x[i - 1])elif (flag[i][j] == 1):get_lcs(input_x, input_y, i - 1, j, flag, lcs)else:get_lcs(input_x, input_y, i, j - 1, flag, lcs)return lcs

4.

在这里插入代码片

六、String


1. Permutation

def perm_str(s=''):if len(s) <= 1:return [s]str_list = []for i in range(len(s)):for j in perm_str(s[0:i] + s[i + 1:]):str_list.append(s[i] + j)return str_list

2. Combinations

# -*- coding: utf-8 -*-
"""
@Time    : 2019/8/22 2:35 PM
@Author  : ddlee
@File    : combinations.py
"""
import itertools# itertools.combinations()
def combinations(iterable, r):pool = tuple(iterable)n = len(pool)if r > n:returnindices = list(range(r))yield tuple(pool[i] for i in indices)while True:for i in reversed(range(r)):if indices[i] != i + n - r:breakelse:returnindices[i] += 1for j in range(i + 1, r):indices[j] = indices[j - 1] + 1yield tuple(pool[i] for i in indices)def combine(n, k):def backtrack(first=1, curr=[]):# if the combination is doneif len(curr) == k:res.append(curr.copy())for i in range(first, n + 1):# add i into the current combinationcurr.append(i)# use next integers to complete the combinationbacktrack(i + 1, curr)# backtrackcurr.pop()res = []backtrack()return resif __name__ == '__main__':# combinations('ABCD', 2) --> AB AC AD BC BD CD# combinations(range(4), 3) --> 012 013 023 123for i in combinations(range(1, 5), 2):print(i)print(combine(n=4, k=2))

3. Josephus

def josephus_formula(n, m):""":param n: 总人数:param m: 每数到m去除:return: 返回最后一个人的下标"""if n == 1:return 0else:return (josephus_formula(n - 1, m) + m) % ndef josephus_mimic(n, k):link = list(range(1, n + 1))ind = 0for loop_i in range(n - 1):ind = (ind + k) % len(link)ind -= 1print('Kill:', link[ind])del link[ind]if ind == -1:  # the last element of linkind = 0print('survice :', link[0])def josephus(n, m):"""Args:n: n peoplem: count m delReturns: last survive"""people = list(range(1, n + 1))idx = 0last = 0for i in range(n):cnt = 0while cnt < m:if people[idx] != -1:cnt += 1if cnt == m:# print(people[idx])last = people[idx]people[idx] = -1idx = (idx + 1) % nreturn lastif __name__ == '__main__':n = 3m = 2ans = josephus(n, m)print(ans)

七、面试题


1. leetcode470 – rand7生成rand10

Given a function rand7 which generates a uniform random integer in the range 1 to 7, write a function rand10 which generates a uniform random integer in the range 1 to 10.
Do NOT use system’s Math.random().

推导:
给定1-a的随机数生成器,产生1-b的随机数生成器

# -*- coding: utf-8 -*-
"""
@Time    : 2019/4/22 9:05 PM
@Author  : ddlee
@File    : 470rand10.py
"""
import randomclass Solution:def rand10(self, n):""":rtype: int"""def rand7():return random.randint(1, 7)res = []for i in range(n):x = 7 * (rand7() - 1) + rand7()while x > 40:x = 7 * (rand7() - 1) + rand7()rnd = x % 10 + 1res.append(rnd)return resif __name__ == '__main__':n = 1000000res = Solution().rand10(n)cnt = [0 for i in range(10)]for i in res:cnt[i-1] += 1print(cnt)

2. leecode273 – 非负整数转换为其对应的英文表示

# -*- coding:UTF-8 -*-"""
将非负整数转换为其对应的英文表示。可以保证给定输入小于 231 - 1 。
示例 1:输入: 123
输出: "One Hundred Twenty Three"
示例 2:输入: 12345
输出: "Twelve Thousand Three Hundred Forty Five"
"""class Solution(object):def numberToWords(self, num):""":type num: int:rtype: str"""d1 = ['', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Eleven', 'Twelve','Thirteen', 'Fourteen', 'Fifteen', 'Sixteen', 'Seventeen', 'Eighteen', 'Nineteen', 'Twenty']d2 = ['', 'Ten', 'Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety']if num == 0: return 'Zero'if num <= 20: return d1[num]if num < 100:t, d = num // 10, num % 10return d2[t] + ' ' + d1[d] if d > 0 else d2[t]if num < 1000:h = num // 100if num % 100 == 0:return d1[h] + ' Hundred'return d1[h] + ' Hundred ' + self.numberToWords(num % 100)if num < 10 ** 6:th = num // 10 ** 3if num % 10 ** 3 == 0:return self.numberToWords(th) + ' Thousand'return self.numberToWords(th) + ' Thousand ' + self.numberToWords(num % 10 ** 3)if num < 10 ** 9:mi = num // 10 ** 6if num % 10 ** 6 == 0:return self.numberToWords(mi) + ' Million'return self.numberToWords(mi) + ' Million ' + self.numberToWords(num % 10 ** 6)if num < 10 ** 12:bi = num // 10 ** 9if num % 10 ** 9 == 0:return d1[num // 10 ** 9] + ' Billion'return self.numberToWords(bi) + ' Billion ' + self.numberToWords(num % 10 ** 9)if __name__ == '__main__':num = 123456print(Solution().numberToWords(num))

3. leetcode207 – 拓扑排序检测有向无环图

# -*- coding: utf-8 -*-
"""
@Time    : 2019/4/23 3:11 PM
@Author  : ddlee
@File    : 207toposort.py
"""
import collections"""
现在你总共有 n 门课需要选,记为 0 到 n-1。在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1]给定课程总量以及它们的先决条件,判断是否可能完成所有课程的学习?示例 1:输入: 2, [[1,0],[0,1]]
输出: false
解释: 总共有 2 门课程。学习课程 1 之前,你需要先完成​课程 0;并且学习课程 0 之前,你还应先完成课程 1。这是不可能的。==> 判断是否为有向无环图
"""class Solution:def canFinish(self, numCourses, prerequisites):""":type numCourses: int:type prerequisites: List[List[int]]:rtype: bool"""graph = collections.defaultdict(list)indegrees = [0] * numCoursesfor course, pre in prerequisites:graph[pre].append(course)indegrees[course] += 1return self.topologicalSort(graph, indegrees) == numCoursesdef topologicalSort(self, graph, indegrees):count = 0queue = []for i in range(len(indegrees)):if indegrees[i] == 0:queue.append(i)l = []while queue:course = queue.pop()l.append(course)count += 1for i in graph[course]:indegrees[i] -= 1if indegrees[i] == 0:queue.append(i)print(l)return countif __name__ == '__main__':print(Solution().canFinish(4, [[1, 0], [1, 2], [0, 3], [2, 3]]))

4. 最小删减构造回文串(最长公共子序列思想)(dp问题)

给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长

def palindrome_seq(s):length = len(s)if length < 2:return 0rs = s[::-1]dp = [[0 for i in range(length + 1)] for j in range(length + 1)]for i in range(1, length + 1):for j in range(1, length + 1):if s[i - 1] == rs[j - 1]:dp[i][j] = dp[i - 1][j - 1] + 1else:dp[i][j] = max(dp[i][j - 1], dp[i - 1][j])for i in dp:print(i)return length - dp[length][length]

5. leetcode300 – 最长上升子序列(dp问题)


def lis2(s):"""最长上升子序列,一维存储:param s::return:"""length = len(s)if length < 2:return length# 以j结尾的最长上升子序列长度dp = [1 for i in range(length + 1)]dp[0] = 0for i in range(1, length + 1):for j in range(i, length + 1):if s[i - 1] < s[j - 1]:dp[j] = max(dp[i] + 1, dp[j])return dp

6. 剑指Offer 14 – 剪绳子最大乘积(dp问题)

def maxProductAfterCutting(n):"""剪绳子, 求乘积最大:param n::return:"""if n < 2:return 0if n == 2:return 1max_list = [0, 1, 2]for i in range(3, n + 1):if i < n:m = ielse:m = 0for j in range(1, i // 2 + 1):tmp = max_list[j] * max_list[i - j]m = max(m, tmp)max_list.append(m)print(max_list)return max_list[n]

7. 最多有多少不重叠的非空区间,使得每个区间内数字的 xor等于0(dp问题)

def most_eor(arr):"""给出n个数字 a_1,...,a_n,问最多有多少不重叠的非空区间,使得每个区间内数字的 xor都等于0。:param arr::return:"""ans = 0xor = 0length = len(arr)mosts = [0 for i in range(length)]map = {}map[0] = -1for i in range(length):xor ^= arr[i]if xor in map:pre = map[xor]  # 找到那个开头位置mosts[i] = 1 if pre == -1 else (mosts[pre] + 1)  # 开头位置的最大值 + 1if i > 0:mosts[i] = max(mosts[i - 1], mosts[i])  # 只依赖前i-1 和 i 两种情况map[xor] = ians = max(ans, mosts[i])return ans

8. 给定一个正数n,求裂开的方法数(dp问题)


def _split_process(pre, rest):if rest == 0:return 1if pre > rest:return 0ways = 0for i in range(pre, rest + 1):ways += _split_process(i, rest - i)return waysdef split_ways(n):if n < 1:return 0return _split_process(1, n)def split_ways_dp(n):"""给定一个正数1,裂开的方法有一种,(1)给定一个正数2,裂开的方法有两种,(1和1)、(2)给定一个正数3,裂开的方法有三种,(1、1、1)、(1、2)、(3)给定一个正数4,裂开的方法有五种,(1、1、1、1)、(1、1、2)、(1、3)、(2、2)、 (4)给定一个正数n,求裂开的方法数。动态规划优化状态依赖的技巧:param n::return:"""if n < 1:return 0dp = [[0 for j in range(n + 1)] for i in range(n + 1)]for i in range(1, n + 1):dp[i][0] = 1for i in range(1, n + 1):dp[i][i] = 1for pre in range(1, n)[::-1]:for rest in range(pre + 1, n + 1):dp[pre][rest] = dp[pre + 1][rest] + dp[pre][rest - pre]for i in dp:print(i)return dp[1][n]

9. 消消乐问题(dp问题)

问题描述:
打气球,一下 能 连续打爆一串回文串,或者打爆一个
求打爆所有的最少需要几次?

# -*- coding:UTF-8 -*-
import sysdef archer(n, nums):"""动态规划:param n::param nums::return:"""dp = [[sys.maxsize for j in range(n)] for i in range(n)]for i in range(n):for j in range(i, n):if i == j:dp[i][j] = 1continueif j - i == 1:dp[i][j] = 1 if nums[i] == nums[j] else 2breakfor i in range(n):for j in range(i, n):for k in range(i, j):dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j])if nums[i] == nums[j] and i + 1 < j - 1:dp[i][j] = min((dp[i][j], dp[i + 1][j - 1]))for i in dp:print(i)return dp[0][n - 1]def dfs(l, r):"""动态规划递归形式:param l::param r::return:"""if dp[l][r] != -1:return dp[l][r]if l == r:dp[l][r] = 1return dp[l][r]if r - l == 1:dp[l][r] = 1 if nums[l] == nums[r] else 2return dp[l][r]ans = sys.maxsizefor k in range(l, r):ans = min(ans, dfs(l, k) + dfs(k + 1, r))if nums[l] == nums[r]:ans = min(ans, dfs(l + 1, r - 1))dp[l][r] = ansreturn dp[l][r]if __name__ == '__main__':"""问题描述:打气球,一下 能 连续打爆一串回文串,或者打爆一个求打爆所有的最少需要几次?"""n = 4nums = [1, 4, 3, 1]dp = [[-1 for j in range(n)] for i in range(n)]print(dfs(0, n - 1))for i in dp:print(i)print("--" * 10)print(archer(n, nums))

10. 企鹅合体问题(dp问题)


def penguin_merge_near(arr):"""企鹅合体,只能合体一次,只能和左右其中的一个合体,合体即乘积,有可能为负数,求最大值:param arr::return:"""length = len(arr)if length < 1:return 0elif length == 1:return arr[0]elif length == 2:return max(arr[0] + arr[1], arr[0] * arr[1])dp = [0 for i in range(length + 1)]dp[1] = arr[0]dp[2] = max(arr[0] + arr[1], arr[0] * arr[1])if length > 2:for i in range(3, length + 1):dp[i] = max(dp[i - 1] + arr[i - 1], dp[i - 2] + arr[i - 1] * arr[i - 2])return dp[-1]def penguin_merge(arr):"""企鹅合体,只能合体一次,合体即乘积,有可能为负数,求最大值由于不指定顺序,因此可以先排序,-5, -3, 0, 1, 3, 5:param arr::return:"""length = len(arr)arr = sorted(arr)if length < 1:return 0elif length == 1:return arr[0]elif length == 2:return max(arr[0] + arr[1], arr[0] * arr[1])ans = 0if length > 2:l = 0r = length - 1while r > 0:if arr[r - 1] > 1:ans += arr[r] * arr[r - 1]r -= 2else:breakwhile l < r:if arr[l + 1] <= 0:ans += arr[l] * arr[l + 1]l += 2else:breakwhile l <= r:ans += arr[l]l += 1return ans

11. leetcode845 – 最长山脉问题(dp问题)

# -*- coding: utf-8 -*-
"""
@Time    : 2019/5/11 3:06 PM
@Author  : ddlee
@File    : 845longest_mountain.py
"""class Solution():def longestMountain1(self, arr):"""求数组中的最长山脉- B.length >= 3- 存在 0 < i < B.length - 1 使得 B[0] < B[1] < ... B[i-1] < B[i] > B[i+1] > ... > B[B.length - 1]输入:[2,1,4,7,3,2,5]输出:5解释:最长的 “山脉” 是 [1,4,7,3,2],长度为 5。"""# j结尾的递增序列def lis(arr):length = len(arr)dp = [0 for i in range(length + 1)]for i in range(1, length + 1):for j in range(i, length + 1):if arr[j - 1] > arr[i - 1]:dp[j] = max(dp[i] + 1, dp[j])return dp# i开头的递减序列def lds(arr):length = len(arr)dp = [0 for i in range(length + 1)]for i in range(1, length + 1)[::-1]:for j in range(i, length + 1)[::-1]:if arr[j - 1] < arr[i - 1]:dp[i] = max(dp[j] + 1, dp[i])return dplis_dp = lis(arr)print(lis_dp)lds_dp = lds(arr)print(lds_dp)res = []for i in range(len(lis_dp)):if lis_dp[i] and lds_dp[i]:res.append(lis_dp[i] + lds_dp[i] + 1)else:res.append(0)return max(res) if res else 0def longestMountain(self, arr):"""求数组中的最长山脉- B.length >= 3- 存在 0 < i < B.length - 1 使得 B[0] < B[1] < ... B[i-1] < B[i] > B[i+1] > ... > B[B.length - 1]输入:[2,1,4,7,3,2,5]输出:5解释:最长的 “山脉” 是 [1,4,7,3,2],长度为 5。"""# i结尾的递增序列def lis(arr):length = len(arr)dp = [0 for i in range(length)]for i in range(1, length):if arr[i] > arr[i - 1]:dp[i] = max(dp[i - 1] + 1, dp[i])return dp# i开头的递减序列def lds(arr):length = len(arr)dp = [0 for i in range(length)]for i in range(length - 1)[::-1]:if arr[i] > arr[i + 1]:dp[i] = max(dp[i + 1] + 1, dp[i])return dplis_dp = lis(arr)# print(lis_dp)lds_dp = lds(arr)# print(lds_dp)res = []for i in range(len(lis_dp)):if lis_dp[i] and lds_dp[i]:res.append(lis_dp[i] + lds_dp[i] + 1)else:res.append(0)return max(res) if res else 0if __name__ == '__main__':arr = [2, 1, 4, 7, 3, 2, 5]arr = list(range(5))arr = []print(Solution().longestMountain(arr))

12. 分隔数组以得到最大和 (dp问题)

给出整数数组 A,将该数组分隔为长度最多为 K 的几个(连续)子数组。
分隔完成后,每个子数组的中的值都会变为该子数组中的最大值。
返回给定数组完成分隔后的最大和。

输入:A = [1,15,7,9,2,5,10], K = 3
输出:84
解释:A 变为 [15,15,15,9,10,10,10]

class Solution:def maxSumAfterPartitioning2(self, A, K):l = len(A)dp = [0 for i in range(l+1)]for i in range(l):maxi = 0rb = min(i + K, l)  # right boundfor j in range(i, rb):maxi = max(maxi, A[j])dp[j + 1] = max(dp[j + 1], dp[i] + (j - i + 1) * maxi)# print(dp)return dp[l]

13. leetcode221 – 最大正方形(dp问题)

在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积。
示例:
输入:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
输出: 4

class Solution:def maximalSquare1(self, matrix):if len(matrix) < 1:return 0matrix = [list(map(int, row)) for row in matrix]m = len(matrix)n = len(matrix[0])dp = [[0 for j in range(n)] for i in range(m)]for i in range(m):dp[i][0] = matrix[i][0]for j in range(n):dp[0][j] = matrix[0][j]for i in range(1, m):for j in range(1, n):if matrix[i][j] == 1:if matrix[i - 1][j - 1] == 1:for ind in range(1, int(math.sqrt(dp[i - 1][j - 1]) + 1)):if matrix[i - ind][j] == 1 and matrix[i][j - ind] == 1:dp[i][j] = int(pow(ind + 1, 2))else:dp[i][j] = int(pow(ind + 1 - 1, 2))breakelse:dp[i][j] = 1return max(map(max,dp))"""计算边长,比上一种方案好"""def maximalSquare(self, matrix):if len(matrix) < 1:return 0matrix = [list(map(int, row)) for row in matrix]m = len(matrix)n = len(matrix[0])dp = [[0 for j in range(n)] for i in range(m)]for i in range(m):dp[i][0] = matrix[i][0]for j in range(n):dp[0][j] = matrix[0][j]for i in range(1, m):for j in range(1, n):if matrix[i][j] == 1:dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1else:min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1])for i in dp:print(i)return pow(max(map(max,dp)), 2)

14. 最后剩一块石头重量(dp问题)

class Solution:"""1049. 最后一块石头的重量 II  显示英文描述有一堆石头,每块石头的重量都是正整数。每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:如果 x == y,那么两块石头都会被完全粉碎;如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。最后,最多只会剩下一块石头。返回此石头最小的可能重量。如果没有石头剩下,就返回 0。示例:输入:[2,7,4,1,8,1]输出:1解释:组合 2 和 4,得到 2,所以数组转化为 [2,7,1,8,1],组合 7 和 8,得到 1,所以数组转化为 [2,1,1,1],组合 2 和 1,得到 1,所以数组转化为 [1,1,1],组合 1 和 1,得到 0,所以数组转化为 [1],这就是最优值。"""def lastStoneWeightII(self, stones):'''动态规划 背包问题'''l = len(stones)if l < 1:return 0half = sum(stones) // 2  # 背包最大放的重量dp = [[0 for j in range(half + 1)] for i in range(l + 1)]for i in range(1, l + 1):for j in range(1, half + 1):if stones[i - 1] > j:dp[i][j] = dp[i - 1][j]else:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - stones[i - 1]] + stones[i - 1])for i in dp:print(i)return sum(stones) - (2 * dp[-1][-1])

15. 最长等差序列(dp问题)


class Solution:"""输入:[3,6,9,12]输出:4解释:整个数组是公差为 3 的等差数列。"""'''dp加缓存'''def longestArithSeqLength(self, A) -> int:if A == None or A == []:return 0n, res = len(A), 1dp = [{0: 1} for _ in range(n)]for j in range(n):for i in range(j):step = A[j] - A[i]if step in dp[i]:if step in dp[j]:dp[j][step] = max(dp[i][step] + 1, dp[j][step])else:dp[j][step] = dp[i][step] + 1else:dp[j][step] = 2res = max(res, max(dp[j].values()))print(dp)return res'''暴力超时'''def las(self, A):if A == None or A == []:return 0l = len(A)if l < 2:return lres = 2for i in range(l):for j in range(i + 1, l):tmp = 2gap = A[j] - A[i]next = A[j] + gapfor k in range(j + 1, l):if A[k] == next:tmp += 1next += gapres = max(res, tmp)return res

16. leetcoe115 – 不同的子序列(dp问题)


"""
不同的子序列
给定一个字符串 S 和一个字符串 T,计算在 S 的子序列中 T 出现的个数。
一个字符串的一个子序列是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。
(例如,"ACE" 是 "ABCDE" 的一个子序列,而 "AEC" 不是)示例 1:输入: S = "rabbbit", T = "rabbit"
输出: 3
解释:
如下图所示, 有 3 种可以从 S 中得到 "rabbit" 的方案。
(上箭头符号 ^ 表示选取的字母)rabbbit
^^^^ ^^
rabbbit
^^ ^^^^
rabbbit
^^^ ^^^
"""class Solution:def numDistinct(self, s: str, t: str) -> int:ls = len(s) + 1lt = len(t) + 1dp = [[0 for j in range(lt)] for i in range(ls)]if not t:return 1for i in range(ls):dp[i][0] = 1dp[i][1] = s[:i].count(t[0])for i in range(1, ls):for j in range(1, lt):if s[i - 1] == t[j - 1]:dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j]# 相等的情况:s用相等这一位的方案 +  s不用相等这一位的方案else:dp[i][j] = dp[i - 1][j]for i in dp:print(i)return dp[-1][-1]

17. leetcoe279 – 完全平方数(dp问题)

解决方案:动态规划,定义一个dp数组,长度为N+1,初始化为系统最大值,0的位置初始化为0
从1开始刷新整个数组:
1的平方是1,所以1……N中填1……N,更新dp
2的平方是4,所以从4的位置开始更新,dp[i] = min(dp[i], dp[i-j^2]+1)
……


'''
279. 完全平方数给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。示例 1:
输入: n = 12
输出: 3
解释: 12 = 4 + 4 + 4.示例 2:
输入: n = 13
输出: 2
解释: 13 = 4 + 9.
'''class Solution:def numSquares(self, n: int) -> int:if n < 1:return 0dp = [sys.maxsize for i in range(n + 1)]dp[0] = 0rnd = int(pow(n, 0.5)) + 1for i in range(1, rnd):for j in range(pow(i, 2), n + 1):dp[j] = min(dp[j], dp[j - pow(i, 2)] + 1)# print(dp)return dp[-1]def numSquares1(self, n):""":type n: int:rtype: int"""def help(N, size):if (N == 0): return True;if (size == 0): return False;k = int(pow(N, 0.5));for i in range(k, 0, -1):if (help(N - i * i, size - 1)):return Truereturn Falsef = Falseans = 0;while (f == 0):ans = ans + 1;f = help(n, ans)return ansif __name__ == '__main__':print(Solution().numSquares2(6175))

21. 数据流求中位数(大根堆问题)

# -*- coding:UTF-8 -*-"""想法:构建两个堆,大根堆,小根堆,保证大根堆的最大值 比 小根堆的最小值 小,保证两个堆相差不超过2这样中位数就可以通过计算堆顶元素获得,时间复杂度O(1)堆调整的复杂度O(logn)"""
class MedianFinder(object):def __init__(self):self.arr = []self.max_heap = []self.min_heap = []def add_num(self, num):self.max_heap.append(num)self.down_ajust_max(self.max_heap)self.min_heap.append(self.max_heap.pop(0))self.down_ajust_min(self.min_heap)if len(self.max_heap) < len(self.min_heap):self.max_heap.append(self.min_heap.pop(0))# self.down_ajust_min(self.min_heap)self.down_ajust_max(self.max_heap)def down_ajust_max(self, arr):length = len(arr)if length < 2:return arrparent_idx = 0tmp = arr[parent_idx]child_idx = 2 * parent_idx + 1while child_idx < length:if child_idx + 1 < length and arr[child_idx + 1] > arr[child_idx]:child_idx += 1if tmp > arr[child_idx]:breakarr[parent_idx] = arr[child_idx]parent_idx = child_idxchild_idx = 2 * child_idx + 1arr[parent_idx] = tmpdef down_ajust_min(self, arr):length = len(arr)if length < 2:return arrparent_idx = 0tmp = arr[parent_idx]child_idx = 2 * parent_idx + 1while child_idx < length:if child_idx + 1 < length and arr[child_idx + 1] < arr[child_idx]:child_idx += 1if tmp < arr[child_idx]:breakarr[parent_idx] = arr[child_idx]parent_idx = child_idxchild_idx = 2 * child_idx + 1arr[parent_idx] = tmpdef find_median(self):if len(self.max_heap) == len(self.min_heap):return (self.max_heap[0] + self.min_heap[0]) / 2else:return self.max_heap[0]if __name__ == '__main__':mf = MedianFinder()mf.add_num(5)mf.add_num(4)mf.add_num(9)mf.add_num(7)mf.add_num(3)print(mf.min_heap)print(mf.max_heap)print(mf.find_median())

22. 判断矩阵中是否存在指定路径(递归)

class Solution:def hasPath(self, matrix, rows, cols, path):# write code herefor i in range(rows):for j in range(cols):if matrix[i * cols + j] == path[0]:if self.find(list(matrix), rows, cols, path[1:], i, j):return Truereturn Falsedef find(self, matrix, rows, cols, path, i, j):if not path:return Truematrix[i * cols + j] = '0'if j + 1 < cols and matrix[i * cols + j + 1] == path[0]:return self.find(matrix, rows, cols, path[1:], i, j + 1)elif j - 1 >= 0 and matrix[i * cols + j - 1] == path[0]:return self.find(matrix, rows, cols, path[1:], i, j - 1)elif i + 1 < rows and matrix[(i + 1) * cols + j] == path[0]:return self.find(matrix, rows, cols, path[1:], i + 1, j)elif i - 1 >= 0 and matrix[(i - 1) * cols + j] == path[0]:return self.find(matrix, rows, cols, path[1:], i - 1, j)else:return False

23. sqrt

def sqrt(x):if x < 2:return xleft, right = 0, xwhile left <= right:mid = left + (right - left) // 2if mid * mid < x:# left=midleft = mid + 1lstmid = mid  # 关键步骤elif mid * mid > x:# right=xright = mid - 1else:return midreturn lstmid

24. 约瑟夫环

"""
Josephuse环
n个人,编号0 到 n-1,每走step步移除一个人,最后剩的编号是?method-1: 用环去模拟
method-2:分析规律  计算(有公式)
"""def last_remain(length, step):if length < 1 or step < 1:return -1nums = [i for i in range(length)]step_cnt = 0remain_cnt = lengthi = -1while remain_cnt > 0:i += 1if i >= length:i = 0if nums[i] == -1:continuestep_cnt += 1if step_cnt == step:nums[i] = -1step_cnt = 0remain_cnt -= 1return i# 公式版本
def last_remain_2(length, step):if length < 1 or step < 1:return -1last = 0for i in range(2, length + 1):last = (last + step) % ireturn lastif __name__ == '__main__':for i in range(1,50):print(last_remain(i, 3), last_remain_2(i, 3))

25. 2sum 3sum

# -*- coding:UTF-8 -*-def sum_2(arr, target):hash_table = {}res = []for i in range(len(arr)):if target - arr[i] in hash_table:res.append([hash_table[target - arr[i]], i])hash_table[arr[i]] = ireturn resdef sum_3(arr, target):arr.sort()len1 = len(arr)res = []if len1 < 3:print(res)for i in range(len1 - 1):left, right = i + 1, len1 - 1  # 以下思路与2sum中的快速排序思想一样while left < right:sum = arr[i] + arr[left] + arr[right]if sum == target and [arr[i], arr[left], arr[right]] not in res:res.append([arr[i], arr[left], arr[right]])left += 1right -= 1elif sum < target:left += 1else:right -= 1print(res)def sum_3_2(arr, target):  # 3sum问题 解 2res = []for i, value1 in enumerate(arr):for j, value2 in enumerate(arr[i + 1:]):if (target - value1 - value2) in arr[i + 2:]:minV = min(value1, value2, target - value1 - value2)maxV = max(value1, value2, target - value1 - value2)midV = target - minV - maxVres.append((minV, midV, maxV))print(list(set(res)))if __name__ == '__main__':nums = [1, 4, 3, 2, 6, 5]target = 6print(sum_2(nums, target))sum_3(nums, target)sum_3_2(nums, target)print(continuous_pos_sum(15))

26. leetcode40 – 和为target的组合(递归)

class Solution:"""leetcode 40给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的每个数字在每个组合中只能使用一次。"""def combinationSum2(self, candidates, target):# 下面有一个目标值小于某一元素就break,所以先排序candidates.sort()# 储存返回的二维列表res, length = [], len(candidates)# 递归,目标值,起始位置,当前组合def dfs(target, start, vlist):# 目标值为0,表明当前递归完成,把当前递归结果加入res并返回if target == 0:return res.append(vlist)# 从开始下标循环for i in range(start, length):# candidates有序,只要当前大于目标后面都大于,直接breakif target < candidates[i]:break# 这个判断保证不重复例如1,1,2,5,6,7,10,第二个1就会被跳过if i > start and candidates[i] == candidates[i - 1]:continue# 否则目标值减当前值,i+1为新的起始位置(不用重复数字),把当前值加入当前组合else:dfs(target - candidates[i], i + 1, vlist + [candidates[i]])dfs(target, 0, [])return res"""leetcode 39给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的每个数字在每个组合中次数不限。"""def combinationSum(self, candidates, target):# 下面有一个目标值小于某一元素就break,所以先排序candidates.sort()# 储存返回的二维列表res, length = [], len(candidates)# 递归,目标值,起始位置,当前组合def dfs(target, start, vlist):# 目标值为0,表明当前递归完成,把当前递归结果加入res并返回if target == 0:return res.append(vlist)# 从开始下标循环for i in range(start, length):# candidates有序,只要当前大于目标后面都大于,直接breakif target < candidates[i]: break# 这个判断保证不重复例如1,1,2,5,6,7,10,第二个1就会被跳过if i > start and candidates[i] == candidates[i - 1]:continue# 否则目标值减当前值,i为用重复数字,把当前值加入当前组合else:dfs(target - candidates[i], i, vlist + [candidates[i]])dfs(target, 0, [])return res

27. leetcode372 – 超级次方 (power的复杂度是log(n))

class Solution:def myPow(self, x: float, n: int) -> float:# return pow(x, n)i = nif i < 0:i = -ires = 1while i != 0:if i % 2 != 0:res *= xx *= xi = i // 2return res if n > 0 else 1 / resdef superPow(self, a, b):"""你的任务是计算 ab 对 1337 取模,a 是一个正整数,b 是一个非常大的正整数且会以数组形式给出。示例 1:输入: a = 2, b = [3]输出: 8示例 2:输入: a = 2, b = [1,0]输出: 1024"""def modn(a, b, c):res = 1while b != 0:if (b & 1):res *= ares %= ca *= aa %= cb >>= 1return respower = 0for i in b:power = power * 10 + ia = a % 1337res = modn(a, power, 1337)return res % 1337if __name__ == '__main__':a = 2b = [3, 0, 0]print(Solution().superPow(a, b))

28. leetcode668 – 给定高度m 、宽度n 的一张 m * n的乘法表,以及正整数k,你需要返回表中第k 小的数字(二分查找,逆向思维)

给定高度m 、宽度n 的一张 m * n的乘法表,以及正整数k,你需要返回表中第k 小的数字。
例 1:
输入: m = 3, n = 3, k = 5
输出: 3
解释:
乘法表:
1 2 3
2 4 6
3 6 9
第5小的数字是 3 (1, 2, 2, 3, 3).

class Solution:def findKthNumber(self, m: int, n: int, k: int) -> int:def cnt_before_x(x):cnt = 0for i in range(1, m + 1):cnt += min(x // i, n)return cntdef binary_search(left, right, k):while left < right:mid = (left + right) >> 1cnt = cnt_before_x(mid)if cnt >= k:right = midelse:left = mid + 1return leftleft = 1right = m * n + 1kth = binary_search(left, right, k)return kth




决战秋招 -- 经典面试题集锦相关推荐

  1. 字节跳动2020秋招研发笔试题

    字节跳动秋招研发笔试题 最近在忙考研,高数复习完了,看了下数据结构和算法,然后对人生比较迷茫. 该不该放弃考研,又怕考不上面临找工作的问题,索性看了几家科技巨头的秋招试题,贴下来和大家分享下 基本都是 ...

  2. FPGA/IC 秋招笔试/面试题总结

    请根据目录浏览,觉得有用三连支持一下也是一种鼓励~. 原创不易,100页+,未经允许,请勿转载. 打印版,联系微信:Crazzy_M FPGA/IC 秋招笔试/面试题总结(目录展示) ☛内容展示点这里 ...

  3. FPGA/IC秋招经典100题(含详解)

    <FPGA/IC秋招经典100题(含详解)> 持续更新中 ,觉得有用三连支持一下也是一种鼓励~. 链接直达☟: <FPGA/IC 秋招笔试/面试题总结> <FPGA/IC ...

  4. java笔试题_公司真题 | 用友2018秋招Java笔试题(四)

    公司真题 | 用友2018秋招Java笔试题(三)答案: 1.正确答案 A B 2.正确答案 A 3.正确答案 D 4.正确答案 B 5.正确答案 A E 6.正确答案 B 7.正确答案 C D 8. ...

  5. [转载] 硬件工程师经典笔试题集锦---(张飞实战电子)

    [别找了全在这]硬件工程师经典笔试题集锦! 直转链接:https://www.sohu.com/a/312704438_819258 数字电路知识问题,请简要回答之. (1) 什么是 Setup和 H ...

  6. 途牛网php笔试题,2018秋招途牛笔试试题分享,期待春招offer!

    去年秋招做的途牛的笔试题,分享给大家,求春招好运,获得一个满意的offer! 单选题 1.下面的代码执行后,i,j的值各是多少(  ) A i=6,j=5 B i=5,j=5 C i=6,j=5 D ...

  7. 国内各大IT公司经典面试题集锦

    1 引言    当即早已进入10月份,十一过后,招聘,笔试,面试,求职渐趋火热.而在这一系列过程背后浮出的各大IT公司的笔试/面试题则蕴含着诸多思想与设计,细细把玩,思考一番亦能有不少收获.     ...

  8. 2022秋招前端面试题(一)(附答案)

    闭包产生的本质 当前环境中存在指向父级作用域的引用 手写 bind.apply.call // callFunction.prototype.call = function (context, ... ...

  9. 美图笔试题java后台_美图2018秋招Java笔试题

    单选题 1.关于垃圾回收算法G1,哪个说法是错误的( B  ). A.  并行和并发,具有多线程操作能力 B.  不适用堆空间太大的场景 C.  G1停顿时间更加可预测 D.  不会对系统吞吐量产生较 ...

最新文章

  1. 本人制作的股票技术分析软件正式开源(.net wpf)
  2. android自定义抽奖,Android自定义view制作抽奖转盘
  3. 吴恩达登录知乎,亲自回答如何系统学习机器学习
  4. oracle备份还原采集,oracle 备份还原
  5. 贝叶斯分类python代码调试_数据挖掘实验2python编写贝叶斯分类器 – FindSpace
  6. Unity的Flutter——UIWidgets简介及入门
  7. OCA第2部分中的Java难题
  8. guava 并发同步_Google Guava –与Monitor同步
  9. Hibernate延时加载
  10. Tabular Editor学习笔记_1
  11. Python实现身份证号码合法性校验
  12. 捍卫自己的WiFi安全
  13. 前端中的A、B、C端解释
  14. swiper 滑动图片垂直居中
  15. 拷贝pdf中的表格数据
  16. wisp5学习日记1
  17. 中关村“染指”番茄花园
  18. CAD版本转换知识大全
  19. php 屏蔽浸膏,【佳学基因】副甲状腺浸膏基因检测
  20. 常用的内存泄漏检查工具

热门文章

  1. 关于HOOK,如何通过钩子截获指定窗口的所有消息
  2. 511遇见易语言API模块进程创建CreateProcess
  3. 【前后端对接迷惑问题】无法加载响应数据:No resource with given identifier found
  4. python2.7开发photoshop一些经验
  5. wordpress 文章php,Wordpress制作文章页面single.php
  6. docker打jdk 1.8镜像
  7. c语言访问mysql,C语言访问mysql数据库
  8. nginx 做均衡负载
  9. 网上买保险靠谱吗?线上保险和线下保险的区别在哪?
  10. html爆炸效果,HTML5 SVG炫酷文字爆炸特效