二分搜索

定义局部最小的概念。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中任意一个局部最小出现的位置即可。
public class Solution {
    public static int findPartMin(int[] data,int lo,int hi){
    	while(lo<=hi){
    		int mid = lo+(hi-lo)/2;
    		if(data[mid]<data[mid-1]&&data[mid]<data[mid+1])
    			return mid;
    		else if(data[mid]>data[mid-1])
    			hi = mid-1;
    		else if(data[mid]>data[mid+1])
    			lo = mid+1;
    	}
    	return -1;
    }
    public int getLessIndex(int[] arr) {
    	if(arr.length==1)
    		return 0;
    	else if(arr.length>1){
    		if(arr[0]<arr[1])
    			return 0;
    		else if(arr[arr.length-1]<arr[arr.length-2])
    			return arr.length-1;
    		else
    			return findPartMin(arr,1,arr.length-2);
    	}else
    		return -1;
    }
}

  

对于一个有序数组arr,再给定一个整数num,请在arr中找到num这个数出现的最左边的位置。

给定一个数组arr及它的大小n,同时给定num。请返回所求位置。若该元素在数组中未出现,请返回-1。

测试样例:
[1,2,3,3,4],5,3
返回:2
import java.util.*;

public class LeftMostAppearance {
    public int findPos(int[] arr, int n, int num) {
        // write code here
        int left = 0,right = n-1;
    	int pos = -1;
    	while(left<=right){
    		int mid = left+(right-left)/2;
    		if(arr[mid]>num)
    			right = mid-1;
    		else if(arr[mid]<num)
    			left = mid+1;
    		else{
    			pos = mid;
    			right = mid-1;
    		}
    	}
    	return pos;
    }
}

有一个有序数组arr,其中不含有重复元素,请找到满足arr[i]==i条件的最左的位置。如果所有位置上的数都不满足条件,返回-1。

给定有序数组arr及它的大小n,请返回所求值。

测试样例:
[-1,0,2,3],4
返回:2
import java.util.*;

public class Find {
    public int findPos(int[] arr, int n) {
        // write code here
        int left = 0,right = n-1;
    	while(left<=right){
    		int mid = left+(right-left)/2;
            if(arr[left]==left)
    			return left;
    		if(arr[mid]>mid)
    			right = mid-1;
    		else if(arr[mid]<mid)
    			left = mid+1;
    		else
    			return mid;
    	}
    	return -1;
    }
}

  

如果更快的求一个整数k的n次方。如果两个整数相乘并得到结果的时间复杂度为O(1),得到整数k的N次方的过程请实现时间复杂度为O(logN)的方法。

给定kn,请返回k的n次方,为了防止溢出,请返回结果Mod 1000000007的值。

测试样例:
2,3
返回:8
import java.util.*;

public class QuickPower {
    public int getPower(int k, int N) {
        // write code here
    	String bin = Integer.toBinaryString(N);
    	//System.out.println(bin+" "+bin.length());
    	long[] temp = new long[bin.length()];
    	temp[0] = k;
    	for(int i = 1;i < bin.length(); i++){
    		temp[i] = ((temp[i-1]*temp[i-1])%1000000007);
    		//System.out.println(temp[i]+" "+i);
    	}
    	long result = 1;
    	for(int i = bin.length()-1;i >= 0; i--)
    		if(bin.charAt(i)=='1'){
    			result = result*temp[bin.length()-1-i];
    			result = result%1000000007;
    		}
    	//System.out.println((int)result+" "+Integer.MAX_VALUE);
    	
    	return (int)result;
    }
}

 更简洁的代码:

import java.util.*;
 
public class QuickPower {
    public int getPower(int k, int N) {
        // write code here
        if(k==0){
            return 0;
        }
        if(k==1){
            return 1;
        }
        if(N==0){
            return 1;
        }
        long modNum=1000000007;
        long res=1;
        long tmp=k;
         
        for(;N>0;N>>=1){
            if((N&1)!=0){
                res*=tmp;
            }
            tmp=(tmp*tmp)%modNum;
            res=res%modNum;
             
        }
      
        return (int)res;
    }
}

  

题目描述

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
import java.util.ArrayList;
public class Solution {
    public int minNumberInRotateArray(int [] array) {
        int left = 0,right = array.length-1;
        int mid = left;
        while(array[left]>=array[right]){
        	if(right-left==1){
        		mid = right;
        		break;
        	}
        	
        	mid = (left+right)/2;
        	
        	if(array[left]==array[right]&&array[mid]==array[left])
        		return search(array,left,right);
        	
        	if(array[mid]>=array[left])
        		left = mid;
        	else if(array[mid]<=array[right])
        		right = mid;
        }
        return array[mid];
    }
    
    int search(int[] array,int left,int right){
    	int result = array[left];
    	for(int i = left+1; i<=right; i++)
    		if(result>array[i])
    			result = array[i];
    	
    	return result;
    }
}

  

原文地址:https://www.cnblogs.com/lxk2010012997/p/5551202.html