剑指offer笔记(五) 第33题至第39题
前言
这次主要记录剑指offer的7道题,主要使用的语言是python,下面将对这7道题的一些感悟和知识点进行汇总!
提示:以下是本篇文章正文内容,下面案例可供参考 截图来源于LeetCode
一、JZ33 二叉搜索树的后序遍历序列
见树,用递归很方便!二叉搜索树的左子树 < 右子树,很棒的特性,一定要用上,后序遍历的顺序是:左右根,因此左 < 右 ,代码中两个while分别用来寻找两个区间的边界:
- index = i 以及 right = index,用来寻找verify(i,right-1)的右边界以及verify(right,j-1)的左边界;
- index == j 用来判断是否已经递归是否已经达到给定数组的右边界。
以下为程序源码:
二、JZ34 二叉树中和为某一值的路径
递归前序遍历便可以,从根节点出发将减去根节点的target与对应的节点进行再次递归,符合要求的路径,即target == 0且到达叶子节点,记录下该路径。
以下为程序源码
三、JZ35 复杂链表的复制
为完成很快地复制操作,可以第一步在每两个节点之间插入一个新的节点,在完成random指针后,使用tmp间隔的将两个链表连起来。这道题并不难,可以参考代码动手画一下。
以下为程序源码:
四、JZ36 二叉搜索树与双向链表
代码很好理解,还是需要动手画一下连接方式,双向链表不动手画一画很难理解,考虑到二叉树搜索树的特性,这里使用了递归方法的前序遍历。
以下为程序源码:
五、JZ37 序列化二叉树
不多说了,看代码,递归方式的前序遍历,很容易理解。
以下为程序源码:
六、JZ38 字符串的排列
这道题非常的典型的非重复排列,可以直接背诵记忆,分以下几步进行:
- 确定一共需要交换的总次数,即 len(s)-1;
- 记录重复的字符串用于后续的排重,使用seen = set()没记录重复的字符;
- 依次遍历,即range(x,len(s)),每次交换完成后,x += 1;
- 注意每次完成交换和x的加一操作后,切记还原原数组的字符串顺序。
OK,按照这四步记忆,就成。
以下为程序源码:
七、JZ39 数组中出现次数超过一半的数字
摩尔投票,时间复杂度为O(n),很牛的一个方法,需要设定rate变量,两个if:
- 第一个if,用来给ans赋值;
- 第二个if,用来加减分数,i == ans,rate += 1;反之,rate -= 1.
以下为程序源码:
八、总结
这7道题,还成。链表的连接果然头疼啊!不知道不参照答案自己能不能写出来,哈哈!这其中一些排列、查数、链表复制、二叉树的后序遍历以及路径求和,这些题都非常的典型,有些需要着重记忆,如排列和查重,有些则需要记忆其中的主要部分,后续会对二叉树的前中后、层序等排列做一个梳理,对于链表也会进行一个大致的梳理。这部分内容本身就抽象不容易搞懂,需要花些功夫。