/leetcode

Primary LanguagePython

#刷剑指offer,记录一下

##斐波那契数列
问题1:斐波那契数列,青蛙跳
思路1:递归 时间复杂度为O(2^n)不可取
思路2:循环 时间复杂度为O(n)

问题2:圆圈中最后剩下的数 思路1:使用list模拟循环链表,用cur作为指向list的下标位置。 当cur移到list末尾直接指向list头部,当删除一个数后list的长度和cur的值相等则cur指向0
思路2:递归或循环 f(n)=(f(n-1)+m)%n

问题4:矩形覆盖
思路:f(n)=f(n-1)+f(n-2)

问题5:字符串的全排列
思路: TO DO

问题6:电话号码的规范
思路:回溯,暴力解法

##数组
问题1:二维数组搜索
思路1:暴力法 不考虑题目给的条件,从左至右,从上至下,顺序遍历,复杂度O(mn)
思路2:考虑 题目条件 从左下角开始搜索

问题2:替换空格
思路1:作弊法 调用函数replace
思路2:替换法 引入新的列表 遇到空格替换 否则不替换

问题3:数组中出现次数过半的数字
思路1:使用字典,记录每个数组出现的次数dic[num],判断是否大于一半 时间复杂度O(n),空间复杂度O(n)
思路2:每次把两个不同的数取出,剩下最后的数判断其个数是否大于一半。

问题4:寻找第N个丑数(公因子只有2,3,5)
思路1:设置是否为丑数条件,循环N次。
思路2:设置3个指针,当选择某个指针时(最小的数),指针向前移动一位

问题5:数组中出现次数为1的两个数
思路1:字典 多加空间复杂度O(n)
思路2:运用异或异或,1.a^b^c=c^b^a 满足交换律 2.两个相同数异或值为0 因此,在找到不同的两个数的异或值之后,判断他哪一位不同,就可以把这个数列分为 各包含一个不同数的数列,再使用异或 得到那个数

问题6:最小的K个数
思路1:排序,找前k个数
思路2:最大堆 1.完全二叉树 2.根节点大于左右节点 时间复杂度O(logn),空间复杂度O(n)
创建最大堆,后续的数进行插入即可

问题7:数据流中的中位数
思路1:维护一个有序数组
思路2:堆排序 复杂度由O(n)变为O(log(n))

问题8:;连续子向量最大和
思路:记录当前最大值,时间复杂度O(n)

问题9:从外先里顺时针打印矩阵 思路:模拟模仿逆时针旋转

问题10:第一个出现一次的字符串
思路1:字典存储,空间复杂度O(2n)
思路2:Hash映射

##栈
问题:两个栈表示一个队列的进与出
思路:进:直接append 出:注意判断stackB是否为空 把stackA入栈到stackB,B再出栈

问题:包含min函数的栈
思路:创建辅助栈 用辅助栈存放较小的元素

问题:栈的压入,弹出序列
思路:创建辅助栈 模拟出栈顺序,当辅助栈的头节点与入栈的数值相同时就辅助栈进行出栈操作 最后判断是否辅助栈是否为空

##查找和排序
问题1:旋转数组的最小问题
思路1:暴力法 遍历 时间复杂度O(n)
思路2:二分法 区别于传统二分法 它分两段进行排序,目标保证最小值位于递增或递减数组中即可 二分法时间复杂度 怎么算O(log(n))

问题2:调整数组顺序使奇数排在偶数前面
思路:把奇数偶数拿出来,拼在一起

问题3:实现了希尔排序,归并排序和快速排序
思路:希尔排序,由间隔值,归并排序采用归并化简**,快排在归并排序的基础上增加了比较值

问题4:把数组排除最小的数
思路:自定义排序str(x1)+str(x2)

问题5:数组中的逆序对
思路:归并** 未完成 TO DO

问题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.在回溯中设置终止条件

##链表
问题1:从尾到头打印链表
思路:从头到尾读取到列表,在reverse()

问题2:打印链表倒数第k个节点
思路1:从头到为打印,读取倒数第k个节点
思路2:设置两个指针p1,p2,p2先走k-1个单位,p1再走

问题3:反转链表
思路1:设置三个指针赋值
思路2:递归,没看懂

问题4:合并两个排序链表
思路1:设置四个指针,第一个为头指针,后三个一次后移即可
思路2:递归 妙啊

问题5:复制复杂链表
思路:复制节点插入原点后,复制random指针,拆分

问题6:输入两个链表,找出它们的第一个公共结点。
思路1:遍历两个链表 复杂度为O(mn)
思路2:寻找到两个链表的差值,让长的先走,在寻找公共节点,时间复杂度O(n)

问题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:数的幂方运算
思路快速求幂算法,把幂次方分解为若干个平方和相乘

##树
二叉树思路主要是遍历,找到遍历结束的点。

问题1:树的前中后遍历
思路1:递归
思路2:循环 直以后续遍历的循环

问题2:重建二叉树,已知二叉树前序和中序,求原来二叉树
思路:遍历**,前序第一个节点是根节点,中序遍历根节点左边是左子树,右边是右子树 ,同理,前序遍历的左子树和右子树也能找到,在再左子树和右子树里面进行遍历

问题3:树的子结构
思路:遍历,求每个节点相同

问题4:树的镜像
思路:我们或许还记得递归的终极**是数学归纳法,我们思考递归的时候一定不要去一步一步看它执行了啥,只会更绕。 我们牢牢记住,思考的方式是我们首先假设子问题都已经完美处理,我只需要处理一下最终的问题即可, 子问题的处理方式与最终那个处理方式一样,但是问题规模一定要以1的进制缩小。 最后给一个递归出口条件即可。
对于本题,首先假设root的左右子树已经都处理好了,即左子树自身已经镜像了, 右子树自身也镜像了,那么最后一步就是交换左右子树,问题解决。 所以我只需要将root.left和root.right交换即可。 下面进入递归,就是处理子问题。 子问题的处理方式与root一样,只是要缩小问题规模, 所以只需要考虑root.left是什么情况,root.right是什么情况即可。

问题5:从上往下打印二叉树
思路:广度优先,借助于一个列表实现

问题6:二叉树后续遍历
思路:后序遍历 的序列中,最后一个数字是树的根节点 , 数组中前面的数字可以分为两部分:第一部分是左子树节点 的值, 都比根节点的值小;第二部分 是右子树 节点的值,都比 根 节点 的值大, 后面用递归分别判断前后两部分 是否 符合以上原则

问题7:二叉树和为某一值的路径
思路1: DFS
思路2: DPS

问题8:二叉树与双节点列表
思路1:非递归,因为是搜索树,因此先求中序遍历,在改变指针
思路2:递归,B站老师讲的真的水

问题9:二叉树的下一个节点
思路1:存储一下中序遍历,然后找出pNode的下一个值
思路2:根据中序遍历的性质
(1)若该节点存在右子树:则下一个节点为右子树最左子节点
(2) 若该节点不存在右子树:这时分两种情况:
2.1该节点为父节点的左子节点,则下一个节点为其父节点
2.2该节点为父节点的右子节点,则沿着父节点向上遍历,知道找到一个节点的父节点的左子节点为该节点,则该节点的父节点下一个节点

问题10:对称的二叉树
思路:递归,看左右子树是否相等,循环也行

问题11:按照之字形打印二叉树
思路:新建两个列表存储不同打印顺序的值

问题12:从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行
思路:同11题

问题13:二叉搜索树第K小的节点
思路:二叉搜索树的中序遍历,就是排序好的队列

问题14:序列化二叉树
思路:前序遍历,反序列化注意递归

问题15:完全二叉树节点
思路1:广度优先,借助队列
思路2:利用满二叉树形状,判断深度,进行递归

问题16:平衡二叉树
思路

问题17:路径总和
思路: 访问每个字节点的时间复杂度O(n),空见复杂度O(logn)~O(n)

问题18:路径总和2
思路:递归,求更新状态

问题19:不同路径求和
思路:对于递归了解了一点,但是说不出来 mmp

问题20:路劲总和3
思路:两次遍历