剑指offer学习笔记(二)

来源:互联网 发布:外交官 知乎 编辑:程序博客网 时间:2024/06/04 17:45

第四章

面试题27:二叉树的镜像
——输入一个二叉树,输出它的镜像
解法:二叉树的镜像就是和原本的二叉树相反,则对调左右子树即可

面试题28:对称的二叉树
——输入一个二叉树,判断是否是对称的
解法:二叉树若是对称的,则二叉树和镜像是相等的,分别从左节点遍历二叉树和右节点遍历二叉树,若得到的序列相等,则是对称的
相关问题:
- LeetCode:Symmetric Tree

面试题29:顺时针打印矩阵
——输入一个指针,按照顺时针打印出来
解法:由于矩阵是一个矩形,所以左上角的每一个点可以看做是每圈的起点,每圈起点的XY坐标都加1,相应对称的右下角的点坐标减1,由此可以写代码实现
相关问题:逆时针打印矩阵

面试题30:包含min函数的栈
——实现一个栈的数据结构,使得min,push,pop的时间都是O(1)
解法:可以通过用两个栈实现,一个储存数据,一个储存最小数。第一次push的时候,两个栈同时插入数据。第二次之后,判断push的值是否小于min的栈顶元素,若小于,push该元素,反之push min的栈顶元素(这样可以防止min储存的最小数在数据栈的最小数被pop之前pop);
相关问题:
- LeetCode:Min Stack

面试题31:栈的压入,弹出序列
——输入两个序列,一个表示入栈顺序,一个表示出栈顺序,判断出栈顺序是否正确
解法:用一个栈储存入栈的序列,一个指针指向出栈的序列;向栈中push入栈序列中的数据,若栈顶元素等于指针所指的指,则pop,并且指针向前加1;如果一直没找到淡出的数据,弹出的序列就是错的

面试题32:从上下打印二叉树
——按照上到下,左到右的顺序输出二叉树
解法:利用队列的FIFO的性质,先存入根节点,然后弹出根节点,输出根节点,再判断是否有左右节点,插入队列,再反复之前的操作(1.分层打印则需要两个变量对该行输出节点数进行存储 2.Z型打印使用栈)

面试题33:二叉搜索树的后序遍历序列
——判断输入的序列是否是某二叉树的后续遍历结果
解法:在二叉搜索树中,左节点小于父节点,右节点大于父节点,在后序遍历中,最后一个值为根节点。根据这个性质可以找到序列中的左序列和右序列,再将子序列拆分成子序列来判断

面试题34:二叉树中和为某一值的路径
——输入二叉树和整数,输出二叉树中节点值等于整数的所有路径
解法:前序遍历二叉树,将节点值相加,存入vector中,如果大于就不继续遍历,等于就输出vector中的值

面试题35:复杂链表的复制
——实现一个函数复制一个复杂链表,节点除了next指针外,还有一个指向任意节点的sibling指针
解法:从头到尾遍历链表,在每个节点N后面插入他的复制节点N’,最后在从头开始删除原始节点

面试题36:二叉搜索树与双向链表
——输入一个二叉树,将其转换成双向链表,不能创建新节点,只能调整树的节点指针的指向
解法:中序遍历二叉树,左节点连接父节点,右节点连接父节点的父节点,最后一个节点连接第一个节点

面试题37:序列化二叉树
——实现两个函数,分别序列化二叉树和反序列化二叉树
解法:序列化二叉树:前序遍历二叉树,若节点存在便增加数据,不存在就用一个特殊符号代替
   反序列化二叉树:按照前序遍历的规则进行递归,节点存在就构造指针,节点为特殊符号就用nullptr
   
面试题38:字符串的排列
——输入字符串,得出他的全部排列
解法:将字符串分成两部分,先求第一个可能出现的字符,然后再判断第二部分,通过递归重复操作1,得到排列的字符串数组
相关问题:
- LeetCode:Subset
- LeetCode:Permutations

第五章

面试题39:数组中出现超过一半的数字
——数组中有一个数字出现的次数超过数组的一半,求该数字
解法1:通过二分法排序。如果一个数出现的次数超过一半,那么数组下标n/2处肯定为该数字
解法2:用2个变量保存数组数字和该数出现的次数,若下一个数不等于改数字,则次数减一,当次数等于一的时候,当前数字替换该数字,到最后一定是出现最多次数的数
相关问题:
- LeetCode:Majority Element

面试题40:最小的k个数
——输入n个整数,输出最小的k个数
解法1:由于是最小的k个数,取第k个数,其他的数一定在k的左右,对比k小的数进行排序
解法2:使用二叉排序树,先输入k个数,在之后输入的时候,若大于最大数,则抛弃;小于最大数的话,删除最大数,并且插入该数(这种解法适用于海量数据的情况)
相关问题:
- LeetCode:Top K Frequent Elements
- LeetCode:K-th Smallest in Lexicographical Order

面试题41:数据流中的中位数
——实现一个函数获取数据流中的中位数
解法:

面试题42:连续子数组的最大和
——输入一个整形数组,求数组的一个或多个连续整数组成的子数组的和的最大值
解法:
解法2:利用动态规划的思想,

面试题43:1~n整数中1出现的次数

面试题44:数字序列中的某一位的数字

面试题45:把数组排成最小的数

面试题46:把数字翻译成字符串
——给定一个数字,按照0-a,1-b的规则翻译成字符串,实现一个函数判断有多少种翻译的方法
解法:
相关问题:
- LeetCode:Integer to Roman
- LeetCode: Roman to Integer
- LeetCode:Excel Sheet Column Number
-
面试题47:礼物的最大价值

面试题48:最长不包含重复字符的子字符串

面试题49:丑数

相关问题:
LeetCode:Ugly Number

面试题50:第一个只出现一次的字符
——在字符串中寻找第一次只出现一次的字符
解法:使用hashmap,字符作为键值,出现次数作为value,第一次遍历之后得到每次字符出现多少次的hashmap,再进行第二次遍历,输出第一个value为1的字符

面试题51:数组中的逆序对

面试题52:两个链表的第一个公共节点
——给定两个链表,找出第一个相交的节点
解法:先遍历两个链表得出长度L1和L2,较长的链表先走|L1-L2|步,然后两个链表再一起走,就能得到第一个公共点

第6章

面试题53:在排序数组中查找数字

面试题54:二叉搜索树的第k大节点

面试题55:二叉树的深度
——输入二叉树的根节点,判断该二叉树的深度
解法1:如果为普通的二叉树,使用递归的方法,输出最大的深度
解法2:如果为平衡二叉树,需要判断左右节点的深度是否超过1,使用后序遍历的方法,使得每个节点只遍历一次,并且遍历的时候已经得到了左右子树的深度

面试题56:数组中数字出现的次数
——数组中只出现一次的两个数字
解法:由于相等的数异或为0,所以将所有数异或一次,得到的数转为2进制,第一个为1的位置n就是两者二进制不同的地方,所以可以将数组分为两个部分,将n处的值为1和0的区分开,因为相同的数在n出一定相等,所以相同的数会被分在一起,最后两个数组再进行异或,最后得到的两个值就是只出现一次的两个数字
解法2(只有一个数,其他数字出现三次):

面试题57:和为S的数字

面试题58:翻转字符串
——输入英文句子,使得单词顺序反转,但单词不变
解法:先翻转整个句子,最后再翻转单词

相关题目:
- LeetCode:Reverse Words in a String

面试题59:队列的最大值

面试题60:n个骰子的点数

面试题61:扑克牌中的顺子
——随机抽取5张牌,判断是否连续的
解法:先将数组排序,判断数字是否为连续的,如果不是连续的并且存在王(数字0)的话,而且刚好能补足缺少的这一位数字,那么还是连续的;反之不连续

面试题62:圆圈中最后剩下的数字

面试题63:股票的最大利润
——把股票的价格按照时间顺序存在数组里,判断最大利润是多少
解法:利润的最大值,实际就是求数组中最大的差值,在遍历数组之前,可以用变量min保存最小的数字,再用一个diff保存当前的利润,在遍历过程中,如果存在比最小数字还小的值,就swap,然后再判断利润是不是大于diff。最后得到的就是最大的利润
相关问题:
- LeetCode:Best Time to Buy and Sell Stock

面试题64:求1+2+3….+n
——不使用for等关键字求值

面试题65:不用加减乘除做加法
解法:

原创粉丝点击