4 回答
TA贡献1862条经验 获得超7个赞
如果不允许用indexOf,其实这个是一个很有意思的题,可能很多人没有注意到这个是一个循环递增数组,意思是在数组中有一个最小值,其左边是最大值!!如果能很快定位这个值的位置,整个序列就变成了有序数组了,用折半查找就会比较快了,但如果没有定位,则折半查找是有一些问题的。
具体实现
function MyindexOf(k, arr, l, h) {
if(l==h && k!=arr[l]) return -1;
if(arr[l]==k) return l;
if(arr[h]==k) return h;
if(l>h){
let t=h;
h=l;
l=t;
}
let m=Math.ceil((l + h) / 2);
if(arr[m]==k) return m;
if(m==h||m==l) return -1;//表明中间没有空位了,也排除了a[m]==a[l]和a[m]==a[h]的情况
if(arr[l]<arr[h]){ //普通二分法查找
if(arr[h]<k) return -1;
if(arr[l]>k) return -1;
if(arr[m]>k) return MyindexOf(k,arr,l+1,m-1);
return MyindexOf(k,arr,m+1,h-1);
}
//下面是特殊二分法查找了,因为不可能有arr[l]==arr[h]了,所以不用判断arr[l]>arr[h]了,下面默认是arr[l]>arr[h]
if(k>arr[l]) {
if(k>arr[m]){
if(arr[m]>arr[l]) return MyindexOf(k,arr,m+1,h-1);//右
return MyindexOf(k,arr,l+1,m-1);//左
}else{//k>arr[m]
if(arr[m]>arr[l]) return MyindexOf(k,arr,l+1,m-1);//普左
return -1; //arr[m]<arr[l],悖论了
}
}else{ //k<arr[l]
if(k>arr[h]){
return -1;//不可能存在于arr[l],arr[h]区间中
}else{//k<arr[h]
if(k>arr[m]){
return MyindexOf(k,arr,m+1,h-1);//其实包含了arr[m]>arr[h]与arr[m]<arr[h]两种情况
}else{ //k<arr[m]
if(arr[m]>arr[h]){
return MyindexOf(k,arr,m+1,h-1);
}else{
if(arr[m]<arr[h]) return MyindexOf(k,arr,l+1,m-1);
}
}
}
}
return -1;
}
TA贡献1817条经验 获得超6个赞
这就是循环遍历去判断啊。或者用数组的 indexOf 方法。
var arr = [5, 8, 9, 10, 1, 3, 4];
var k = 3;
function getK(k) {
for(var i = 0; i < arr.length; i++) {
if(k === arr[i]) {
return i
}
}
return -1
}
var kIndex = getK(k);
console.log('kIndex:', kIndex)
下面这个是二分查找的方式,可以减少复杂度。
var Arr = [3, 5, 6, 7, 9, 12, 15];
function binary(find, arr, low, high) {
if (low <= high) {
if (arr[low] == find) {
return low;
}
if (arr[high] == find) {
return high;
}
var mid = Math.ceil((high + low) / 2);
if (arr[mid] == find) {
return mid;
} else if (arr[mid] > find) {
return binary(find, arr, low, mid - 1);
} else {
return binary(find, arr, mid + 1, high);
}
}
return -1;
}
binary(15, Arr, 0, Arr.length - 1);
添加回答
举报