[剑指Offer笔记]08_查找与排序 minNumberInRotateArray

[剑指Offer笔记]08_查找与排序 minNumberInRotateArray

面试重点注意:

  • 二叉查找
  • 归并排序
  • 快速排序

注意: 很多算法有递归和循环两种写法. 递归代码简洁,但性能不如循环的.

  • 位运算! 是一种特殊的算法
  • 与 或 异或 左移 右移 这五种操作

查找与排序

  • 顺序查找 / 二分查找 / 哈希表查找 / 二叉排序树查找

  • 对各类的排序算法都要烂熟于心,能够从额外空间消耗/平均时间复杂度和最差时间复杂度等方面

  • 快排的重要思想:

    现在数组中选择一个数字,然后把数组中的数组分成两个部分.

    一个小于它,一个大于它.

题目描述:

  • 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。

    例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

分析:

  • 在数字都不相同的情况下:

    利用有两个递增的数组!

    l指针始终指向 第一个数组!

    r指针始终指向 第二个数组!

    r-l==1时,则找到了最小值

实现:

class Solution {
	public:
		int minNumberInRotateArray(vector<int> rotateArray) {

			int len = rotateArray.size();
			if (len == 0)
				return 0;

			// 没有旋转
			if (rotateArray[0] < rotateArray[len - 1])
				return rotateArray[0];

			else {
				// 发生了旋转,则 [0] 一定> [len-1]
				int l = 0, r = len - 1; // l指向第一个递增数组的最后一个数字,r指向第二个递增数组的第一个数字
				while (l < r) {
					if (r - l == 1) // 若相差1个,则找到了
						break;
					int mid = (r - l) / 2 + l;

					if (rotateArray[mid] >= rotateArray[l]) {
						// mid仍在第一个递增数组
						l = mid;
					}
					else if (rotateArray[mid] <= rotateArray[r]) {
						// mid仍在第二个递增数组
						r = mid;
					}
				}            
				return rotateArray[r];
			}
		}
	};

做题体会:

  • 二分查找法! 最重要的是 定义好你的指针! 他们指向什么!从始到终一定要固定!!!

猜你喜欢

转载自blog.csdn.net/qjh5606/article/details/84503146