时间复杂度csdn(js indexof时间复杂度)

我们在工作中免不了要筛查、遴选「数据」,在处理数据的时候就需要涉及到算法,而判断算法的好与坏,主要标准是时间复杂度和空间复杂度。

时间复杂度其实是一个函数,它来描述算法需要运行多长时间,用大 O 符号来表述。一般来讲,我们都假设输入值是无穷大,一直可增长的,所以也可以说它是渐进的。

我们可以通过预估代码的执行次数,来做出复杂度的判断。常见的有O(1)、O(n)、O(n2)、O(logn)…

「时间复杂度」执行一个算法的时间成本,随着 n 的值越来越大,算法之间的差异就能体现出来。

「空间复杂度」执行一个算法所需要的空间成本,当需要存储一些临时数据时,就涉及到了空间成本;

举个「生活」例子:

假如说你要搬家,从 A 点搬到 B 点,现在呢,给出两种解决方案:

1、自己搬,一次次用行李箱搬运,需要来回运 10 次;

2、搬家公司,把所有东西放到货车上,一次性搬走;

这两种方法就很好的表现了搬家这个事件的时间复杂度与空间复杂度。第一种方法没占用什么空间,但一直占用着时间,第二种利用了空间,在时间上大大节省了。

在搬家这个事件中,有很明显的时间和空间上的取舍存在。这和我们在工作中处理数据时所思考的一样,怎样才能做到既省时间,又省空间呢。「算法」就在其中发挥了作用。而评判算法的好与坏,就可以用渐进式的时间复杂度和空间复杂度来表示。

常数时间 O(1)

{  let i = 1;  let b = ++i;}

无论代码有多少行,只要没有循环,那执行次数就是一次。时间复杂度都记为 O(1)。

线性时间 O(n)

    for(let i=0;i<n;i++){  //执行 i 的操作}

    这样的代码我们应该写的最多,循环次数为 n 次,n有多大,就执行多少次。n 为5就执行5次,n 为50就执行50次。

    我们的假设是 n 为无穷大,所以时间复杂度都可称为「渐进」,所消耗时间都是由 n 决定。

    平方时间 O(n2)

    for(let i=0; i<len; i++){  for(let j=0; j<len2; j++){    //执行 i 和 j 的操作  }}

    平方时间一般指双层循环,如果 len 和 len2 各为 10 的话,那执行次数就是 100 次,如果画一张 100 * 100 的地图,那执行次数就为 10000 次。由于平方计算量太大,在工作中慎重使用

    还有对数时间、线性对数时间、指数时间等等 … 

    我们来看一个 LeetCode 算法题「两数之和」

    给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标。
    你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
    你可以按任意顺序返回答案。
    输入:nums = [2,7,11,15], target = 9
    输出:[0,1]
    解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
    https://leetcode-cn.com/problems/two-sum/

    来看第一个解法:

    var twoSum = function(nums, target) {    //nums 整数数组需要依次遍历,下标0去找下标1下标2... 最后算出 target 是否相等。如果算完,需要向前移动一个下标    let _result = [];    for( let currentIndex = 0;currentIndex < nums.length; currentIndex++){        nums.forEach((_,index)=>{            let _nums = nums[currentIndex] + nums[currentIndex + index + 1];            if( _nums === target ){                _result = [currentIndex, currentIndex + index + 1]            }        })    }    return _result};

    看下 LeetCode 最终单测结果:

      52/52个通过测试用例执行用时: 172 ms内存消耗: 39.6 MB

      下面,我们再来看另一个解法:

      var twoSum = function(nums, target) {    let _result = [];    for( let currentIndex = 0;currentIndex < nums.length; currentIndex++){        let _num = target - nums[currentIndex];        nums.forEach((item,index)=>{            if( currentIndex >= index ) return;            if( item === _num ){                _result = [currentIndex,index];            }        })        if( _result.length ){            break;        }    }    return _result};
        52/52个通过测试用例执行用时: 76 ms内存消耗: 37.5 MB
        在时间上节省了一倍,可见算法思路多么重要,不同的算法之间差异非常高。

        参考资料:
        《漫画算法》
        https://zh.wikipedia.org/wiki/%E6%97%B6%E9%97%B4%E5%A4%8D%E6%9D%82%E5%BA%A6
        https://zhuanlan.zhihu.com/p/50479555

        https://www.jianshu.com/p/f4cca5ce055a


        图片授权基于 www.pixabay.com 相关协议

        原创文章,作者:小道研究,如若转载,请注明出处:https://www.sudun.com/ask/34485.html

        (0)
        小道研究's avatar小道研究
        上一篇 2024年4月10日 下午2:47
        下一篇 2024年4月10日 下午2:49

        相关推荐

        发表回复

        您的邮箱地址不会被公开。 必填项已用 * 标注