![](https://img-blog.csdnimg.cn/20190927151132530.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
剑指
o
Better-1
这个作者很懒,什么都没留下…
展开
-
课程表~~~
DFS深度优先,先用字典记录所有的信息,但是可以用第二种方法,直接使用列表记录即可~~class Solution: def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool: ## 也就是不是一个环 record = {} sign = {} for i in range(len(prerequisites)): .原创 2021-09-25 15:00:51 · 144 阅读 · 0 评论 -
python-zip函数- list - set操作
a = [1,2,3,5,8] ## 如果两个的长度不同,那么结果就是较短的长度b = [2,3,4,8]print(dict(zip(a, b))) #{1: 2, 2: 3, 3: 4, 5: 8}print(list(zip(a, b))) #[(1, 2), (2, 3), (3, 4), (5, 8)]print(tuple(zip(a, b))) #((1, 2), (2, 3), (3, 4), (5, 8))...原创 2021-09-09 21:33:54 · 271 阅读 · 0 评论 -
百搜相关----
数组中只包含012,将数组升序排列,on时间复杂度o1空间复杂度三个指针,和partition一样的思想~class Solution: def sort(self, nums): res1 = 0 res2 = 0 res3 = 0 for i in range(len(nums)): if nums[i] == 0: nums[res2], nums[res3] = num原创 2021-07-24 12:22:25 · 103 阅读 · 0 评论 -
链表汇总专题~~
只要first出马,一般都没问题。两两交换节点# Definition for singly-linked list.# class ListNode:# def __init__(self, val=0, next=None):# self.val = val# self.next = nextclass Solution: def swapPairs(self, head: ListNode) -> ListNode:原创 2021-07-18 18:20:17 · 106 阅读 · 0 评论 -
交点-hard
#### 斜截式:y=kx+b【适用于不垂直于x轴的直线】#### 参数方程式,它可以表示任意的直线,并且它非常适合用于表示线段。假设我们给定两个点 (x_1, y_1)(x1,y1) 以及 (x_2, y_2)(x2,y2),我们只需要令:# x = x_1 + t(x_2 - x_1) and y = y_1 + t(y_2 - y_1)#### 所以这道题的点就在于要用参数方程来求解。必须可以表示任意的直线~~#### 当然我还是用斜截式,比较熟悉。所以要分是否与x轴垂直。 k = (.原创 2021-07-18 10:56:26 · 81 阅读 · 0 评论 -
盛水问题总结
直方图水量1、两边收缩~ 好!!!从两边收缩,因为本来就是通过两边来的,所以两边的最值是可以肯定的。如果左边的最值比右边的最值小,那么左边的水量是可以肯定的,肯定是短板~class Solution: def trap(self, height: List[int]) -> int: result = 0 left = 0 right = len(height) - 1 left_max = 0 right原创 2021-07-17 11:11:10 · 242 阅读 · 0 评论 -
几道规律题的总结
规律题还是少碰,感觉提高不大。1、数字序列中某一位的数字思路是每次去除对应位数的总和,比如1位的总数是9,二位的总和是180… 分别减去1位数的总和,二位数的总和等等,最后剩余部分就是最上层的位数 对应的数了。class Solution: def findNthDigit(self, n): if n <= 0: return 0 res = 1 num = 1 tmp = 9原创 2021-06-29 12:07:59 · 116 阅读 · 0 评论 -
heapq的使用总结
heapq实现的就是最小堆,如果需要实现最大堆,可以通过加上负号。heapq.heappop(res)heapq.heappush(res, num)heapq.heapify() 转化成堆1、#### 可以直接使用self.heap1[0]来代表堆顶,用nsamllest太麻烦了,时间复杂度太大2、注意最小堆,堆顶绝对是最小的。3、永远都是heapq开头,原本的堆放在函数里面。注意,堆在这里只是一个抽象的数据结构,还是基于list实现的。4、其实从头开始直接 heapq.heappush和h原创 2021-06-27 12:12:31 · 1248 阅读 · 0 评论 -
移掉k位数字
莽撞了~一直在试结果。。。做题不可如此。下面解法的关键思想是高位的元素如果越小越好,所以如果比之前位上的值更小,那么就把 之前位上的值 去掉~~ 所以比栈顶大的元素直接入栈, 如果比栈顶小,就把栈顶弹出来~~class Solution: def removeKdigits(self, num: str, k: int) -> str: if len(num) == k: return "0" res = [] .原创 2021-06-15 08:59:55 · 48 阅读 · 0 评论 -
编辑距离~
删除: dp[i][j] = min(dp[i-1][j]+1, dp[i][j]插入: dp[i][j] = min(dp[i][j-1]+1, dp[i][j])替换: dp[i][j] = dp[i-1][j-1]+1归结: dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1还是通过表格,最直观可以了解到, 删除的话,那么其实就是相当于i-1已经做到的,此时i可以不用的情况;插入就是相当于原本i满足j-1了,此时插入就是满足.原创 2021-06-15 07:57:10 · 115 阅读 · 1 评论 -
正则表达式匹配
两种方法,一种是动态规划,一种是递归,这题属于hard题了。其实递归稍微简单一些,但是一些特殊情况比较难以考虑,比如p的开头就是“*”,要提前排除。 递归要提前考虑p[1]是否为 星号。动态规划:if p[j-1] == “*”:if s[i-1] == p[j-2]: dp[i][j] |= dp[i-1][j-1]dp[i][j] |= dp[i][j-2]class Solution: def isMatch(self, s: str, p: str) -> bool: .原创 2021-06-12 16:58:29 · 72 阅读 · 0 评论 -
旋转字符串
第一种做法是O(n*n)的复杂度,第二种做法是O(N)。class Solution: def solve(self , A , B ): # write code here if not A and not B: return True if len(A) != len(B): return False done = 0 for i in range(len(B)):.原创 2021-06-10 21:26:56 · 60 阅读 · 0 评论 -
~~~旋转数组
美团二面面到了~归根结底还是范围的缩小!1、旋转数组的难点是在是否有重复的数字,下面这题是有的,所以直接与最后的一位/第一位比较来判断是否属于左边的数组还是右边的数组是不可行的。但是因为只是找最小的,所以还可~注意缩小范围的方法: 如果mid值大于right,必然在左边的数组,故left=mid+加一个判断条件,如果left=mid,直接跳出; 如果mid小于right,其实错: 可能是左边也可能是右边的数组,只可能是右边的数组,所以 right = mid ; 如果mid等于right, right原创 2021-06-09 22:35:55 · 68 阅读 · 0 评论 -
排序全总结
面试无非:快排、归并、堆、冒泡、插入,以及复杂度、稳定性快排 == 不稳定相当于先序遍历 时间复杂度O(nlogn),最差O(n*n), 空间复杂度O(logn)===不稳定def partition(nums, left, right): tar = nums[right] res1 = left res2 = left - 1 for i in range(left, right): if nums[i] <= tar:原创 2021-06-07 09:33:53 · 88 阅读 · 0 评论 -
剑指 Offer 03. 数组中重复的数字
其他排序nlogn; O(N)空间复杂度的记录; 就不阐述了。 最优的还是时间复杂度O(N), 空间复杂度O(1)。这里有个坑,还是不要随便 a, b = b, a交换了。 在带数组的这里,不是同时交换的。下面的方法就是从左开始,因为本题如果是nums[i] != i, 那么就一直交换,如果相等就继续往下,如果实在没有i这个值,那么其实就是原地不动了,直到交换到 该点本身就是 该点的值。 就return重复的数了~~nums = [1,2,3,4,5]nums[1], nums[nums[1].原创 2021-06-05 16:53:28 · 67 阅读 · 0 评论 -
单源最短路
这道题本不难,难点是在重边。 正常逻辑应该都可以想到 存储顶点与顶点之间的长度的关系,然后dfs从1到n,相当于回溯~存储的话 第一种解法是字典,稍许麻烦,因为重边的原因,先排序,然后后续进来一致的都否掉;第二种解法是dp二维列表存储,dp[i] [j]代表的是顶点i到顶点j的距离,下次来就是求min。然后就是常规的dfs。第一种解法遇到的障碍是忽略了可能不在record里面,相当于在利用字典的时候,还是应该提前判断是否在字典中,否则很难检查,遗留大患!!!!class Solution: .原创 2021-06-05 14:14:40 · 124 阅读 · 0 评论 -
动态规划--牛牛的数列
这道题目遇到的问题:没有考虑到数可以增大,其实也可以减小~所以,必须从两个方向入手。从左边入手可以查看递增的,从右边入手查看递减的。下面第一种方法是 从左开始,只考虑让某个数增大形成递增数列; 从右边开始只考虑让某个数减少形成递减数列。== 因为只有两种情况,不是增大就是减小。记录两种状态:使用两个列表,一个列表记录的是当前没有改变过数的最长数列; 一个记录的是改变了当前位置的数最长数列。class Solution: def maxSubArrayLength(self , nums ):.原创 2021-06-03 07:33:29 · 710 阅读 · 1 评论 -
tab和空格替换
已存在的文件 空格|tab 长度替换TAB替换为空格:set ts=4:set expandtab:%retab!空格替换为TAB:set ts=4:set noexpandtab:%retab!加!是用于处理非空白字符之后的TAB,即所有的TAB,若不加!,则只处理行首的TAB。...原创 2021-06-01 17:47:54 · 871 阅读 · 0 评论 -
完全二叉树的节点个数
O(N)难度极低,面试肯定是小于O(N)# O(N)的时间复杂度class Solution: def countNodes(self, root: TreeNode) -> int: if not root: return 0 return self.countNodes(root.left) + 1 + self.countNodes(root.right)下面是O(NLOGN) 利用满二叉树的概念。其实就是划分左右子树,如.原创 2021-06-01 09:44:17 · 186 阅读 · 0 评论 -
单调栈~~下一个更大的元素
O(N)时间复杂度解决~~左边就从左边开始,如果比上一个小,那么上一个弹出…右边就从右边开始,如果比上一个大,放入,小也弹出之前的.# 反正记住优先队列就是有进有出~~这么思考class Solution: def foundMonotoneStack(self , nums ): # write code here # 左边就从左边开始,如果比上一个小,那么上一个弹出... # 右边就从右边开始,如果比上一个大,放入,小也弹出之前的. .原创 2021-05-31 20:16:59 · 141 阅读 · 0 评论 -
最小生成数
生成树的概念就是满足有n个顶点的生成树,有且仅有n-1条边,但是有n-1条边的图不一定都是生成树。准则:1、必须只使用该图的边来构造最小生成树2、必须使用且仅使用n-1条边来连接图中的n个顶点3、不能使用产生回路的边。保证任意两个节点都可以互相链接就可以。很简单。直接用并查集完事。先排序,然后并查集查询是否是同个根节点,如果是,那么肯定不可以连接,否则回路生成。所以 并查集一个关键作用就是可以查询是否存在联系。class Solution: def miniSpanningTree原创 2021-05-30 18:15:44 · 157 阅读 · 0 评论 -
主持人调度
联系一下美团三面的题。两个排序数组,进行合并。[[1, 3], [6, 10]], [[2, 5], [7, 11]]合并: [[1, 5], [6, 11]]解题方法就是每次抽取两个数组中首位最小的,然后与前面提取的末位进行比较,如果小于末位,就可以融合,否则新起一组。下面的题目其实就是求 最大的有公共区间的数目。这道题极有可能面试题,第一种做法很常规,记录每次的结束时间,但是需要排序,因为只需要确定当前的开始时间比记录的结束时间大,那么就不需要增加一个老师。heapq主要是heapq.h原创 2021-05-30 13:13:41 · 452 阅读 · 0 评论 -
未排序数组中累加和为给定值的最长子数组的长度
好的解法其实是O(N),通过字典记录已经存在的长度,如果当前长度减去已经存在的长度是k,那么其实是说明从记录点后面开始到当前位置的和就是K。class Solution: def maxlenEqualK(self , arr , k ): # write code here n = len(arr) res1 = 0 max_length = 0 for i in range(n): if .原创 2021-05-29 17:25:15 · 78 阅读 · 0 评论 -
字符串变形
时间复杂度O(N)class Solution: def trans(self, s, n): # write code here result = "" sub = "" for i in range(n-1, -1, -1): if s[i] != " ": if ord(s[i]) < ord("a"): sub = chr(.原创 2021-05-25 14:49:12 · 109 阅读 · 0 评论 -
升序数组转化为平衡二叉搜索树
class Solution: def sortedArrayToBST(self , num ): # write code here # 中序遍历转层序遍历 # 平衡指的是任意节点的子树高度差小于等于1 # 只需返回root就行了,不需要参数传递root. def rebuild(left, right): if left > right: return.原创 2021-05-24 08:03:18 · 139 阅读 · 0 评论 -
旋转数组
class Solution: def minNumberInRotateArray(self, rotateArray): if not rotateArray: return 0 left = 0 right = len(rotateArray) - 1 while left < right: mid = (left + right)//2 if rot.原创 2021-05-22 11:42:39 · 60 阅读 · 0 评论 -
最长重复子串
这道题如果使用下面的O(NNN)的时间复杂度的话,只能jawa或者C++才可以解决~python超时。class Solution {public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * @param a string字符串 待计算字符串 * @return int整型 */ // 这个部分可是错漏百出啊~~~判断是否是对称的 注意起点,终点是变化的 bool is_sy.原创 2021-05-16 10:13:58 · 82 阅读 · 0 评论 -
矩阵的最长递增路径
这题的缺陷在变量没有看好,粗心!!!然后 注意边界 其实很简单~ 不需要回溯单纯回溯不能解决问题,会超时,因为最长的增长路径是唯一的,所以可以进行记录。下次遇到直接获取。就不用继续走。这样是不可能出现重复走一个格子的情况的,因为是递增的。能访问到的只可能越来越大。class Solution: def longestIncreasingPath(self, matrix: List[List[int]]) -> int: result = {} n.原创 2021-05-15 16:28:53 · 97 阅读 · 0 评论 -
分糖果-hard
这题确实比较绕,还是直接用O(N)的空间复杂度比较简单,O(1)比较难~使用tmp来间接保存的作用时可以随时检查是否原本已经满足比小的大了~而不是在逆向的时候,盲目加。class Solution: def candy(self , arr ): if not arr: return 0 if len(arr) == 1: return 1 tmp = [1] * len(arr)原创 2021-05-15 14:18:36 · 62 阅读 · 0 评论 -
动态规划-最大的正方形
i j 表示正方形的右下角的坐标 === >dp[i][j]代表的是正方形的边长。其实画图可以看出,这个边长取决于min(dp[i-1][j], dp[i-1][j-1], dp[i][j-1]), min的话,在min的基础上+1,目前的坐标点表示的就是正方形。class Solution: def solve(self , matrix ): # write code here n = len(matrix) m = len(matri.原创 2021-05-13 13:59:00 · 90 阅读 · 0 评论 -
合并二叉树
class Solution: def mergeTrees(self , t1 , t2 ): # write code here if not t1: return t2 if not t2: return t1 first = TreeNode(0) first.left = t1 left = 1 right = 1 .原创 2021-05-13 09:00:52 · 60 阅读 · 0 评论 -
旋转数组
不允许使用另外的数组class Solution: def solve(self , n , m , a ): # write code here """ 不符合,不允许使用另外的数组 m = m % n return a[(n-m)::] + a[0:(n-m)] """ m = m % n def reverse(n, m, s): whil.原创 2021-05-12 15:53:22 · 53 阅读 · 0 评论 -
三个数的最大乘积
其实不需要排序class Solution: def solve(self , A ): # write code here #其实就是找到两个相乘最大的正数和一个没用到的最小的正数;# 或者是相乘最小的负数和一个最小的没用到的负数 # 那其实就是全部相乘后排序 if len(A) < 3: return 0 A = sorted(A) .原创 2021-05-12 12:32:05 · 97 阅读 · 0 评论 -
resnet网络结构图
很重要,单独放原创 2021-05-04 16:18:58 · 1704 阅读 · 0 评论 -
图:邻接矩阵和邻接表
邻接矩阵的作用就是可以记录边与边之间的关系,如果是无向图那么矩阵存储的就是顶点的度;如果是有向图那么存储的就是出度。邻接矩阵的优点是可以快速达到两点之间边的关系,但是对于图中有多少条边,确定需要较多的时间代价。邻接表是顺序分配与链式分配相结合的存储方法。共有n个顶点,对每个顶点建立一个单链表,再把单链表都序号组合起来,就形成了邻接表。...原创 2021-04-20 16:22:47 · 1253 阅读 · 0 评论 -
矩阵元素查找
这个题说简单也很简单,主要还是思路,不然确实很难写~~如果从做左上角或者右下角开始遍历,需要考虑两种情况,很麻烦。如果是从右上角或者左下角开始遍历,就比较简单,只需要考虑一种情况。class Solution: def findElement(self, mat, n, m, x): res1 = 0 res2 = m-1 while res1 < n and res2 >= 0: if mat[res1][r原创 2021-04-19 14:05:28 · 65 阅读 · 0 评论 -
字典树 tries
字典树:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。1 有一个1G大小的一个文件,里面每一行是一个词,词的大小不超过16字节,内存限制大小是1M。返回频数最高的100个词。2 1000万字符串,其中有些是重复的,需要把重复的全部去掉,保留没有重复的字符串。请怎么设计和实现?3 一个文本文件,大约有一万行,每行一个词,要求统计出其中最频繁出现的前10个词,请给出思想,给出时间复杂度分析。Trie的核心思想是空间换时间,利用字符串的公共前缀来降低查询时间的开销原创 2021-04-19 09:10:39 · 170 阅读 · 0 评论 -
空间复杂度
首先要明确一个概念,变量的内存分配发生在定义的时候 忽略常数,用O(1)表示递归算法的空间复杂度=递归深度N*每次递归所要的辅助空间DFS和BFS时间复杂度:O(n)因为这是树 遍历,我们必须触摸每个节点,使这个O(n),其中n是树中的节点数。BFS空间复杂度:O(n)BFS必须至少存储队列中整个树的级别(样本 队列实施)。使用完美的完全平衡二叉树,这将是(n / 2 + 1)个节点(最后一个级别)。 最佳案例 (在此上下文中),树严重不平衡,每层只包含1个元素,空间复杂度为O(1)。 最坏原创 2021-04-18 09:17:19 · 131 阅读 · 0 评论 -
不相邻最大子序列和
# dp[i]代表前i个的最大自序和# dp[i] = max(d[i-1], dp[i-2] + array[i])class Solution: def subsequence(self , n , array ): if not array: return 0 dp = [0]*(n+1) dp[0] = 0 dp[1] = max(dp[0], array[0]) for i in .原创 2021-04-15 20:46:36 · 96 阅读 · 0 评论 -
KMP-labuladong笔记
参考 https://mp.weixin.qq.com/s/r9pbkMyFyMAvmkf4QnL-1g模式串pat,文本串txt,KMP 算法是在txt中查找子串pat,如果存在,返回这个子串的起始索引,否则返回 -1。KMP 算法永不回退txt的指针i,不走回头路(不会重复扫描txt),而是借助dp数组中储存的信息把pat移到正确的位置继续匹配,时间复杂度只需 O(N),用空间换时间,所以我认为它是一种动态规划算法。计算这个dp数组,只和pat串有关。意思是说,只要给我个pat,我就能通过这个模式转载 2021-04-11 20:59:57 · 285 阅读 · 0 评论