女朋友没有时间刷剑指offer,并且书有点厚,还都是c++写的,所以写了一份浓缩的python版的剑指offer,七夕节礼物。大多数都是最优解,不是最优解的几个题是因为最优解不好记,次优的容易记。
全手打@转载请注明出处
选取从右上角开始或者左上角开始,必须是一个方向变大,一个方向变小。
在申请一个比原字符串长“空格数*2”长度空间,然后倒着复制,遇到空格就往里加 0 、2、 %。
方法一:很简单
方法二:递归本质就是个栈,所以递归到头之后回来的过程中,将值加入列表中。
思想就两个栈,负负得正,总是往第一个栈入队,第二个栈用来出队,第二个栈空的时候,把第一个栈的数全拿过来
斐波那契[0,1,1,2,3…] k>=2时,再执行k-1次加和就是第n项
可以从前面任意台阶过来,所有等于前面所有方法总和 + 一步跳过来这种方法
题不难,细节比较重要,主要考边界条件,并且有优化空间(以平方形式乘)
如图,想删h,则将i.val赋值给h,h.next指向j,再删除i节点就行了
1.若不需要保证相对位置:
2.若保留相对位置:
新建一个数组,遍历,奇数放前面 或者
冒泡思想,相邻两个前是偶数后是奇数就交换
先让第一个指针走k步,然后第二个指针和第一个一起走到头,第一个指针就指向倒数第k个,
题主要考察三个边界条件:
1.k=0 2.长度不够k 3.输入的是空链表
只需要考虑一下,如果一个链表遍历完了,另一个直接接在新链表后面
分两步:1.树1中找到树2的根节点
2.找到之后,对比左右子树是否相等
比较简单,就判断下pop出去的数 是不是在minStack里就行
用一个栈和一个队列来模拟,如果栈顶和队列头部元素相同,同时pop掉,若最后栈是空的代表对
递归的判断 是否前面的都比根节点小,后部分比根节点大,index记录的是左右子树临界点,再分别判断左右子树
二叉搜索树是有序的,只要中序遍历,就是一个从小到大有序的序列
1.双向链表表头一定是最左的节点
2. 表尾不断以中序遍历方式向右移动:
和遍历到的节点 相互指向,然后 将表尾更新到当前节点 循环
排序之后,中间的数就是答案,但是时间复杂度是 nlogn,面试时可以先说出来,然后在改
时间复杂度n的方法:
初始化一个count result设置为数组第一个,如果碰到相同的,+1,否则-1,当减到0时候更换result为当前的,count归为1,最后记得验证一下 还是o(n)
top k问题,
两种:一种直接全排序,去前k个 ,时间复杂度nlogn
另一种最小堆,维护k大小的最小堆,时间复杂度 nlogk
##########################
记住两个答案,脱口而出最low的 然后再假装思考,想出来最优的 ,比较真实,不像做过这道题的样
粗暴: 牛客超时了
正常;用数组记录得到的所有丑数,每次用之前的丑数 求出来个比当前仅大一点点的丑数
等等补充
一种 o(n) 可以用字典计数
另一种logn ,用两次二分查找 分别找出第一次出现的k 和最后一次出现的K, 算距离,注意考虑不存在k的情况
在上道题的基础上,递归的判断 是否左右子树的深度绝对值差都不大于1
就不能用字典计数了,利用上一题思想,将数组分为两个,每一个都包含一个只出现一次的数字,怎么分呢?
怎么知道异或结果中1的位置呢?
那么怎么判断倒数第二位是不是1呢?
整体程序:
将每个单词的每个字母合并为一个字符,然后翻转整个单词序列,这样可以保证每个单词顺序没变
两种方法:
1.简单 但是low一点:
2.看着高端的解法
先将整个字符串翻转,这样需要左移的k位都跑最后去了, 然后分别对两部分翻转就恢复了
abcXYZ -> ZYXcba ->XYZ + abc
扔第n个骰子的时候的sum,只能由第n-1个骰子时候的值得来
f(n,s)=f(n-1,s-1)+f(n-1,s-2)+f(n-1,s-3)+f(n-1,s-4)+f(n-1,s-5)+f(n-1,s-6) ,
第一种 return sum(a,b),面试先说,肯定不合格
第二种死记硬背,不会
边界条件是考察点
“+” “-” 字母 空的这四种
不用int 可以用 ord(s) - ord(“0”)来得单个数字
1.如果是二叉搜索树:如果两节点比父节点大,在右子树中找,如果一个比当前节点大,一个比当前节点小,则当前节点就是公共祖先,
2.如果有指向父节点的指针,则每个叶子节点都是一个链表的表头,找出含有两节点的两个链表,转化为求两链表的公共节点
3.如果只是普通的二叉树
如果左右子树各有一个目标节点,则返回当前节点
如果左面没有,那就递归右子树,反之