1. 旋转数组的最小数字
问题描述:
把一个数组最开始的若干个元素搬到数组的末尾,称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出该旋转数组的最小元素。
例如:
数组 {3,4,5,1,2} 为 {1,2,3,4,5} 的一个旋转,该数组的最小数字为 1。
思路:
旋转数组可以划分为两个排序的子数组。前面子数组的元素都大于等于后面子数组的元素。最小的元素的分界线。
用二分查找法的思路,两个指针,分别指向第一个和最后一个元素。
找到数组的中间元素。Mid = ( p1 + p2 ) / 2;
- 如果 Mid 大于 p1 指向元素,那么 Mid 在第一个子数组中,最小元素位于其后面。于是让 p1 指向 Mid;
- 如果 Mid 小于 p2 指向元素,那么 Mid 在第二个子数组中,最小元素位于其前面。于是让 p2 指向 Mid;
p1 总是指向前一个递增数组的元素,p2 总是指向 递增数组的元素。最终 p1指向前一个数组的最后一个元素,p2 指向后一个数组的第一个元素,即最小元素。这是循环结束的条件。
特例:
如果把排序数组的前面 0 个元素搬运到后面,也是一个旋转数组。此时最小元素就是第一个数字。所以把 indexMid 初始化为 index1。
当 index1,index2,indexMid 指向的三个数字相等时,只能顺序查找。
代码:
|
|
2.调整数组顺序使奇数位于偶数前面
问题描述:
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
version1 思路:
维护两个指针 i 和 j 。第一个指针 i 指向数组第一个元素,第二个指针 j 指向数组最后一个元素;
如果 i 指向偶数,j 指向奇数,交换这两个数字;
如果 i 指向奇数,j 指向奇数,后移 i ,直到 i 指向偶数;
如果 i 指向偶数,j 指向偶数,前移 j,直到 j 指向奇数;
如果 i 指向奇数,j 指向偶数,则后移 i ,前移 j ,直到到达循环结束条件;
循环结束条件:第二个指针在第一个指针前面,此时所有奇数都已经在偶数前面了。
version1 代码:
|
|
version 1 可以实现把数组中的所有奇数都移到整数的前面,但是不能保证原有次序。例如:
测试用例:[1,2,3,4,5,6,7]
对应输出应该为:[1,3,5,7,2,4,6]
我的输出为:[1,7,3,5,4,6,2]
于是有了 version2。
version2 思路:
要保证原有次序,只能顺次移动或者相邻交换。
- i 从左向右遍历,找到第一个偶数;
- j 从 i+1 开始向后找,直到找到第一个奇数;
- 将 [i, …, j-1] 的元素整体后移一位,最后将找到的奇数放入 i 位置,然后 i++;
- 终止条件: j 向后遍历查找失败。
3.数组中出现次数超过一半的数字
题目描述:
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
例如:输出一个长度为 9 的数组 {1,2,3,2,2,2,5,4,2}。
由于数字 2 在数组中出现了 5 次,超过数组长度的一半,因此输出 2。
思路:
在遍历数组的时候保存两个值:一个是数组中的数字,一个是次数;
如果下一个数字和之前保存的数字相同,则次数加一;
如果下一个数字和之前保存的数字不同,则次数减一;
如果次数为零,则保存下一个数字,并将次数设为 1;
验证一下是不是真的出现次数超过数组长度一半。防止有的测试用例不满足要求。
代码:
|
|
4.连续子数组的最大和
问题描述:
输入一个整型数组,数组里有整数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为 O(n)。
例如:
输入:数组为 {1,-2,3,10,-4,7,2,-5},
则最大的连续子数组为{3,10,-4,7,2},
输出:该子数组的和 18。
第一种思路:
- 从头到尾累加数组中的每个数字,初始化和为 0。
- 如果当前和 CurSum 为负值,则不加(加了肯定更小),把 CurSum 直接设为下一数组元素值;
- 如果加到某个数值 array[i] 之后,比加 array[i] 之前的和更大,则更新可能的最大和 GreatSum;
- 如果加到某个数值 array[i] 之后,比加 array[i] 之前的和要小,则 GreatSum 仍为原值;
第一中解答:
|
|
第二种思路(动态规划):
用函数 f(i) 表示以第 i 个数字结尾的子数组的最大和,则:
$$
f(n) =
\begin{cases}
array[i], & \text{i = 0 or f(i - 1) <= 0} \
f(n - 1) + array[i], & \text{i != 0 && f(i - 1) > 0} \
\end{cases}
$$
解答和第一种一样。