题解 | #数字在升序数组中出现的次数#

数字在升序数组中出现的次数

http://www.nowcoder.com/practice/70610bf967994b22bb1c26f9ae901fa2

总结了三个方法:

  1. 第一个方法: 利用 indexOf()lastIndexOf() 但是时间复杂度 O(n) 不推荐~

  2. 第二个方法: 投机取巧 时间复杂度 O(logN) 符合题目要求

  3. 第三个方法: 第三个方法: 二分查找第一个索引和最后一个索引 时间复杂度O(logN)

现在直接上代码,看注释就能明白:

代码

第一个方法: 时间复杂度 O(n)

function GetNumberOfK(data, k)
{
    // write code here
    // 第一个方法: 利用Api 时间复杂度 O(n)
    return findIndex(data, k)
    
}

// 第一个方法: 利用Api 时间复杂度 O(n)
// indexOf的操作时间复杂度是O(n) 所以以下不是最优解
function findIndex(data, k) {
    let firstIndex, lastIndex, count = 0;
    firstIndex = data.indexOf(k)
    lastIndex = data.lastIndexOf(k)
    if(firstIndex !== -1) {
        count = lastIndex - firstIndex + 1
    }
    return count
}



module.exports = {
    GetNumberOfK : GetNumberOfK
};

第二个方法: 时间复杂度 O(logN)

function GetNumberOfK(data, k)
{
    // write code here
    // 第二个方法: 投机取巧 时间复杂度 O(logN) 符合题目要求
    return insertIndex(data, k + 0.1) - insertIndex(data, k - 0.1)
   
    
}



// 第二个方法: 投机取巧
// 题目给的是整数,我可以取这个整数的浮点数 
// 把3加减0.1之后 利用二分法搜索k-0.1和k+0.1这两个数应该插入的位置 
function insertIndex(data, k) {
    let left = 0,
        right = data.length - 1;
    while(left <= right) {
        let mid = left + ((right - left) >> 1)
        if(data[mid] < k) {
            left = mid + 1
        } else if (data[mid] > k) {
            right = mid - 1
        }
    }
    return left
}

module.exports = {
    GetNumberOfK : GetNumberOfK
};

第三个方法: 时间复杂度 O(logN)

主要思路是当mid等于k时,判断左右是否还有相同的数。

function GetNumberOfK(data, k)
{
    // write code here
    // 第三个方法: 二分查找第一个索引和最后一个索引 时间复杂度O(logN)
  let first = firstIndex(data,k),
      last = lastIndex(data, k);
  if(first === -1 || last === -1) return 0;
  return last - first + 1;
    
}

// 第三个方法: 找第一个和最后一个索引
function firstIndex(data, k) { // 第一个索引
    let left = 0,
        right = data.length - 1;
    while(left <= right) {
        let mid = left + ((right - left) >> 1)
        if(data[mid] < k) {
            left = mid + 1
        }
        if(data[mid] > k) {
            right = mid - 1
        }
        if(data[mid] === k) {
            if(data[mid-1] !== k){ // mid - 1 看左边是否还有相同的数
                return mid
            } else {
                right = mid - 1 // 注意: 继续只寻找左边
            }
        }
    }
    return -1
}

function lastIndex(data, k) {// 最后一个索引
    let left = 0,
        right = data.length - 1;
    while(left <= right) {
        let mid = left + ((right - left) >> 1)
        if(data[mid] < k) {
            left = mid + 1
        }
        if(data[mid] > k) {
            right = mid - 1
        }
        if(data[mid] === k) {
            if(data[mid+1] !== k){  // mid + 1 看右边是否还有相同的数
                return mid
            } else {
                left = mid + 1  // 注意: 继续只寻找右边
            }
        }
    }
    return -1
}



module.exports = {
    GetNumberOfK : GetNumberOfK
};
全部评论

相关推荐

实习挂完提前批挂_提前批挂完秋招挂:我是来结束这个秋招的😤
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务