在刷LeetCode-1TwoSum的时候,有个人在论坛留言,大致意思如下:

我的算法击败了90%的人,O(nlgn)算法比O(n)算法快。

我觉得这个人是不懂算法的。让我一步一步解释。

# O的含义

通俗的说,O表示忽略系数的复杂度上限,常常用一个量级表示,比如n,nlgn。

# 忽略的系数重要吗

重要。我觉得《算法》比《算法导论》优秀的原因之一是,作者用实例证明,在不少情况下,复杂度之前的系数很重要。比如,系数可以导致O(n^2)的插入排序可以比O(nlgn)快速排序快。

可以看一个例子。

// 伪代码,程序1
void add(int num)
{
num++;
num++;
num++;
num++;
num++;
num++;
num++;
num++;
num++;
num++;
} void add(int[] nums)
{
for (int i = ; i < n; i++)
add(nums[i]);
}
// 伪代码,程序2
void add(int num)
{
num++;
} void add(int[] nums)
{
for (int i = ; i < n; i++)
for (int j = ; j < n; j++)
add(nums[i]);
}

程序1的时间复杂度为O(n),程序2的时间复杂度为O(n^2)。如果从O来看,程序2的执行速度一定会比程序1快。

实际上速度相当。假设nums的大小为10,程序1要执行10 * 10 = 100次i++,程序2同样执行10 * 10 * 1 = 100次i++。

原因就在于,程序1需要的时间是10 * n,系数很大为10,而程序2需要的时间是1 * n ^ 2,系数很小为1。

# 那个人错在哪里

或许不是他的错,是LeetCode的错。

渐进时间一定要在系数相对于数据量比重很小很小的时候,才有用。像排序算法一类比较简单的算法,需要上十万的数据量,才能体现出复杂度为nlgn和n^2的细小区别。

这个人用了很聪明很简单的算法,没有用复杂的数据结构,全是基本变量,时间复杂度为O(nlgn)。而O(n)用了Hashtable,共有n个数,对于每个数,Hashtable里面有很多计算的过程,系数很大。

此题,LeetCode可能单个数据集不是很大,系数显得格外重要。

# 链接

Q: https://leetcode.com/problems/two-sum/

A: https://github.com/mofadeyunduo/LeetCode/tree/master/1TwoSum

(请多多支持我刚刚建立的GitHub和博客,谢谢,有问题可以邮件609092186@qq.com或者留言,我尽快回复)

我们为什么不能只用O记号来谈论算法?的更多相关文章

  1. 用大O记号法测量算法的效率(Algorithm efficiency Asymptotic notation Big O notation)

    为什么要了解算法的效率? 一般来说,编程就是把各种已知的算法代入到自己的代码当中,以此来解决问题.因此,了解各种算法的效率对于我们选择一个合适的算法有很大帮助. 算法的效率由什么确定? 从算法分析的理 ...

  2. 当我们谈论算法我们在谈论什么:由疫情核酸检测想到的分治算法(Divide-and-Conquer)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_159 北京的疫情一波未平一波又起,由此看来,战"疫"将是一场旷日持久的战争,绝不能掉以轻心.轻易言胜.病毒随时 ...

  3. JVM 平台上的各种语言的开发指南

    JVM 平台上的各种语言的开发指南 为什么我们需要如此多的JVM语言? 在2013年你可以有50中JVM语言的选择来用于你的下一个项目.尽管你可以说出一大打的名字,你会准备为你的下一个项目选择一种新的 ...

  4. 用 C# 读取二进制文件

    当想到所有文件都转换为 XML时,确实是一件好事.但是,这并非事实.仍旧还有大量的文件格式不是XML,甚至也不是ASCII.二进制文件仍然在网络中传播,储存在磁盘上,在应用程序之间传递.相比之下,在处 ...

  5. Analysis of Algorithms

    算法分析 Introduction 有各种原因要求我们分析算法,像预测算法性能,比较不同算法优劣等,其中很实际的一条原因是为了避免性能错误,要对自己算法的性能有个概念. 科学方法(scientific ...

  6. CSS3全览_动画+滤镜

    CSS3全览_动画+滤镜 目录 CSS3全览_动画+滤镜 1. 列表和生成的内容 2. 变形 3. 过渡 4. 动画 5. 滤镜, 混合, 裁剪和遮罩 6. 针对特定媒体的样式 作者: https:/ ...

  7. NHibernate系列文章二:创建NHibernate工程

    摘要 这篇文章介绍了如何创建一个简单的使用NHibernate的控制台应用程序,包括使用NuGet.简单的配置.单表映射.对NHibernate配置文件添加智能提示.使用ISessionFactory ...

  8. [ay原创作品]用wpf写了个模仿36Kr网站登录背景的效果

    这里我借鉴了,上周比较火的一个前端文章,人家用js去写的,地址 自己用wpf也写了一个,但是它的  粒子比较,然后连线算法真的很差,他创建了一个加入鼠标点的集合,2个集合进行比较,并且粒子会向鼠标靠近 ...

  9. 学习理论之正则化(Regularization)与模型选择

    一.引言 对于一个学习问题,可以假设很多不同的模型,我们要做的是根据某一标准选出最好的模型.例如,在多项式回归中,对于我们的假设模型,我们最要紧的是决定 k 到底取多少合适,能不能有一种方法可以自动选 ...

随机推荐

  1. UML课程复习重点

    第一章 一.UML图示建模工具 二.UML--统一建模语言,以图形符号为基础,描述软件模型既简洁又清晰.它不是开发方法,是独立于任何开发方法之外的语言.它用于描述软件系统分析.设计和实施中的各种模型. ...

  2. .NET 基础 一步步 一幕幕[面向对象之方法、方法的重载、方法的重写、方法的递归]

    方法.方法的重载.方法的重写.方法的递归 方法: 将一堆代码进行重用的一种机制. 语法: [访问修饰符] 返回类型 <方法名>(参数列表){ 方法主体: } 返回值类型:如果不需要写返回值 ...

  3. 博客使用BOS上传图片

    1.博客平台的选定 从大学开始做个人主页算起,最开始是使用html,CSSS写简单的页面,后面大学毕业之后接触到了WordPress,就开始用WordPress搭建网站.现在还维护着一个农村网站.ht ...

  4. 如果你也会C#,那不妨了解下F#(7):面向对象编程之继承、接口和泛型

    前言 面向对象三大基本特性:封装.继承.多态.上一篇中介绍了类的定义,下面就了解下F#中继承和多态的使用吧.

  5. setCapture、releasCapture 浅析

    1. setCapture 简介 setCapture可以将鼠标事件锁定在指定的元素上,当元素捕获了鼠标事件后,该事件只能作用在当前元素上. 以下情况会导致事件锁定失败: 当窗口失去焦点时,锁定的事件 ...

  6. 封装集合(Encapsulate Collection)

    封装就是将相关的方法或者属性抽象成为一个对象. 封装的意义: 对外隐藏内部实现,接口不变,内部实现自由修改. 只返回需要的数据和方法. 提供一种方式防止数据被修改. 更好的代码复用. 当一个类的属性类 ...

  7. BPM流程中心解决方案分享

    一.需求分析 在过去办公自动化的浪潮中,很多企业已经实施了OA流程,但随着客户的发展和对流程管理的越来越重视, 客户对流程应用需求越来越深 入,您可能面临以下需求: 1.流程功能不能满足需求,包括流程 ...

  8. 「译」JUnit 5 系列:环境搭建

    原文地址:http://blog.codefx.org/libraries/junit-5-setup/ 原文日期:15, Feb, 2016 译文首发:Linesh 的博客:环境搭建 我的 Gith ...

  9. 跟着老男孩教育学Python开发【第四篇】:模块

    双层装饰器示例 __author__ = 'Golden' #!/usr/bin/env python # -*- coding:utf-8 -*-   USER_INFO = {}   def ch ...

  10. LVM基本介绍与常用命令

    一.LVM介绍LVM是 Logical Volume Manager(逻辑卷管理)的简写,它是Linux环境下对磁盘分区进行管理的一种机制LVM - 优点:LVM通常用于装备大量磁盘的系统,但它同样适 ...