search-in-rotated-sorted-array
题目描述
假设按照升序排序的数组在预先未知的某个点上进行了旋转。搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。
你可以假设数组中不存在重复的元素。
你的算法时间复杂度必须是 O(log n) 级别。
设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。
深度优先搜索
1 | bool find(vector<vector<char>>& board, bool** access, string s, int index, int x, int y) |
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。
最小元素所在的位置就是旋转点。
1 | int minArray(vector<int>& numbers) { |
一开始也想用二分法解决来着……但是没有写出来……还是要多学习。
输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
明明都知道要用递归来建左子树和右子树,却一直写不对递归的参数。唉。
1 | TreeNode * makeTree(vector<int>& preorder, vector<int>& inorder, int index, int left, int right) |
注意什么时候返回nullptr。
找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
可以借助set数据结构,使用它的count()和insert()两个功能:
1 | int findRepeatNumber(vector<int>& nums) { |
另一种时间复杂度更低的解法:
如果没有重复的话,数值i应该在第i个位置上,所以,从前往后遍历数组,当遇到num[i] = m != i时,将nums[i]与nums[m]互换,直到num[i]==i,如果中途遇到相同的值,就立即返回。
1 | int findRepeatNumber(vector<int>& nums) { |
给定一个字符串,逐个翻转字符串中的每个单词。
说明:
无空格字符构成一个单词。
输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
请选用 C 语言的用户尝试使用 O(1) 额外空间复杂度的原地解法。
先放一个空间复杂度为O(n)的:
1 | string reverseWords(string s) { |
不过效率太低了。睡一觉再改吧。
先将字符串整个反转一下,然后再反转单个单词就行了。这其中可以去掉空格。
1 | string reverseWords(string s) |
根据逆波兰表示法,求表达式的值。(即后缀表达式)
有效的运算符包括 +
, -
, *
, /
。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
要用到栈的结构吧,遇到一个操作符就弹出两个操作数,然后压入计算结果。
1 | int evalRPN(vector<string>& tokens) { |
给定一个二维平面,平面上有 n 个点,求最多有多少个点在同一条直线上。
对于每一个定点,向后面遍历每一个点,就得到一条直线,找在这条直线上最多的点数。
斜率如果是小数的话就会存在精度问题,不能做key,因此对分数进行约分,保存为特殊字符串:”分子@分母”。约分的话需要找出最大公约数gcd,计算gcd需要使用辗转相除法。
还要考虑重复的点。
1 | inline int gcd(int a, int b) |
怎么办啊 我太菜了。
在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。
常数级空间复杂度,不能使用递归,使用bottom-to-up的算法。先两个两个的 merge,完成一趟后,再 4 个4个的 merge,直到结束。
1 | ListNode* merge(ListNode* h1, ListNode* h2) |
或许可以恢复状态了。