1. 通俗地讲

  • 算法是解决计算问题的方法

2. 算法的五大特性

  1. 输入总数 >= 0
  2. 输出数量 >= 1
  3. 有穷性
  4. 确定性
  5. 可行性

3. 众所周知的“公式”

程序 = 数据结构 + 算法

4. 举个例子

例 1. 百钱买百鸡

公鸡,五钱一只;母鸡,三钱一只;小鸡,一钱三只。

一百钱买一百只鸡,如何买?

1. 数学解法

解:设购买公鸡 x 只,母鸡 y 只,小鸡 z 只

\[\left\{ \begin{aligned} x + y + z = 100 \\ 5x + 3y + \frac z3 = 100 \end{aligned} \right.
\]

2. C 的解法

#include <stdio.h>

void buy_chicken();

int main() {
buy_chicken(); return 0;
} void buy_chicken() {
int cocks = -1, hens, chicks;
while (cocks < 20) {
cocks++;
hens = -1;
while (hens < 33) {
hens++;
chicks = 100 - cocks - hens;
if (chicks % 3) {
continue;
}
if (5*cocks + 3*hens + chicks/3 == 100) {
printf("百钱可买公鸡 %2d 只,母鸡 %2d 只,小鸡 %d 只\n", cocks, hens, chicks);
}
}
}
}

3. Python 的解法

# coding:utf-8

def buy_chicken():
for cocks in range(20):
for hens in range(33):
chicks = 100 - cocks - hens
if chicks % 3 == 0 and 5*cocks + 3*hens + chicks//3 == 100:
print(f"百钱可买公鸡 {cocks:>2} 只,母鸡 {hens:>2} 只,小鸡 {chicks} 只")
return None if __name__ == "__main__":
buy_chicken()

4. Java 解法

public class BaiJiwenti {
public static void main(String[] args) {
buy_chicken();
} public static void buy_chicken() {
for (int x=0; x<20; x++) {
for (int y=0; y<33; y++) {
int z = 100 - x - y;
if (z % 3 == 0 && (5*x + 3*y + z/3 == 100 )) {
System.out.printf("百钱可买公鸡 %2d 只,母鸡 %2d 只,小鸡 %d 只\n", x, y, z);
}
}
}
}
}

5. 小结

  • 对于“百鸡问题”这一类甚至更多的问题,虽然不同语言的语法不尽相同,但解起来思路一致,关键几句更是如出一辙

5. 算法衡量

  • 衡量算法应该剔除机器配置,运算数量等无关因素

5.1 有这样两个指标

  • 时间复杂度 T(n)
  • 空间复杂度 S(n)

5.2 大 O 记法

  • 对于单调的整数函数,如果存在一个整数函数 g 和实常数 c (c>0),使得对于充分大的 n 总有

    f(n) <= c * g(n)

    即函数 g 是 f 的一个渐进函数(忽略常数),记为 f(n) = O(g(n))

    即在趋向无穷的极限意义下,函数的增长速度受到函数 g 的约束

    即函数 f y与函数 g 的特征相似

5.3 时间复杂度及其他

5.3.1 定义

  • 假设存在函数 g,使得算法 A 处理规模为 n 的问题示例所用时间为 T(n) = O(g(n)),则称 O(g(n)) 为算法 A 的渐进时间复杂度,简称时间复杂度,记为 T(n)

5.3.2 此外,还有

  1. 最优时间复杂度
  2. 最坏时间复杂度
  3. 平均时间复杂度
  • 一般关注最坏时间复杂度

5.3.3 时间复杂度计量规则

  • 基本操作,如只有常数项, 时间复杂度是 1
  • 顺序结构,时间复杂度按加法计算
  • 循环结构,按乘法计算
  • 分支结构, 取最大值
  • 得到一个方程式,然后在做化简,取方程的阶

5.3.4 判断一个算法的效率

  • 关注操作数量的最高次项,其余可忽略
  • 若没特殊说明,我们所分析的算法时间复杂度一般指最坏的复杂度

5.3.5 其他

  • “大样本统计方法”、“渐进等价”、“渐进展开”等数学概念我就略过了
  • 题外话:大家都知道“复”应该读第四声,但在这个短语中“复”读第三声超顺;类似的还有“标志符”、“char”等

6. 举例分析

# coding:utf-8

import sys
from time import perf_counter_ns def cal_time(func):
def in_():
start = perf_counter_ns()
name = func()
stop = perf_counter_ns()
print(f">>> {name}'s cost times: {stop - start}\n")
return in_ @cal_time
def solve1():
for cocks in range(101):
for hens in range(101):
for chicks in range(301):
if cocks + hens + chicks == 100 \
and 5*cocks + 3*hens + chicks/3 == 100:
print(f"公鸡 {cocks:>2} 只,母鸡 {hens:>2} 只,小鸡 {chicks} 只")
return sys._getframe().f_code.co_name @cal_time
def solve2():
for cocks in range(20):
for hens in range(33):
chicks = 100 - cocks - hens
if chicks % 3 == 0 and 5*cocks + 3*hens + chicks//3 == 100:
print(f"公鸡 {cocks:>2} 只,母鸡 {hens:>2} 只,小鸡 {chicks} 只")
return sys._getframe().f_code.co_name if __name__ == "__main__":
solve1()
solve2()
  • 不同的机子运算速度不同,但可以肯定的是 solve2() 比 solve1() 快,而且快挺多
  • 简单地说,solve1() 的循环嵌套比 solve2() 的多一层,这就决定了它的时间复杂度要多一个幂次
    • solve1() 的 T(n) = O(mnk)
    • solve2() 的 T(n) = O(mn)

[DS+Algo] 001 先简单说说算法的更多相关文章

  1. 基于BP神经网络的简单字符识别算法自小结(C语言版)

    本文均属自己阅读源代码的点滴总结.转账请注明出处谢谢. 欢迎和大家交流.qq:1037701636 email:gzzaigcn2009@163.com 写在前面的闲话: 自我感觉自己应该不是一个非常 ...

  2. 简单排序算法 C++类实现

    简单排序算法: 冒泡排序 插入排序 选择排序 .h代码: // // SortClass.h // sort and selection // // Created by wasdns on 16/1 ...

  3. 简单排序算法设计(Java)

    总共有八种排序算法,还是慢慢看吧 1.简单排序算法 简单排序算法就是设置标兵,逐个比较数,然后查找插入位置,插入 public static void p(int[] a){ for(int i=0; ...

  4. 简单的算法题, Find Minimum in Rotated Sorted Array 的Python实现。

    简单的算法题, Find Minimum in Rotated Sorted Array 的Python实现. 题目: Suppose a sorted array is rotated at som ...

  5. 一个简单的算法,定义一个长度为n的数组,随机顺序存储1至n的的全部正整数,不重复。

    前些天看到.net笔试习题集上的一道小题,要求将1至100内的正整数随机填充到一个长度为100的数组,求一个简单的算法. 今天有空写了一下.代码如下,注释比较详细: using System; usi ...

  6. 教你用Python实现简单监督学习算法

    教你用Python实现简单监督学习算法 监督学习作为运用最广泛的机器学习方法,一直以来都是从数据挖掘信息的重要手段.即便是在无监督学习兴起的近日,监督学习也依旧是入门机器学习的钥匙. 这篇监督学习教程 ...

  7. 简单数学算法demo和窗口跳转,关闭,弹框

     简单数学算法demo和窗口跳转,关闭,弹框demo <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&quo ...

  8. [DS+Algo] 005 三种简单排序及其代码实现

    目录 1. 冒泡排序 BubbleSort 1.1 算法描述 1.2 性能分析 1.3 Python 代码实现 2. 选择排序 SelectionSort 2.1 算法描述 2.2 选择排序的主要优点 ...

  9. [DS+Algo] 006 两种简单排序及其代码实现

    目录 1. 快速排序 QuickSort 1.1 步骤 1.2 性能分析 1.3 Python 代码示例 2. 归并排序 MergeSort 2.1 步骤 2.2 性能分析 2.3 Python 代码 ...

随机推荐

  1. UI控件Telerik UI for Silverlight发布R2 2019|附下载

    Telerik UI for Silverlight包含了超过100个能用于纯Silverlight应用程序中或能作为现有ASP.NET应用程序的一部分的UI控件.通过与我们的WPF控件共享一个相同的 ...

  2. SQL语句 函数

    6.4 Functions   6.4.1 Numeric abs/mod 绝对值/求模 sqrt/power/exp 求幂 ceil/floor/round 取整 trunc 截取小数点 sin/c ...

  3. @ResponseStatus注解作用

    @ResponseStatus注解有两种用法,一种是加载自定义异常类上,一种是加在目标方法中 这里我们说一下加在目标方法上的这种情况,注解中有两个参数,value属性设置异常的状态码,reaseon是 ...

  4. Vue props双向绑定

    props是不能改变的 项目里遇到一个问题,就是props的组件内是不能改变,就像react中的props值也是不能改变的, 所以我在用的时候竟然忽略了这个点.真的要反省反省, 下面就是这个报错的问题 ...

  5. HDU-2732-leapin'Lizards(最大流, 拆点)

    链接: https://vjudge.net/problem/HDU-2732 题意: Your platoon of wandering lizards has entered a strange ...

  6. ESP8266--TCP Server

    所谓server,可以简单理解为提供服务,提供数据的一个地方 ESP8266上建立一个server是比较简单的,不过是属于局域网内的server,因为真正意义上的server并不是这样的,大伙了解一个 ...

  7. js对对象增加删除属性

    1.首选创建一个对象 var a={}; 2.然后对这个对象赋值 a.name='zhouy';console.log(a);var age="age";a[age]=26;con ...

  8. linux-文件系统-5

    cat /proc/partions cat /proc/mounts mount [options] -o [option] -t 文件类型 设备 挂载目录 设备: (1)设备文件:例如/dev/s ...

  9. entry 遍历 Map 元素

    1.书写类 import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; public class test ...

  10. 【知识】定时器setTimeout/setInterval执行时this指针指向问题

    [问题描述] setTimetout/setInterval中this指针指向window,以下是一个小demo: var demoChange = { key: true, changeFun() ...