#刷剑指offer,记录一下
问题2:圆圈中最后剩下的数
思路1:使用list模拟循环链表,用cur作为指向list的下标位置。
当cur移到list末尾直接指向list头部,当删除一个数后list的长度和cur的值相等则cur指向0
思路2:递归或循环 f(n)=(f(n-1)+m)%n
问题6:电话号码的规范
思路:回溯,暴力解法
问题3:数组中出现次数过半的数字
思路1:使用字典,记录每个数组出现的次数dic[num],判断是否大于一半
时间复杂度O(n),空间复杂度O(n)
思路2:每次把两个不同的数取出,剩下最后的数判断其个数是否大于一半。
问题5:数组中出现次数为1的两个数
思路1:字典 多加空间复杂度O(n)
思路2:运用异或异或,1.a^b^c=c^b^a 满足交换律 2.两个相同数异或值为0
因此,在找到不同的两个数的异或值之后,判断他哪一位不同,就可以把这个数列分为
各包含一个不同数的数列,再使用异或 得到那个数
问题10:第一个出现一次的字符串
思路1:字典存储,空间复杂度O(2n)
思路2:Hash映射
问题:栈的压入,弹出序列
思路:创建辅助栈 模拟出栈顺序,当辅助栈的头节点与入栈的数值相同时就辅助栈进行出栈操作
最后判断是否辅助栈是否为空
##查找和排序
问题1:旋转数组的最小问题
思路1:暴力法 遍历 时间复杂度O(n)
思路2:二分法 区别于传统二分法 它分两段进行排序,目标保证最小值位于递增或递减数组中即可
二分法时间复杂度 怎么算O(log(n))
问题6,7,8,9:回溯小结
步骤:1.画出大概的树图,了解减枝条件,递归结束条件
2.进行回溯 伪代码如下
def dps(args):
if 终止条件:
结果
for elem in list1():
做选择
dps
撤销选择
思考:对于剪枝的若干总结
1.解集不包含重复组合,且输入为有序数组 for i in range(index,len)
2.全排列是最简单的组合
3.输入包含重复数字,应先排序 剪枝条件 if i>0 and array[i]==array[i-1]
问题15-20:小结
思路:对于二维数组回溯,
1.首先,回溯对于这个点走前后左右的选择
2.因此,两个for 循环遍历每个点
3.在回溯中设置终止条件
问题7:链表中环的入口节点
思路1:增加空间复杂度,把所有元素放入空列表,如果有相同则返回
思路2:使用两个指针,一个slow走1,fast走2
##二进制
问题1:二进制中1的个数
思路1:注意负数 用python不处理会报错(-1&0xFFFFFFFF),
转化为二进制,如果等于1就count+1
思路2:把数与1(1进行左移)进行位与操作,统计count
问题2:不用加减乘除,实现加法操作 思路:两个数异或:相当于每一位相加,而不考虑进位;两个数相与,并左移一位:相当于求得进位;将上述两步的结果相加 注意:当输出为负数的时候 进行~(a&0xFFFFFFFF)操作
##数学逻辑
问题1:从n当中数1出现的次数
思路1:暴力法,存储每个数,需要花费大量的存储空间
思路2:递归法,f(n)=f(n-1)+count(n),count(n)为n中1的个数
思路3:1 取第 i 位左边(高位)的数字,乘以 10 i−1 ,得到基础值 a 。
2.取第 i 位数字,计算修正值: 如果大于 X,则结果为 a+ 10 i−1 。
如果小于 X,则结果为 a 。
如果等 X,则取第 i 位右边(低位)数字,设为 b ,最后结果为 a+b+1 。
问题2:数的幂方运算
思路快速求幂算法,把幂次方分解为若干个平方和相乘
##树
二叉树思路主要是遍历,找到遍历结束的点。
问题2:重建二叉树,已知二叉树前序和中序,求原来二叉树
思路:遍历思想,前序第一个节点是根节点,中序遍历根节点左边是左子树,右边是右子树
,同理,前序遍历的左子树和右子树也能找到,在再左子树和右子树里面进行遍历
问题4:树的镜像
思路:我们或许还记得递归的终极思想是数学归纳法,我们思考递归的时候一定不要去一步一步看它执行了啥,只会更绕。
我们牢牢记住,思考的方式是我们首先假设子问题都已经完美处理,我只需要处理一下最终的问题即可,
子问题的处理方式与最终那个处理方式一样,但是问题规模一定要以1的进制缩小。
最后给一个递归出口条件即可。
对于本题,首先假设root的左右子树已经都处理好了,即左子树自身已经镜像了,
右子树自身也镜像了,那么最后一步就是交换左右子树,问题解决。
所以我只需要将root.left和root.right交换即可。
下面进入递归,就是处理子问题。
子问题的处理方式与root一样,只是要缩小问题规模,
所以只需要考虑root.left是什么情况,root.right是什么情况即可。
问题6:二叉树后续遍历
思路:后序遍历 的序列中,最后一个数字是树的根节点 ,
数组中前面的数字可以分为两部分:第一部分是左子树节点 的值,
都比根节点的值小;第二部分 是右子树 节点的值,都比 根 节点 的值大,
后面用递归分别判断前后两部分 是否 符合以上原则
问题9:二叉树的下一个节点
思路1:存储一下中序遍历,然后找出pNode的下一个值
思路2:根据中序遍历的性质
(1)若该节点存在右子树:则下一个节点为右子树最左子节点
(2) 若该节点不存在右子树:这时分两种情况:
2.1该节点为父节点的左子节点,则下一个节点为其父节点
2.2该节点为父节点的右子节点,则沿着父节点向上遍历,知道找到一个节点的父节点的左子节点为该节点,则该节点的父节点下一个节点
问题20:路劲总和3
思路:两次遍历