算法简单总结

算法:时间复杂度和空间复杂度?时间复杂度和空间复杂度取舍?哪些时间复杂度是需要被优化的?优化的方法是什么?时间复杂度看最高的那个复杂度?

数据结构:有哪些数据结构?关系式是什么?
在这里插入图片描述

一、时间复杂度

1. O(1) 常数复杂度
不需要任何运算,其实就是一次运算。
2. O(n) 线性复杂度
循环语句,从1循环到n,不管n为多少,只要循环n次,与n一个数量级,时间复杂度均为n。
在这里插入图片描述
注:复杂度看最高的那个

let a = 0;    //时间复杂度为O(1);
a += i;       //时间复杂度为O(1);

循环时间复杂度是O(n),那么嵌套循环时间复杂度是O(n²)

3. O(n²) 平方复杂度
在这里插入图片描述
注意
(1):O(n)+O(n)=O(2n) 仍是O(n),前面的系数2忽略;
(2):继承循环共同完成一个循环,仍是O(n);
在这里插入图片描述

在这里插入图片描述
4. O(logn) 和 O(nlogn) 时间复杂度
与一些特定解题算法相关联,如常见的4中算法的时间复杂度:
二分查找:O(logn)
二叉树遍历:O(n) 因为每个节点仅遍历一次
排序查找/二维矩阵查找:O(n) 若一维则是O(logn)
排序:O(nlogn)
在这里插入图片描述
5. O(n³) 和 O(n!) 时间复杂度
常需要优化的
在这里插入图片描述

二、空间复杂度

在解题中,创建的变量、数组、链表等,为方便解题的数据结构,增加了空间复杂度,比如var、let、const定义了一个变量,里面存放某些值。

1. O(1) 空间复杂度
在这里插入图片描述
2. O(n) 空间复杂度
在这里插入图片描述
注意:(1)是自己创建的,不是题目给的。(2)一个数组里的数是若固定的,就不是O(n),而是O(1):比如数组里有两个数。

3. O(n²) 空间复杂度

三、时间复杂度和空间复杂度的取舍

一般取时间复杂度低的,因为空间内存相对时间较廉价一些,除非题目说明要求局限在这个空间中,如:原地算法、或不增加数据结构等。

四、复杂度优化方法

在这里插入图片描述

五、数据结构

1. 数组

  1. 访问任何一个未知的数组元素,时间复杂度都为O(1),一次操作即可,是硬件保证的;
  2. 但是删除、插入数组元素,要动后面所有的元素,因此时间复杂度都为O(n),但若插入的元素位置在数组的最后一个,则时间复杂度都为O(1);
  3. 那么如何改进数组的删除和插入呢?
    ------->链表:单链表、双链表

2. 链表

  1. 单链表:每个元素,它的指针指向它的后期节点,一般用next指针,由于指针的存在,则删除和插入比较容易,时间复杂度为O(1);但是访问较慢,时间复杂度为O(n),从头到尾访问,与数组相反;
    在这里插入图片描述
    链表每个节点node包含两部分,第一部分存储的是值data,第二个部分是指针next;

  2. 双链表:有next指针和previous指针;删除和插入仍为时间复杂度为O(1);查询仍为时间复杂度为O(n)

  3. 实战项目力扣206------反转链表

3. 栈(Stack)、队列(Quene)

  • 查询时间复杂度均为O(n)插入和删除的时间复杂度均为O(1)
  • 栈(Stack) :先进后出;
  • 队列(Quene): 先进先出;
  • 实战------力扣232、225栈实现队列或用队列实现栈

4. 优先队列(Priority Quene)

  • 正常进,按优先级出(元素大小、元素出现次数等);
  • 实现机制:堆(heap)、二叉搜索树;
  • 实战------力扣703、239

5. 映射(Map)、集合(Set)

ES6中新增的存储数据的两个方式:Map、Set;虽然JS中的Object也是用(key:value)存储数据的,与hashMap类似,但相对Object的优点是:(1)纯hash,性能比Object好很多;(2)本身提供的一些方法,高效简介;(3)与java中的用法类似;

1. 映射(Map)
与Object存储数据类似(Key,Value)。

1)映射就是存储`(键,值)数据对的数据结构`(Key,Value)。根据键(Key),寻找值(Value);
(2)有序映射中的键具有顺序性,基于搜索树实现;
(3)无序映射中的键没有顺序性,基于哈希表实现;
(4`key不可以重复,value可以重复`;
(5`Map` 可以直接利用之前学习的`链表、二叉搜索树`AVL树、红黑树)等数据结构来实现;

2. 集合(Set)

1)不存放重复的元素;
(2)常用于去重;
(3)存放新增IP,统计新增IP 量;
(4)存放词汇,统计词汇量;
(5)集合(Set)可用动态数组、链表、二叉搜索树(AVL树、红黑树)来实现;


在这里插入图片描述
补充:箭头函数用法
在这里插入图片描述
3. 哈希表、哈希函数、哈希碰撞

  • 哈希表
    哈希表可以存储各种类型的数据,当我们从哈希表中查找所需要的数据时,理想情况是不经过任何比较,一次存取便能得到所查记录,那就必须在记录的存储位置(value)和它的关键字(key)之间建立一个确定的对应关系 f,使每个关键字和结构中一个唯一的存储位置相对应。(关键字Key就是所要存储的数据存储位置value相当于数组的索引);

  • 当然,可以把哈希表理解为一个数组,每个索引value关键字key(数据本身)通过哈希函数得到;
    链接:https://www.jianshu.com/p/4e64fce04a38

  • “散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

  • 哈希函数
    给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。”

  • 哈希表是数组的一种扩展,没有数组,就没有哈希表;数组中查找某个数据时,要从头开始查找,麻烦,而哈希表通过哈希函数可以直接查找到;

  • 哈希碰撞
    通过哈希函数计算出的索引,即使关键字不同,索引也会有可能相同。这就是哈希冲突;

4. 实战

力扣-----242    变位词
力扣-----1      两数之和    用set解
力扣-----15     三数之和
力扣-----18     四数之和

6. 树和图

1. 字典和数组都是线性结构

1)字典和数组,链表都是按照位置来存储数据的,例如字段是通过哈希计算下标,数组是使用下标,链表则是一个一个的链接在一起;
(2)字典和数组,链表都是 实现的几乎都是一对一的结构,既数据之间的关系的关系是一一对应。

2. 树

上述的数据结构几乎是一对一的,而实际中常常存在一对多或者是多对多的情况。

原文链接:https://blog.csdn.net/iamsongyu/article/details/101775453

3. 树的分类 和 图的遍历(深度优先遍历、广度优先遍历)

见参考链接:https://blog.csdn.net/JonyHwang/article/details/80956840

  • (1)满二叉树(full binary tree):除了叶节点,其它节点都有左右子节点;
  • (2)完全二叉树(complete binary tree):若设二叉树的高度为h,除第 h 层外(最后一层),其它各层 (1~h-1) 的结点数都达到最大个数,且最后一层节点集中在左边,这就是完全二叉树。
  • (3)二叉搜索树(binary search tree): BST 也被称为二叉排序树,是一种特殊类型的容器: 在内存中存储“项目”(例如数字,名称等)的数据结构。它们允许快速查找、添加和删除项目,所有左子树结点的元素小于根节点的数据,所有右子树结点的元素大于根节点数据。常与递归相关联。
  • 4)平衡二叉树(AVL树): 是一种特殊的二叉排序树。AVL树或者是一棵空树,或是具有以下性质的二叉树:
1)左子树和右子树都是平衡二叉树;
(2)左子树和右子树的深度(高度)之差的绝对值不超过1

在这里插入图片描述

  • (5)红黑树:红黑树也是一种自平衡的二叉查找树。
	 1.每个结点要么是红的要么是黑的。(红或黑)
	 2.根结点是黑的。  (根黑)
	 3.每个叶结点(叶结点即指树尾端NIL指针或NULL结点)都是黑的。  (叶黑)
	 4.如果一个结点是红的,那么它的两个儿子都是黑的。  (红子黑)
	 5.对于任意结点而言,其到叶结点树尾端NIL指针的每条路径都包含相同数目的黑结点。(路径下黑相同)


保证红黑树满足它的基本性质,就是在调整数据结构自平衡。
红黑树自平衡的调整操作方式就有旋转变色两种

原文链接:https://blog.csdn.net/wannuoge4766/article/details/83998377

  • (6)二叉树的遍历方式
先序遍历:先根节点->遍历左子树->遍历右子树

中序遍历:遍历左子树->根节点->遍历右子树

后序遍历:遍历左子树->遍历右子树->根节点

在这里插入图片描述
4. 红黑树:特性?旋转?
见参考链接:
https://blog.csdn.net/qq_36610462/article/details/83277524

7. 实战----力扣704 二分查找

[-1,0,3,5,9,12]     target=9

(1)给定一个数组,和一个目标值,在数组中查找该值,若找到返回该值对应下标;找不到,返回-1;
(2)看到排序好的数组,考虑二分搜索树。
或者,排好序数组,稍作一些变化,也可考虑二分查找方法。
但若是个完全乱序的数组,不适合二分查找。
(3)二分搜索:利用排好序的数组,直接比较数组中间(下标用mid表示)的数值与目标值,直接砍掉数组一半的值,再接着比较,时间复杂度O(logn);
而不是一个一个搜索,时间复杂度是O(n);

  • 防止结果超过整型数的最大值;mid、left、right是数组下标

    在这里插入图片描述
  • Math.floor.mid 取mid值的向下值;
    在这里插入图片描述
  • 返回值为-1情况时:
    在这里插入图片描述
  • 考题:left、right根据题有时会等于mid值,变化,防止边界问题、死循环。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值