剑指offer经典题目二:旋转数组的最小数字

x33g5p2x  于2022-01-13 转载在 其他  
字(1.2k)|赞(0)|评价(0)|浏览(285)

剑指offer经典题目二

题目链接旋转数组的最小数字
题目描述:
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

题目要求给一个非递减排序的数组的一个旋转,需要输出旋转数组的最小元素,我们可以直接进行遍历去找最小的那个数,但是这种方法肯定是效率最低的

核心考点:数组理解,二分查找,临界条件

方法一思路:
一个非递减的数组左旋之后,最开始出现递减的地方的那个数字就是最小值,我们可以比较相邻的两个数,如果右边的数小于左边的数,那么该右边的这个数字就是最小值,这种方法本质上和上面的没有区别,效率不高

方法二思路:

定义首位下标,因为是非递减数组旋转,所以旋转最后可以看作成两部分,前半部分整体非递减,后半部分整体非递减,前半部分整体大于后半部分。当a[mid]大于等于a[left]时,说明mid属于原数组前半部分,目标最小值,在mid的右侧,让left = mid;当a[mid]小于a[left],说明mid位置在原数组后半部分,说明目标最小值在mid的左侧,让right = mid。

方法二解题代码:

  1. class Solution
  2. {
  3. public:
  4. int minNumbeiInRotateArray(vector<int> array)
  5. {
  6. if(array == nullptr||array.size() == 0)
  7. {
  8. return 0;
  9. }
  10. int left = 0;
  11. int right = array.size()-1;
  12. int mid = 0;
  13. while(left<right)
  14. {
  15. //当right和left相邻时,右边的值是
  16. if(right - left==1)
  17. {
  18. mid = right;
  19. break;
  20. }
  21. //如果这三者相等,没有办法判断左半部分还是右半部分
  22. if(arrar[left] == array[right] && arrar[left] == array[mid])
  23. {
  24. //此时遍历式的去找
  25. int result = array[left];
  26. for(int i = left+1;i<right;i++)//i不用等于right,因为right是和left相等的不用比较
  27. {
  28. if(result>arrar[i])
  29. {
  30. result = array[i];
  31. }
  32. }
  33. return result;
  34. }
  35. mid = (right+left)>>1;
  36. if(array[mid]>=array[left])
  37. {
  38. //当a[mid]大于等于a[left]时,说明mid属于原数组前半部分,目标最小值,在mid的右侧
  39. left = mid;
  40. }
  41. else
  42. {
  43. //当a[mid]小于a[left],说明mid位置在原数组后半部分,说明目标最小值在mid的左侧
  44. right = mid;
  45. }
  46. }
  47. return array[mid];
  48. }
  49. }

相关文章