剑指Offer——构建乘积数组(JS实现) |刷题打卡

简介: 剑指Offer——构建乘积数组(JS实现) |刷题打卡

前言

掘金团队号上线,助你 Offer 临门! 点击 查看详情

题目描述

image.png

解题思路

  • 遇到这道题,我首先使用使用双指针,左右遍历
  • 遇到第i个元素则停止遍历,然后进行求乘积
  • 但是结果超时
  • 最终通过对称遍历的方式成功解决问题

解题代码一:暴力双指针(超时)

var constructArr = function (a) {
    // 使用左右指针两边遍历的方法
    const result = [];
    let l = 0;
    let r = a.length - 1;
    let temp = 1;
    let temp2 = 1;
    for (let i = 0; i < a.length; i++) {
        while (l !== i) {
            temp = temp * a[l];
            l++;
        }
        while (r !== i) {
            temp2 = temp2 * a[r];
            r--;
        }
        l = 0;
        r = a.length - 1;
        result.push(temp * temp2)
        temp = 1;
        temp2 = 1;
    }
    return result;
};

超时原因

  • 涉及到多个循环,时间复杂度太高,必须改进时间复杂度。

解题代码二:使用截取除i个元素之外的所有元素(超时)

var constructArr = function (a) {
    const result = [];
    let testarr = [];
    let l = 0;
    let r = a.length - 1;
    let temp = 1;
    let temp2 = 1;
    for (let i = 0; i < a.length; i++) {
        testarr.push(...a.slice(0,i),...a.slice(i+1))
        result.push(testarr.reduce((pre,cur) => pre * cur,1));
        testarr = [];
    }
    return result;
};

超时原因

  • 还是时间复杂度太高。

解题代码三:使用对称遍历(成功AC)

var constructArr = function (a) {
    let right = [];
    let left = [];
    const result = [];
    for (let i = 0; i < a.length; i++) {
        if (i === 0) {
            left[i] = a[0];
            right[i] = a[a.length - 1];
        } else {
            left[i] = left[i-1] * a[i];
            right[i] = right[i-1] * a[a.length-1-i];
        }
    }
    for (let i = 0; i < a.length;i++) {
        if (i === a.length - 1) {
            result.push(left[left.length-2]);
            break;
        }
        if (i === 0) {
            result.push(right[right.length-2])
        } else {
            result.push(right[right.length-1-i-1] * left[i-1])
        }
    }
    return result;
};

总结

  • 本题乍一看不难,大家也都容易想到一定的思路,但是难就难在时间复杂度的问题上
  • 只有比较低的时间复杂度才能够通过
  • 本题给我们的启示就是对称遍历
  • 这里的对称遍历刚开始是包好第i个元素的,并不是说将第i个元素去掉,这是我思维上的误区,就是一直想在刚开始就将第i个元素去掉,实际上通过对称遍历,存储左边的数组和存储右边的数组,刚开始都是全部遍历完的,之后再从结果中去取我们想要的结果。
  • 路漫漫其修远兮,吾将上下而求索。加油!


相关文章
|
4月前
|
JavaScript 前端开发 物联网
JavaScript:构建动态世界的引擎
JavaScript:构建动态世界的引擎
|
4月前
|
前端开发 JavaScript 开发者
JavaScript:构建动态网络的引擎
JavaScript:构建动态网络的引擎
|
4月前
|
前端开发 JavaScript 开发者
JavaScript:构建动态Web的核心力量
JavaScript:构建动态Web的核心力量
|
8月前
|
前端开发 算法 API
构建高性能图像处理Web应用:Next.js与TailwindCSS实践
本文分享了构建在线图像黑白转换工具的技术实践,涵盖技术栈选择、架构设计与性能优化。项目采用Next.js提供优秀的SSR性能和SEO支持,TailwindCSS加速UI开发,WebAssembly实现高性能图像处理算法。通过渐进式处理、WebWorker隔离及内存管理等策略,解决大图像处理性能瓶颈,并确保跨浏览器兼容性和移动设备优化。实际应用案例展示了其即时处理、高质量输出和客户端隐私保护等特点。未来计划引入WebGPU加速、AI增强等功能,进一步提升用户体验。此技术栈为Web图像处理应用提供了高效可行的解决方案。
|
9月前
|
前端开发 搜索推荐 JavaScript
如何通过DIY.JS快速构建出一个DIY手机壳、T恤的应用?
DIY.JS 是一款基于原生 Canvas 的业务级图形库,专注于商品定制的图形交互功能,帮助开发者轻松实现个性化设计。适用于 T 恤、手机壳等多种商品场景。它自带丰富功能,无需从零构建,快速集成到项目中。通过创建舞台、添加模型、定义 DIY 区域和添加素材四个步骤即可完成基础用法。支持在线演示体验,文档详细,易上手。
439 57
|
9月前
|
前端开发 JavaScript NoSQL
使用 Node.js、Express 和 React 构建强大的 API
本文详细介绍如何使用 Node.js、Express 和 React 构建强大且动态的 API。从开发环境搭建到集成 React 前端,再到利用 APIPost 高效测试 API,适合各水平开发者。内容涵盖 Node.js 运行时、Express 框架与 React 库的基础知识及协同工作方式,还涉及数据库连接和前后端数据交互。通过实际代码示例,助你快速上手并优化应用性能。
|
10月前
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
10月前
|
JavaScript 前端开发 API
JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等,array.map()的使用详解(附实际应用代码)
array.map()可以用来数据转换、创建派生数组、应用函数、链式调用、异步数据流处理、复杂API请求梳理、提供DOM操作、用来搜索和过滤等,比for好用太多了,主要是写法简单,并且非常直观,并且能提升代码的可读性,也就提升了Long Term代码的可维护性。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
10月前
|
JavaScript 前端开发 Java
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
柯里化是一种强大的函数式编程技术,它通过将函数分解为单参数形式,实现了灵活性与可复用性的统一。无论是参数复用、延迟执行,还是函数组合,柯里化都为现代编程提供了极大的便利。 从 Redux 的选择器优化到复杂的数据流处理,再到深度嵌套的函数优化,柯里化在实际开发中展现出了非凡的价值。如果你希望编写更简洁、更优雅的代码,柯里化无疑是一个值得深入学习和实践的工具。从简单的实现到复杂的应用,希望这篇博客能为你揭开柯里化的奥秘,助力你的开发之旅! 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一
|
10月前
|
数据采集 JavaScript 前端开发
JavaScript中通过array.filter()实现数组的数据筛选、数据清洗和链式调用,JS中数组过滤器的使用详解(附实际应用代码)
用array.filter()来实现数据筛选、数据清洗和链式调用,相对于for循环更加清晰,语义化强,能显著提升代码的可读性和可维护性。博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~