Coursera Algorithms week1 Interview Questions: Search in a bitonic array

本文探讨如何在位序数组(先递增后递减的整数数组)中寻找特定元素。标准方法使用约3lgN次比较,而挑战在于设计一种使用约2lgN次比较的算法。文章通过分析和代码实现,解释了两种方法的原理,特别是如何在不寻找最大值的情况下优化到2lgN的时间复杂度。

题目要求:

An array is bitonic if it is comprised of an increasing sequence of integers followed immediately by a decreasing sequence of integers. Write a program that, given a bitonic array of n distinct integer values, determines whether a given integer is in the array.

  • Standard version: Use ∼3lgn compares in the worst case.
  • Signing bonus: Use ∼2lgn compares in the worst case (and prove that no algorithm can guarantee to perform fewer than ∼2lgn compares in the worst case).

分析

bitonic array是一个内部先递增再递减的队列,实现3lgn很简单,先找出最大值用掉lgn,再从左侧有序数组中查找用掉lgn,未找到则再从右侧有序数组中查找用掉lgn,最坏情况下复杂度就是3lgn。详见代码中findNormal方法。

但是2lgn的做法我一直没想出来合适的,作业的hint提示“Signing bonus. Do it without finding the maximum integer.”意味着去掉查找最大值可以减少复杂度。我一时也没想到好的实现方法,在网上看到一篇别人转载的文章后恍然大悟(http://blog.csdn.net/fiveyears/article/details/11263381)。参照其思路,自己实现findFast方法。

public class SearchBitonicArray {
	private static int seachLeft(int key,int[] a, int lo, int hi){
		int mid = 0;
		while(lo <= hi){//遍历左侧增长序列
			mid = lo + (hi-lo)/2;
			if(key > a[mid]) lo = mid +1;
			else if(key < a[mid]) hi = mid -1;
			else return mid;
		}
		return -1;
	}
	private static int searchRight(int key, int[] a, int lo, int hi){
		int mid = 0;
		while(lo <= hi){
			mid = lo + (hi-lo)/2;
			if(key > a[mid]) hi = mid -1;
			else if(key < a[mid]) lo = mid +1;
			else return mid;
		}
		return -1;
	}
	
	//worst case use 3lgn
	public static int findNormal(int key, int[] a){
		int lo = 0;
		int hi = a.length -1;
		int mid = 0;
		while(lo<=hi){
			mid = lo + (hi-lo)/2;
			if(a[mid]==key) return mid;
			else{
				if(mid==0 || mid==a.length-1) return -1;
				if(a[mid]>a[mid-1] && a[mid]>a[mid+1]){//mid刚好取到最大数
					break;
				}else if(a[mid]>a[mid-1] && a[mid]
  
    a[maxValIndex]) return -1;//key大于a[i]中最大值,key肯定不在数组中
		if(key < a[0] && key < a[a.length -1]) return -1;
		int findValue = seachLeft(key,a,0,maxValIndex-1);
		if(findValue == -1)
			findValue = searchRight(key,a,maxValIndex+1,a.length-1);
		
		return findValue;
	}
	
	public static int findFast(int key, int[] a){
		int lo = 0;
		int hi = a.length -1;
		int mid = 0;
		int findValue = -1;
		while(lo<=hi){
			mid = lo + (hi-lo)/2;
			if(a[mid]==key) return mid;
			else if(a[mid] > key){
				if(a[mid]>a[mid+1] && a[mid]>a[mid-1]){
					findValue = seachLeft(key,a,0,mid-1);
					if(findValue != -1) return findValue;
					else return searchRight(key,a,mid+1,a.length-1);
				}else if(a[mid]>a[mid+1] && a[mid]
   
  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值