Day 6:旋转数组的最小数字

时间:2022-07-24
本文章向大家介绍Day 6:旋转数组的最小数字,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

剑指Offer_编程题——旋转数组的最小数字

题目描述:

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

具体要求:

时间限制: C/C++ 3秒,其他语言6秒 空间限制: C/C++32M,其他语言64M

具体思路:

思路1:二分查找(折半查找)+递归算法 根据题意可知,数组是非递减的,是有序的,最适合的就是二分查找了 当array[mid]>array[left]时,最小的数必定在min的右侧 当array[mid]<array[left]时,最小的数必定在min的左侧 当array[mid]=array[left]时,最小的数不能确定是在左还是在右,这时候,我们不妨直接将left向右移动一位( 当然也可以向左)。 具体我们分别用java和python来实现这一思路 1、首先我们用java来实现

import java.util.Arrays;
public class Solution {
    public int minNumberInRotateArray(int [] array) {
        //二分查找
        int left=0;
        int right=array.length-1;
        int mid=(left+right)/2;
         if(array.length==2) {
        	return array[0]<array[1]?array[0]:array[1];
        }
         if(array.length==1) {
        	return array[0];
        }
        if(array[mid]>array[left]){
           return  minNumberInRotateArray(Arrays.copyOfRange(array,mid,array.length));
        }else if(array[mid]<array[left]){
            return  minNumberInRotateArray(Arrays.copyOfRange(array,0,mid+1));
        }else{
            return minNumberInRotateArray(Arrays.copyOfRange(array,1,array.length));
        }
       
    }
}

其效果如图所示:

2、接下来用python将其实现

class Solution:
	def minNumberInRotateArray(self, rotateArray):
		if len(rotateArray) == 0:
			return 0
		left = 0
		right = len(rotateArray) - 1
		while (left < right):
			if rotateArray[left] < rotateArray[right]:
				return rotateArray[left]
			mid = left + (right - left) // 2
			if rotateArray[left] < rotateArray[mid]:
				left = mid + 1
			elif rotateArray[mid] < rotateArray[right]:
				right = mid
			else:
				left = left + 1
		return rotateArray[left]

其效果如图所示:

思路2 分析数组的特点可知,发现数组非递减,若突然变小,在非递减,则可知突然变小的值即为最小值。 我们用java实现该思路:

import java.util.Arrays;
public class Solution{
	public int minNumberInRotateArray(int [] array){
		if(array.length == 1){
			return array[0];
		}
		if(array == null || array.length == 0){
			return 0;
		}
		for (int i = 0; i < array.length - 1; i++){
			if(array[i] > array[i + 1]){
				return array[i + 1];
			}
			else{
				if(i == array.length - 2){
					return array[0];
				}
			}
		}
			return 0;
	}
}

其效果如图所示:

class Solution:
	def minNumberInRotateArray(self, rotateArray):
		if len(rotateArray) == 0:
			return 0
		res_min = 100000000000000000;
		for i in range(len(rotateArray) - 1):
			j = i + 1
			if rotateArray[i] > rotateArray[j] and rotateArray[j] < res_min:
				res_min = rotateArray[j]
		return res_min

其效果如图所示:

总结

  本道题主要考察查找,在做题之前,我们应该了解几种常用的查找方法,比如:二分查找、散列表、二叉查找树、平衡二叉树等,当然也要掌握递归算法,俗话说“大神用递归,一般人用迭代”。一般数据结构是最重要的,要把所有的算法融会贯通,这道题就是将递归和二分查找的有序结合,前道题是栈与队列的结合,因此,我们要更加的掌握各种算法,只有这样才能在遇到各种算法相结合的时候,才能想到相应的算法。继续加油,争取早日找到工作,Good Luck!!!

参考文献

本代码主要参考了以下的博客: [1] 好好学习_天天向上de [2] 小小Java人