zoukankan      html  css  js  c++  java
  • [程序员代码面试指南]数组和矩阵-在数组中找到一个局部最小的位置(二分)

    题目描述

    定义局部最小的概念。arr长度为1时,arr[0]是局部最小。arr的长度为N(N>1)时,如果arr[0]<arr[1],那么arr[0]为局部最小。如果arr[N-1]<arr[N-2],那么arr[N-1]是局部最小。如果0<i<N-1,arr[i]<arr[i+1]&&arr[i]<arr[i-1],那么arr[i]是局部最小。
    给定无序数组arr,已知arr中**任何两个相邻的数不相等**。写一个函数,只需返回arr中**任何一个**局部最小出现的位置即可。
    

    题解

    二分查找.

    • 先查第一个元素/最后一个元素是不是局部最小。不是的话对l=1,r=len-2进行二分。
    • 如果arr[mid]>arr[mid-1],那么区间缩小为[l,mid-1]; (因为不满足上一条,试着画一画,可判定新的区间有局部最小)
    • 如果不满足上一条,且arr[mid]<arr[mid-1],那么区间缩小为[mid+1,r];
    • 如果一二都不满足,那么由题意相邻的数不相等,说明arr[mid-1]<arr[mid]<arr[mid+1],mid即为所求。(由于不满足第一条,所以中间子数组一定存在局部最小,剩了一个元素一定是所求)
    • 当l==r循环结束,l即为所求。

    相关

    这个题推翻了自己之前的看法。注意二分数组并不是数组有序时才可以使用,只要能确定二分两侧的某一侧肯定存在要找的内容,就可以使用二分查找

    时间复杂度O(logN)、额外空间复杂度为O(1).

    代码

    public class Main {
    	public static void main(String args[]) {
    		int[] arr= {10,9,8,9};
    		int localMinIdx=localMinIdx(arr);
    		System.out.println(localMinIdx);
    	}
    	
    	public static int localMinIdx(int[] arr) {
    		if(arr.length==1) {
    			return 0;
    		}
    		if(arr.length==2) {
    			return arr[0]<arr[1]?0:1;
    		}
    		int l=1;
    		int r=arr.length-1;
    		int mid=-1;
    		while(l!=r) {
    			mid=(l+r)/2;
    			if(mid>mid-1) {
    				r=mid-1;
    			}
    			else if(mid<mid+1) {
    				l=mid+1;
    			}
    			else {
    				return mid;
    			}
    		}
    		return mid;
    	}
    }
    
  • 相关阅读:
    CentOS重启与关机
    VIM打开文件与保存文件
    sql Split
    JS获取URL参数
    C#后台调用公网接口(GET, POST)
    鼠标右击.exe的程序出现闪退(桌面重启)怎么办
    JS判断有无网络(移动端)
    TFS API : 四、工作项查询
    TFS API:三、TFS WorkItem添加和修改、保存
    TFS API:二、TFS 代码查询工作项
  • 原文地址:https://www.cnblogs.com/coding-gaga/p/10915082.html
Copyright © 2011-2022 走看看