有一個已經排序的數組(升序),數組中可能有正數、負數或0,求數組中元素的絕對值最小的數,要求,不能用順序比較的方法(複雜度需要小於O(n)),可以使用任何語言實現例如,數組{-20,-13,-4, 6, 77,200} ,絕對值最小的是-4。
問題分解:
第一步:二分法尋找改變符號的位置(0視為正數)
第二步:比較位置左右數位絕對值大小,取較小的那一個
<script language="javascript"> var getBound = function(a,fr,to){ //[fr,to]是候選位置區間,位置從0開始計數 var b=fr,f=fr,t=to,s=true; var left=function(b){return a[b-1];};//擷取該位置右邊的數字,增加代碼可讀性 var right=function(b){return a[b];};//擷取該位置左邊的數字,增加代碼可讀性 if(a.length===0){ return -1;//數組為空白,返回-1 }else{ if(right(b)>=0){ s=false;//初始化位置就是要找的位置 }else{ for(var i=1;i<=100 && s;i++){ b=f+Math.ceil((t-f)/2);//找到中點 if(right(b)===undefined||(left(b)<0 && right(b)>=0)){ s=false;//中點就是要找的位置 }else if(right(b)<0){ f=b;//下次前進找中點 }else{ t=b;//下次後退找中點 } } } return b; } }; var getMinAbs = function(a){ var b=getBound(a,0,a.length);//擷取位置 if(b>=0){ if(b===0){ return Math.abs(a[b]);//位置在最左邊 }else if(b===a.length){ return Math.abs(a[b-1]);//位置在最右邊 }else{ return (Math.abs(a[b])>Math.abs(a[b-1])?Math.abs(a[b-1]):Math.abs(a[b]));//位置在中間 } }else{ return false; } }; //測試代碼 var myArray=[-20,-13,-4,0,0,0,6,77,200,201,202]; alert("[" + myArray + "]: " + getMinAbs(myArray)); var myArray=[]; alert("[" + myArray + "]: " + getMinAbs(myArray)); var myArray=[-1]; alert("[" + myArray + "]: " + getMinAbs(myArray)); var myArray=[1]; alert("[" + myArray + "]: " + getMinAbs(myArray)); var myArray=[0,0]; alert("[" + myArray + "]: " + getMinAbs(myArray)); var myArray=[-1,-1]; alert("[" + myArray + "]: " + getMinAbs(myArray)); </script>
以myArray=[-20,-13,-4,0,0,0,6,77,200,201,202]為例,測試彈出: