牛客网-剑指offer刷题

python刷题笔记基础

题目 知识点 笔记

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 方法默认正序排列
第一个参数 -hash[word] 即单词出现次数的相反数
当我们对其进行正序排列时,相当于词频的倒序排列

当词频相同时,用第二个参数 word 进行排序,即字母正序排列

res = sorted(hash, key=lambda word:(-hash[word], word))

return res[:k]

哈希表hashtable:存放key-value,非线程安全

哈希映射hashmap:存放key-vaule,线程安全

哈希集合hashset:存放key,非重复值

DFS

BFS

JZ4 重建二叉树

力扣105

力扣106

重建二叉树

力扣从前序与中序遍历序列构造二叉树

力扣从中序与后序遍历序列构造二叉树

  1. 先序遍历序列第一个元素为根pre[0]
  2. 找到根元素在中序遍历序列中的位置index
  3. 计算出先序和中序遍历序列中左子树和右子树遍历序列的范围
  4. 递归的计算左右子树
  • 注意:判断为空的时候是用not x还是x==None??????还不知道
  • x==None用的多
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<<i表示1左移多少位.即第i位为1.再与n的话,可以看出n的第i位是不是1

第三种直接用n&(n-1),做几次与运算,即有几个1

JZ48 不用加减乘除做加法 不用加减乘除做加法

没懂????

可以使用sum([])

二分法

升序

有三种情况:

1.基本二分,找到就返回,找不到就返回-1

l=0,r=len()-1

while l<=r:

r=mid-1,l=mid+1

2.寻找左边界。【left,right),

l=0,r=len()

while l<r:

r=mid,l=mid+1,return lerf

3.寻找右边界

l=0,r=len()

while l<r:

r=mid,l=mid+1,return lerf-1

力扣704 力扣二分查找 普通
力扣35 力扣搜索插入位置 可以普通,主要是看找不到的时候返回什么
力扣162 力扣寻找峰值 不属于,但是用了二分法,不是递增的。
力扣74 二维数组中的查找,变成一维数组直接用In或者二分法再比较一种是二分法,(不能使用,不是排序的)

回溯法

解决穷举的问题

for循环里面的递归,在递归调用之前做选择,在递归调用之后撤销选择。

力扣22 括号生成

dfs+剪枝

剪枝一般采用if判断不符合的条件

力扣46 全排列 数组无重复数字,在整个数组里面做选择,回溯递归的时候每次都从0开始
力扣47 全排列2 数组有重复数字,没看懂???

数学

JZ12 数值的整数次方 数值的整数次方

猜你喜欢

转载自blog.csdn.net/weixin_45823221/article/details/119678168