OFFER 第6章

2018/9/28 posted in  算法

53. 在排序数组中查找数字

统计一个数字在排序数组中出现的次数。例如输入排序数组{1,2,3,3,3,3,4,5}和数字3。由于3在这个数组中出现了4次。因此输出4;

54. 二叉搜索树的第k大节点

给定一颗叉树的搜索树,请找出第k大的节点。

中序遍历就可以了

55. 二叉树的深度

输入一颗二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点形成树的一条路径,最长路径的长度为树的深度。

55.1 平衡而叉树

输入一颗二叉树的根节点,判定该树是不是平衡二叉树。如果某二叉树中任意节点的左,右子树的深度相差不超过1,那么它就是一颗平衡二叉树。

56. 数组中数字出现的次数

56.1 数组中只出现一次的两个数字

一个整型数组里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度时O(n),空间复杂度是O(1);例如{2,4,3,6,3,2,5,5}

56.2 数组中唯一只出现一次的数字

在一个数组中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。

57. 和为s的数字

输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s,若果有多对数字的和等于s,则输出任意一对即可。

思路1
一个一个遍历相加试探。时间复杂度o()n2

思路2
一个个遍历,后面的有序的进行二分查找s - c的数。时间复杂度o(n*logn)

思路3
采用两个指针,头指针,尾指针,相加大于s时,尾指针向前移动。小于s将头指针向后移动。知道找到为止。时间复杂度O(n)

57.1 和为s的连续正数序列

输入一个正数s,打印出所有和为s的连续正数序列。例如输入15,由于1+2+3+4+5 = 4+5+6=7+8 = 15,所以打印出3个连续序列1~5,4~6,和7~8;

思路
从头开始,逐个比较,直到只有两个相加大于s为止。时间复杂度是O(s2);

优化思路
用两个指针,头,尾,尾向后移动大于s时,去掉头,小于s时,增加尾。直到位编程s/2为止。

58. 翻转字符串

58.1 翻转单词顺序

输入一个英语句子,翻转句子中单词的顺序,但单词内字符顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student",则输出"student. a am i".

思路
先将每个单词翻转,在将整个翻转。整个在与代码的实现。

59. 队列的最大值

59.1 滑动窗口的最大值

给定一个数组和滑动窗口的大小,请找出所有滑动窗口里的最大值。
例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,它们的最大值分别为{4,4,6,6,6,5}。

思路
从上面来看,滑动窗口就是一个队列。我们可以用一个双端的队列(即可以从头部出,也可以尾部弹出)。在向后移动时,要加入的元素比前一个元素的值大时,将前面的元素移除。将后面的元素加入。如果要小,不将后面的值放入队列。每次比较时候,都要判定,头部元素是否还在窗口的范围里。

59.2 队列的最大值

请定义一个队列并实现函数max得到队列里的最大值,要求函数max,push_back和pop_front的时间复杂度都是o(1)

思路
和上面的思路一样

60. n个骰子的点数

把n个骰子扔在地面上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。

61. 扑克牌