1.4.18數組的局部最小元素。編寫一個程序,給定一個含有N個不同整數的數組,找到一個局部最小元素:滿足a[i]<a[i-1],且a[i]<a[i+1]的索引i。程序在最壞情況下所需的比較次數為~2lgN。
答:檢查數組的中間值a[N/2]以及和它相鄰的元素a[N/2-1]和a[N/2+1]。如果a[N/2]是一個局部最小值則算法終止;否則則在較小的相鄰元素的半邊中繼續查找。
說明:按照上面的提示寫出下面的代碼不能將這個排列中的局部最小找出來。排列:7? 6? 9? 5? 4? 3? 2? 1 中的6找不出來。
public class E1d4d18
{
??? public static int min(int[] a)
??? {
??????? int lo=1;
??????? int hi=a.length-1;
??????? int mid;
??????? while(lo<hi)
??????? {
??????????? mid=(lo+hi)/2;
???????????? if(mid-1>=0 && a[mid-1]<a[mid])
??????????????? hi=mid-1;
??????????? else if(mid+1<a.length && a[mid]>a[mid+1])
??????????????? lo=mid+1;
??????????? else
??????????????? return mid;
??????? }
??????? return -1;
??? }
???
??? public static void main(String[] args)
??? {
????? int[] a=In.readInts(args[0]);
????? StdOut.println(min(a));
??? }
}
按照下面版本的代碼可以避免上述問題,算法是選從mid-1與mid+1中較小的一邊找,找不到時再從mid-1與mid+1中較大的一邊找。
public class E1d4d18
{
??? public static int min(int[] a)
??? {
??????? int lo=1;
??????? int hi=a.length-2;
??????? int mid;
??????? int localMinIndex=-1;
??????? //find in rang smaller
????? while(lo<=hi && localMinIndex==-1)
??????? {
??????????? mid=(lo+hi)/2;
??????????? if(a[mid]<a[mid-1] && a[mid]<a[mid+1])
??????????????? localMinIndex=mid;
??????????? else if(a[mid-1]<a[mid+1])
??????????????? hi=mid-1;
??????????? else if(a[mid-1]>a[mid+1])
??????????????? lo=mid+1;
??????? }
?????? //
????? lo=1;
????? hi=a.length-2;
????? while(lo<=hi && localMinIndex==-1)
????? {
????????? mid=(lo+hi)/2;
????????? if(a[mid]<a[mid-1] && a[mid]<a[mid+1])
????????????? localMinIndex=mid;
????????? else if(a[mid-1]<a[mid+1])
????????????? lo=mid+1;
????????? else if(a[mid-1]>a[mid+1])
????????????? hi=mid-1;
????? }
????? return localMinIndex;
??? }//end min
??? public static void main(String[] args)
??? {
????? int[] a=In.readInts(args[0]);
????? StdOut.println(min(a));
??? }
}
轉載于:https://www.cnblogs.com/longjin2018/p/9854443.html