sisterAn / JavaScript-Algorithms

基础理论+JS框架应用+实践,从0到1构建整个前端算法体系
5.51k stars 634 forks source link

实现一个 findIndex 函数 #137

Open sisterAn opened 3 years ago

sisterAn commented 3 years ago

找到有序数组 [1, 2, 3, 4, 7, 7, 7, 9, 12, 23, 34, 45, 55, 67]中第一次出现的位置,比如7第一次出现的位置是4

linlinyang commented 3 years ago

二分查找


    function findIndex(arr, target){
        const len = arr.length;
        let left = 0;
        let right = len - 1;

        let ret = -1;
        while (left <= right) {
            const middle = ((right - left) >> 1) + left;
            const val = arr[middle];
            if (val >= target) {
                if (val === target) {
                    ret = middle;
                }
                right = middle - 1;
            } else {
                left = middle + 1;
            }
        }

        return ret;
    }
sisterAn commented 3 years ago

腾讯&字节&leetcode34:在排序数组中查找元素的第一个和最后一个位置

jdkwky commented 3 years ago
function findIndex(list, target){
            let start = 0, end = list.length -1;
            let index = -1;
            while(start !=end && start < end){
                let mid = start + Math.floor((end - start ) / 2);
                if(list[mid] > target){
                    end = mid -1;
                }else if (list[mid] < target){
                    start = mid + 1;
                }else{
                    index = mid;
                    end = mid -1;
                }
            }
            return index;
         }
z253573760 commented 3 years ago
const arr = [1, 2, 3, 4, 7, 7, 7, 9, 12, 23, 34, 45, 55, 67];

function findIndex(arr, target, start = 0, end = arr.length - 1) {
  let index = Math.floor((start + end) / 2);
  const midd = arr[index];
  if (midd === target) {
    while (index >= 0) {
      if (arr[index] === target) {
        index -= 1;
      } else {
        return index + 1;
      }
    }
  }
  if (midd < target) {
    return findIndex(arr, target, index + 1, end);
  } else {
    return findIndex(arr, target, start, index - 1);
  }
}
const res = findIndex(arr, 7); //4
console.log(res);
dlrandy commented 3 years ago

function findIndex(sortedArray, seekElement) {
    let startIndex = 0, endIndex = sortedArray.length - 1;
    while (startIndex <= endIndex) {
        const middleIndex = startIndex + Math.floor((endIndex - startIndex)/2)
        if (sortedArray[middleIndex] === seekElement) {
           let leftIndex = middleIndex; 
           while(sortedArray[leftIndex] === seekElement && leftIndex >= 0){
                leftIndex--;
           }
            return leftIndex + 1;
        }

        if (sortedArray[middleIndex] < seekElement) {
            startIndex = middleIndex + 1;
        } else {
            endIndex = middleIndex - 1;
        }
    }

    return -1;
}
xllpiupiu commented 3 years ago
/**
 * O(n)遍历 找到出现的第一个位置
 * 二分查找O(logn)遍历
 */
//普通遍历
Array.prototype.findIndex = function (val) {
    for (let i = 0; i < this.length; i++) {
        if (this[i] === val) return i;
    }
    return -1;
}
//找到结束位置
Array.prototype.findEndIdx = function (val) {
    for (let i = this.length - 1; i >= 0; i--) {
        if (this[i] === val) return i;
    }
    return -1;
}
let arr = [1, 2, 2, 4];
let index = arr.findIndex(2);
console.log('index: ', index);
let endIdx = arr.findEndIdx(2);

console.log('endIdx: ', endIdx);

/**
 * 2. 优化算法使得时间复杂度为O(logn)
 * 使用二分查找因为数组有序
 */
Array.prototype.findStartIdx = function (val) {
    let left = 0;
    let right = this.length - 1;
    while(left<=right) {
        let midIdx = Math.floor(left+(right-left)/2);
        if(this[midIdx]===val&&this[midIdx-1]<val||midIdx===0){
            return midIdx;
        } else if(this[midIdx]>=val){
            //往左侧查找
            right = midIdx - 1;
        } else {
            left = midIdx + 1;
        }
    }
    return -1;
}
Array.prototype.findEndIdx2 = function(val) {
    let left = 0;
    let right = this.length - 1;
    while(left<=right) {
        let midIdx = Math.floor(left+(right-left)/2);
        if(this[midIdx]===val&&this[midIdx+1]>val||midIdx===this.length-1) {
            return midIdx;
        } else if(this[midIdx]<=val) {
            //往左侧查找
            left = midIdx + 1;
        } else {
            right = midIdx -1;
        }
    }
    return -1;
}
let startIdx = arr.findStartIdx(9);
console.log('startIdx: ', startIdx);

let findEndIdx2 = arr.findEndIdx2(4);
console.log('findEndIdx2: ', findEndIdx2);
ZhaoWeiming9317 commented 2 years ago

可以仿照python的bisect-left的源码来写呀

function findIndex(arr: number[], target: number) {
    let lo = 0;
    let hi = arr.length - 1;
    while (lo < hi) {
        let mid = Math.floor((lo + hi) / 2);
        if (target > arr[mid]) {
            lo = mid + 1;
        } else {
            hi = mid;
        }
    }
    return lo;
}