剑指offer-JavaScript版本实现(1)--数组部分

本文深入解析《剑指Offer》中的经典算法题,包括二维数组查找、重复数字检测及构建乘积数组,提供多种解题思路与代码实现,助力算法学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

自己总结下刷完剑指offer,使用js的实现等。

一、二维数组的查找

题目描述: 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

方法一: 把每一行看成有序递增的数组,利用二分查找,通过遍历每一行去得到是否含有该整数, 时间复杂度: O(n*logn)

function Find(target, array)
{
    // write code here
    for(let i = 0; i < array.length;i++){
        if(binarySearch(target,array[i])){
            return true;
        }
    }
    return false;
}
 
function binarySearch(target,arr){
    let low = 0;
    let high = arr.length - 1;
    while(low <= high){
        let mid = parseInt((low + high) / 2);
        if(target < arr[mid]){
            high = mid - 1;
        }else if(target > arr[mid]){
            low = mid + 1;
        }else if(target == arr[mid]) {
            return true;
        }else return false;
        
    }
    return false;
}

方法二: 矩阵是有序的,从左下角来看,向上数字递减,向右数字递增。 因此从左下角开始查找,当要查找的数字比左下角数字的时候,向右移动; 当要查找的数字比左下角数字小时,向上移动。 时间复杂度: O(行高 + 列宽) , 空间复杂度: O(1)

function Find(target, array)
{
    // write code here
    let row = array.length;
    let col = array[0].length;
    if (row == 0 || col == 0) return false;
    let i = row - 1;
    let j = 0;
    while(i >= 0 && j < col){
       if (target < array[i][j]) {
            i--;
            continue;
        } else if (target > array[i][j]) {
            j++;
            continue;
        } else {
            return true;
        }
    }
    return false;
}

方法三: 一行代码,实用型

function Find(target, array) {
    return array.some(arr => arr.some(e => e === target))
}

二、 重复的数字

在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。

方法一: 利用hash,也就是js里面的{};

function duplicate(numbers, duplication)
{
    // write code here
    //这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
    //函数返回True/False
    var len = numbers.length;
    var obj = {};
    for(var i = 0; i < len; i++) {
        if(numbers[i] in obj) {
            duplication[0] = numbers[i];
            return true;
        } else {
            obj[numbers[i]] = 1;
        }
    }
    return false;
}

方法二:

  1. 把当前序列当成是一个下标和下标对应值是相同的数组;
  2. 遍历数组,判断当前位的值和下标是否相等: 2.1. 若相等,则遍历下一位; 2.2. 若不等,则将当前位置i上的元素和a[i]位置上的元素比较:若它们相等,则成功; 若不等,则将它们两交换。换完之后a[i]位置上的值和它的下标是对应的,但i位置上的元素和下标并不一定对应;
  3. 重复2.2的操作,直到当前位置i的值也为i,将i向后移一位,再重复2.

时间复杂度O(n), 空间复杂度O(1)

function duplicate(numbers, duplication)
{
    // write code here
    //这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
    //函数返回True/False
   let len = numbers.length;
   if (numbers == null || len <= 0) return false;
    for(let i = 0; i < len; i++) {
        while(numbers[i] != i) {
            if (numbers[i] == numbers[numbers[i]]) {
                duplication[0] = numbers[i];
                return true;
            }
            let temp = numbers[i];
            numbers[i] = numbers[temp];
            numbers[temp] = temp;
        }
    }
    return false;
}

三、构建乘积数组

给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]A[1]...*A[i-1]A[i+1]...*A[n-1]。不能使用除法。(注意:规定B[0]和B[n-1] = 1)

B[i]的值可以看作下图的矩阵中每行的乘积。 先算下三角中的连乘,然后倒过来按上三角中的分布规律,把另一部分也乘进去。

 

 

 

function multiply(a)
{
    // write code here
    var len = a.length;
    var b = [];
    if (len != 0) {
        b[0] = 1;
        <!-- 计算下三角连乘 -->
        for(var i = 1; i < len; i++) {
            b[i] = b[i-1] * a[i-1];
        }
        var temp = 1;
        <!-- 计算上三角 -->
        for(var j = len - 2; j >= 0; j--) {
            temp *= a[j+1];
            b[j] *= temp;
        }
    }
    return b;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值