旋转数组的最小数字——js

旋转数组的最小数字

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

思路

把数组从大到小排列,然后输出最小数字,这种思路的时间复杂度是O(n)也没有利用旋转数组的一些特点,并不是题的意图,算是一种方法。
旋转之后的数组实际上可以划分为两个排序的子数组,而且前面的子数组的元素都大于或者等于后面的子数组的元素。最小的元素刚好是这两个子数组的分界线。在排序的数组中可以用二分查找实现O(logn)的查找。

1.我们用两个指针low和high分别指向数组的第一个元素和最后一个元素。按照题目的旋转的规则,第一个元素应该是大于等于最后一个元素的;但是如果不是旋转,第一个元素肯定小于或等于最后一个元素。

2.找到数组的中间元素。中间元素大于最后一个元素,则中间元素位于前面的递增子数组,此时最小元素位于中间元素的后面。我们可以让第一个指针low指向中间元素。

3.中间元素小于最后一个元素,则中间元素位于后面的递增子数组,此时最小元素位于中间元素的前面。我们可以让第二个指针high指向中间元素。

4.中间元素等于最后一个元素,则将第二个指针向前移,然后继续比较。

代码

function minNumberInRotateArray(rotateArray)
{
    // write code here
    rotateArray.sort(function(a,b){
        if(a<b)return -1;
        else return 1
    });
    return rotateArray[0];
}
//方法二:调用Math.min方法
    //Math.min 参数里面不支持数组Math.min([param1,param2]);但它支持Math.min(param1,param2,…)
    if(rotateArray.length==0){
        return 0;
    }
    return Math.min.apply(null,rotateArray);
    //apply第一个参数给了一个null,是因为没有对象去调用这个方法,只需要用这个方法计算得到结果,所以直接传递了一个null过去
    //example
    /*
    function a(xx) {
        this.b = xx; 
	} 
	var o = {}; 
	a.apply(o, [5]); //a.apply(null, [5]);下面o.b结果就是undefined
	alert(a.b);    // undefined 
	alert(o.b);    // 5
    */


//第三种
function minNumberInRotateArray(rotateArray)
{
    var len = rotateArray.length
    if (len == 0){
        return 0
    }else{ 
        var low = 0;
        var high = len-1;
        while(low<high){
            var mid = low + Math.floor((high - low) / 2);        
            if(rotateArray[mid] > rotateArray[high]){
                low = mid + 1;
            }else if(rotateArray[mid] == rotateArray[high]){
                high = high - 1;
            }else{
                high = mid;
            }   
        }
        return rotateArray[low];
        }
    }

知识点

sort() 方法用于对数组的元素进行排序。
如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码的顺序进行排序。要实现这一点,首先应把数组的元素都转换成字符串(如有必要),以便进行比较。
如果想按照其他标准进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,其返回值如下:
若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值。
若 a 等于 b,则返回 0。
若 a 大于 b,则返回一个大于 0 的值。

min() 方法可返回指定的数字中带有最低值的数字。
Function.apply()是JS的一个OOP特性,一般用来模拟继承和扩展this的用途,对于上面这段代码,可以这样去理解:

XXX.apply是一个调用函数的方法,其参数为:apply(Function, Args),
Function为要调用的方法,Args是参数列表,当Function为null时,默认为上文,

Math.max.apply(null, arr)

可认为是
apply(Math.max, arr)
然后,arr是一个参数列表,对于max方法,其参数是若干个数,即
Math.max(a, b, c, d, …)
当使用apply时,把所有参数加入到一个数组中,即
arr = [a, b, c, d, …]
代入到原式,
Math.max.apply(null, [a, b, c, d, …])
实际上等同于
Math.max(a, b, c, d, …)
在此处,使用apply的优点是在部分JS引擎中提升性能。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值