题目 | 知识点 | 笔记 |
J27 力扣509 |
斐波那契数列 力扣斐波那契数 |
递归方法会超时,采用循环方法 |
JZ8 跳台阶 | 跳台阶 | 和J27思路一样 |
JZ9 跳台阶扩展问题 | 变态跳台阶 | 和J27,JZ8思路一样,循环,但是找规律更简单 |
JZ10 矩形覆盖 | 矩形覆盖 | |
数组 |
1.纯数组操作2.有序的用二分法.后面单独出二分法 |
|
JZ1 二维数组中的查找 | 二维数组中俄查找 | 有三种方法,直接变成一维数组,一种是In在不在, 还有一种比较二维数组。 |
JZ2 替换空格 | 替换空格 | 有两种,一种用列表实现,列表变字符串‘ ’.join(列表) 第二种直接采用字符串replace(原来,更换后的内容) |
JZ6 旋转数组的最小数字 | 旋转数组中的最小数字 | 有两种,一是排序直接找。二是二分法,利用中间值减去左边的绝对值和减去右边的绝对值进行对比,这种感觉不太好 |
JZ13 调整数组顺序使奇数位于偶数前面 | 调整数组顺序使奇数位于偶数前面 | 数组简单算法 |
JZ33 丑数 | 丑数 | 直接循环判断,时间不能通过 采用后面的数都是×2或者×3或者×5得到的,一直写出所有的丑数,然后把最后一个取出来即可 |
JZ64 滑动窗口的最大值 | 滑动窗口的最大值 | 主要是分清一共多少种可能 |
力扣485 | 最大连续1的个数 | b站数据结构1-【数组】代码文本 用count计数,当下一轮开始时重新计数,比较result和count的最大值. |
力扣283 | 移动0 | 只能在原数组上改变 |
力扣27 | 移除元素 | 可以使用和283题一样的思路 也可以快慢指针 |
栈 |
||
JZ20 包含min函数的栈 | 包含min函数的栈 | 不会实现一个栈的编写。 is not None也不等于什么都没有写True 这里判断空使用==[ ] or len()==0 |
JZ21 栈的压入、弹出序列 | 栈的压入、弹出序列 | while循环那里不好想 |
力扣20 | 有效的括号 | b站数据结构4-【栈】代码文本 |
力扣496 | 下一个更大元素 | 有点难,栈不理解! 暴力法也不理解 |
队列 |
||
933 | 最近的请求次数 | b站数据结构3-【队列】代码文本 虽然创建用deque,但是用起来和数组一样。 |
链表 |
第一种——双指针的快慢指针来解决:(找节点)1.一个快一个慢,距离间隔多少2.两个指针的移动速度第二种——递归(链表相关) |
|
JZ3 从尾到头打印链表 | 从尾到头打印链表 | 采用数组的insert(0,值),这样就每次往数组的头那里插入一个值,即实现了倒着排序 |
JZ14 链表中倒数最后k个结点 力扣19 |
链表中倒数最后k个节点 力扣删除链表倒数第N个节点 |
使用快慢指针,让快指针先走k步,然后再同时走。 一个是判断fast==None,一个是fast.next为none。我怀疑是fast==none意思是长度小于fast先走的步数。这个是要找到某一个,即找到就行。 fast.next是判断到头了,倒数第n个节点即为第一个。因为要删除某个节点,所以必须考虑next节点,当前节点没法去掉。这个也不需要考虑长度问题。 |
JZ15 反转链表 力扣92 |
反转链表 3种情况: 1.反转整个链表 2.反转前n个节点 3.反转中间的一部分链表力扣92反转链表2 |
两种方法: 1.三个指针循环 2.递归 |
JZ16 合并两个排序的链表 | 合并两个排序的链表 | 递归 |
JZ25 复杂链表的复制 | 复杂链表的复制 | import copy copy.deepcopy(值) 深拷贝:如果b复制了A,A改变时B改变了就是浅拷贝,B没改就是深拷贝 |
JZ36 两个链表的第一个公共结点 | 两个链表的第一个公共点 | 需要判断链表的长度,然后让长链表的长度先走两个链表相差的长度的步数。然后一起走,当长的走到头的时候,短的正好走到公共节点那里。 |
JZ55 链表中环的入口结点 | 链表中环的入口节点 | 快慢指针,一个走两步,一个走一步,当两个相遇的时候,退出循环。然后让慢的到头部,同时走,再次相遇的时候即为环的节点。 |
JZ56 删除链表中重复的结点 力扣83 |
删除链表中的重复的节点 力扣删除排序链表中的重复元素 |
两道题不一样,一个是留下一个重复元素,另一个是只要有重复的就删掉 |
力扣203 | 力扣移除链表元素 | 一个是快慢指针(常用) 一个是递归。 |
力扣328 | 力扣奇偶链表 | 纯链表编程,注意奇数后面要连上偶数的头,要多一个指针放在头那里不要变 |
JZ46 孩子们的游戏(圆圈中最后剩下的数) | 孩子们的游戏(圆圈中最后剩下的数) | 自己构造环形链表 其实没太懂 |
哈希表 |
解决的问题是——所有和次数有关的 |
|
JZ28 数组中出现次数超过一半的数字 | 数组中出现次数超过一半的数字 | 字典的键存放数组的值,字典的值存放数组值出现的次数 |
JZ40 数组中只出现一次的两个数字 | 数组中只出现一次的两次数字 | 字典遍历key |
JZ50 数组中重复的数字 | 数组中重复的数字 | 哈希表找最大的key |
JZ37 数字在升序数组中出现的次数 | 数组在升序数组中出现的次数 | counts.get(k,default=null)。等价于counts[k] 如果get的键不在里面,则返回null。第二个会返回0. |
力扣389 | 力扣找不同 | collections.Counter(s)可以统计s里面每个值的次数,可以直接使用。和for循环统计一样 |
力扣169 | 力扣多数元素 | counts=collections.Counter(nums) return max(counts.keys(),key=counts.get) |
力扣692 | 力扣前k个高频单词 | 双关键词排序, sorted 方法默认正序排列 当词频相同时,用第二个参数 word 进行排序,即字母正序排列 res = sorted(hash, key=lambda word:(-hash[word], word)) return res[:k] |
哈希表hashtable:存放key-value,非线程安全 哈希映射hashmap:存放key-vaule,线程安全 哈希集合hashset:存放key,非重复值 |
||
树 |
DFSBFS |
|
JZ4 重建二叉树 力扣105 力扣106 |
重建二叉树 力扣从前序与中序遍历序列构造二叉树 力扣从中序与后序遍历序列构造二叉树 |
|
JZ17 树的子结构 | 树的子结构 | 整体分三步,先判断root是不是相等,在判断left是不是相等,最后判断right是不是相等 判断相等需要自己写一个函数,也是分三步,判断root left right都相等就返回true ,否则返回false |
JZ18 二叉树的镜像 力扣226 |
二叉树的镜像 力扣翻转二叉树 |
递归 后序 |
JZ22 从上往下打印二叉树 | 从上往下打印二叉树 | BFS,利用队列实现 |
JZ24 二叉树中和为某一值的路径 力扣112 |
二叉树中和为某一值的路径 力扣路径之和 |
DFS |
JZ57 二叉树的下一个结点 | 二叉树的下一个节点 | 分情况讨论 |
JZ58 对称的二叉树 力扣101 |
对称的二叉树 对称二叉树 |
递归 |
JZ59 按之字形顺序打印二叉树 | 按之字形顺序打印二叉树 | 一般添加根节点时,添加root 但是其他节点时,用left.val |
JZ61 序列化二叉树 | 序列化二叉树 | |
力扣144 | 二叉树的前序遍历 | DFS自己定义,或者栈实现 |
力扣94 | 二叉树的中序遍历 | DFS |
力扣145 | 二叉树的后序遍历 | DFS |
力扣102 JZ60 把二叉树打印成多行 |
二叉树的层序遍历 把二叉树打印成多行 |
BFS 和JZ59差不多 |
力扣236 | 二叉树的最近公共祖先 | 递归 不明白为什么p或者q只有一个位于以root为根的树中,函数会返回该节点???什么叫子树不存在 |
力扣116 | 填充每个节点的下一个右侧节点指针 | BFS ??? |
力扣114 | 二叉树展开为链表 | 后序遍历+递归 |
力扣654 | 最大二叉树 | 递归 |
力扣652 | 寻找重复的子树 | 没懂?序列化为字符串 |
二叉搜索树:左边的树的子节点都小于根节点,右边的树的子节点都大于根节点每一个子树也是一个二叉搜索树。空树也是二叉搜索树。 |
||
JZ23 二叉搜索树的后序遍历序列 | 二叉搜索树的后序遍历序列 | 记住:根节点的取值一般要删去,和其他数组单纯取值不一样 |
JZ62 二叉搜索树的第k个结点 力扣230 |
二叉搜索树的第K个节点 力扣二叉搜索树中第k个节点 |
中序遍历第k个 力扣和牛客不一样,对于根节点的添加,牛客是root,但是力扣是root.val |
JZ26 二叉搜索树与双向链表 | 二叉搜索树与双向链表 | 中序遍历 对于左子树要寻找他的最右边与根节点连接起来,对于右子树不需要此操作 |
堆 |
最大堆最小堆也会有其他解决方法,比如哈希表或者数组, 解决的问题是:前k或者第k个值 |
|
JZ29 最小的K个数 | 最小的k个数 | 最小k用最大堆,取-1 |
力扣215 | 数组中的第k个最大元素 | 最大k用最小堆,堆顶的为第k大 |
字符串 |
||
JZ34 第一个只出现一次的字符 | 第一个只出现一次的字符 | 其实用到的是哈希表 |
JZ43 左旋转字符串 | 左旋转字符串 | 和数组一样,采用拼接+的方式 |
JZ44 翻转单词序列 | 翻转单词序列 | 按空格切分字符串为数组,然后翻转数字,最后用空格拼接 |
位运算 |
||
JZ11 二进制中1的个数 | 二进制中1的个数 | 有三种方法,首先知道在python中负数怎么表示,用n&0xffffffff 第一种换成字符串,判断当前位是不是'1'.疑问:数字为什么要变成字符串呢???? 第二种是1<表示1左移多少位.即第i位为1.再与n与的话,可以看出n的第i位是不是1 第三种直接用n&(n-1),做几次与运算,即有几个1 |
JZ48 不用加减乘除做加法 | 不用加减乘除做加法 | 没懂???? 可以使用sum([]) |
二分法 |
升序有三种情况:1.基本二分,找到就返回,找不到就返回-1l=0,r=len()-1while l<=r:r=mid-1,l=mid+12.寻找左边界。【left,right),l=0,r=len()while l r=mid,l=mid+1,return lerf3.寻找右边界l=0,r=len()while l r=mid,l=mid+1,return lerf-1 |
|
力扣704 | 力扣二分查找 | 普通 |
力扣35 | 力扣搜索插入位置 | 可以普通,主要是看找不到的时候返回什么 |
力扣162 | 力扣寻找峰值 | 不属于,但是用了二分法,不是递增的。 |
力扣74 | 二维数组中的查找,变成一维数组直接用In或者二分法再比较 |
|
回溯法 |
解决穷举的问题for循环里面的递归,在递归调用之前做选择,在递归调用之后撤销选择。 |
|
力扣22 | 括号生成 | dfs+剪枝 剪枝一般采用if判断不符合的条件 |
力扣46 | 全排列 | 数组无重复数字,在整个数组里面做选择,回溯递归的时候每次都从0开始 |
力扣47 | 全排列2 | 数组有重复数字,没看懂??? |
数学 |
||
JZ12 数值的整数次方 | 数值的整数次方 | |