算法基础知识总结(基础算法)

article/2025/11/10 20:36:27

算法基础知识总结

Efficient procedures for solving problems on large inputs.

一、基础算法

1、快速排序

1、类别:快速排序是一种 交换排序,冒泡排序也是一种交换排序。

2、原理:将未排序的元素根据一个作为基准的主元(Pivot)分成两个子序列,其中一个子序列的数都大于主元,另一个子序列的数都小于主元,然后递归地对两个子序列进行排序。

3、本质:分而治之的思想。减小问题规模再分别进行处理。

4、时间复杂度:最好和平均: O ( N l o g N ) O(NlogN) O(NlogN), 最差 O ( N 2 ) O(N^2) O(N2) 。不适合用于数据量比较小的时候。数据比较小的时候可以用插入排序。

5、基本步骤:

第一步:设置左右指针和主元

第二步:根据快速排序的原理移动左右指针,当指针停止移动并且没有错位时交换两个指针指向的元素

第三步:递归解决左右两边

6、代码注意点:

(1)注意程序停止的条件:当要排序的序列左下标大于等于右下标时无法排序,则停止。
(2)所有比较都不带等于号!

2、归并排序

1、原理:将长度为N的序列看成N个长度为1的子序列,对相邻两个子序列进行归并操作不断迭代直到序列长度变成N。

2、核心:归并操作+分而治之

3、时间复杂度: O ( N l o g N ) O(NlogN) O(NlogN)

4、基本步骤:

第一步:递归地排序左子列

第二步:递归地排序右子列

第三步:归并

​ (1)创建一个空数组用于存放排序结果

​ (2)让两个指针分别指向已经排好序的子序列的第一个位置,然后依次比较两个指针指向的元素,将较小的放入空数组,并将当前指针后移一位。重复该步骤

第四步:扫尾

5、代码注意点:

(1)需要创建一个新的空数组来存放比较结果。两个指针的开始位置应该是两个序列的开头。
(2)判断逆元的时候要用 res += mid - i + 1 而不能 res += j - i,因为 j 在循环中不断变化。

3、归并排序与快速排序

1、比较:快速排序为什么快?归并排序时间复杂度和快速排序相同,并且快速排序最差的时候会是 O ( N 2 ) O(N^2) O(N2)

首先时间复杂度忽略了系数。事实上快速排序的系数是最小的,并且它不需要开辟额外的空间,因此总体来说在平均意义上快速排序是表现最好的。而诸如堆排序,几乎不会比较相邻元素对cache不友好很少被采用。

2、代码注意点:

(1)根据快排的定义,我们需要将每个元素和主元比较,因此得首先计算出主元而不能写在循环里!int x = nums[(l + r) >> 1];

但是归并排序是依次比较两个指针指向的元素,所以需要在循环里一个一个比较。

4、整数二分

1、二分与单调性:有单调性的一定可以二分,但是能够二分的未必一定要有单调性(分段处理,使其满足在每一段解空间具备单调性)。

2、二分的本质:边界。如果定义了某个性质,使得某个边界的一边满足该性质,另一边不满足的话,二分法可以找到这个边界点。

3、基本步骤:

第一步:确定左右指针初始位置。

第二步:找到中点

第三步:根据是否满足性质移动左右指针。

4、代码注意点:

(1)应当在while循环内部定义中点,因为中点需要随着循环更新;

(2)循环结束的条件是左指针大于等于右指针;

(3)千万不能漏掉更新左右指针时的 else !!!!

(4)对于 l = mid; r = mid - 1的更新方式应该有:mid = (l + r + 1) >> 1!原因是,当 l = r - 1时,如果更新方式为:l = mid并且mid = (l + r) >> 1 = l就会发生死循环。但是如果mid = (l + r + 1) >> 1,就会更新:l = mid = r然后循环结束。
(5)对于check(mid)的两种模板,我们首先应该确定要找的答案满足什么样的边界性质。例如:
给定一个按照升序排列的长度为 n 的整数数组,以及 q 个查询。对于每个查询,返回一个元素 k 的起始位置和终止位置(位置从 0 开始计数)。
样例:a[6] = {1, 2, 2, 3, 3, 4},查找3的起始位置和终止位置。对于起始位置,它满足的性质可以是左边的数都小于自己,那么check函数为:a[mid] < 3,更新方式自然就是true: l = mid + 1; false: r = mid,它的性质也可以是右边的数都大于等于自己那么check函数为:a[mid] >= 3,更新方式为true: r = mid; false: l = mid + 1。对于终止位置,它满足的性质可以是左边的数都小于等于自己,那么check函数为:a[mid] <= 3,更新方式自然就是true: l = mid; false: r = mid - 1,它的性质也可以是右边的数都大于自己那么check函数为:a[mid] > 3,更新方式为true: r = mid - 1; false: l = mid

5、高精度加法

1、作用:解决两个超长整数相加的问题

2、基本思想:用数组存放加数和最终结果,手动模拟加法过程

3、代码注意点:

(1)定义vector时不能初始化长度,因为vector本身就是变长数组。

(2)数字应该倒着存储,以便于最后有进位时可以直接添加在数组最后,而不用把整个数组往后移动。

(3)add( ) 函数的参数是两个vector的引用!

(4)要记得比较两个加数的长度,应该遍历长度更长的一个,这样便于直接把答案添加到新的vector中

(5)循环结束后,记得把最后的进位添加到数组中

6、高精度减法

1、作用:解决两个超长整数相减的问题

2、基本思想:用数组存放数据,手动模拟减法过程

3、代码注意点:

(1)存放数据是依然是倒序

(2)在比较两个数的大小时应该从高位开始比较

(3)注意求差的小技巧:(t + 10) % 10

(4)注意最后”去 0“操作时结果的长度至少是1,因为有可能结果为0。

7、高精度乘法

1、作用:解决两个超长整数相乘

2、基本思想同上

3、代码注意点:

(1)乘法不用管数字的长度或者大小

(2)和加法一样要记得添加最后的进位

(3)和减法一样记得最后去0

8、高精度除法

1、作用:解决两个超长整数相除的问题

2、基本思想同上

3、代码注意点:

(1)依然是倒序存储

(2)在进行除法时,应该从高位开始。但是高位得到的结果可能会是前导0,所以还需要把 res 翻转然后来一个删除前导0操作,最后再倒序输出。

9、一维前缀和数组

1、前缀和数组:对于原数组 a [ N ] = [ a 1 , a 2 , a 3 , a 4 , . . . , a N ] a[N] = [a1, a2, a3, a4, ..., aN] a[N]=[a1,a2,a3,a4,...,aN] 有前缀和数组 b [ N ] = [ b 1 , b 2 , b 3 , b 4 , b 5 , . . . , b N ] , b i = ∑ k = 1 k = i a k b[N] = [b1, b2, b3, b4, b5,..., bN],\quad b_i = \sum_{k=1}^{k=i}a_k b[N]=[b1,b2,b3,b4,b5,...,bN],bi=k=1k=iak

2、作用:能快速地求出某一段区间的和

3、递推公式: b [ i ] = b [ i − 1 ] + a [ i ] b[i] = b[i - 1] + a[i] b[i]=b[i1]+a[i] 或者直接把数组a变成自己的前缀和数组: a [ i ] + = a [ i − 1 ] a[i] += a[i - 1] a[i]+=a[i1]

4、a数组在区间 [ l , r ] [l, r] [l,r] 的和为: b [ r ] − b [ l − 1 ] b[r] - b[l - 1] b[r]b[l1]

5、代码注意点:

(1)存储数组从下标1开始!

10、二维前缀和数组

1、概念与作用和一维前缀和数组雷同。

2、代码注意点:

(1)千万注意最开始定义数组长度N的时候不能超过太多,否则会报错。

11、一维差分数组

1、概念:求差分数组是求前缀和数组的逆运算。对于原数组 a [ N ] = [ a 1 , a 2 , a 3 , a 4 , . . . , a N ] a[N] = [a1, a2, a3, a4, ..., aN] a[N]=[a1,a2,a3,a4,...,aN] ,构造差分数组 b [ N ] = [ b 1 , b 2 , b 3 , b 4 , b 5 , . . . , b N ] , a i = ∑ k = 1 k = i b k b[N] = [b1, b2, b3, b4, b5,..., bN],\quad a_i = \sum_{k=1}^{k=i}b_k b[N]=[b1,b2,b3,b4,b5,...,bN],ai=k=1k=ibk

2、作用:在原数组的某一段区间加上一个数

3、构造思想:
b 1 = a 1 b 2 = a 2 − a 1 b 3 = a 3 − a 2 . . . b1 = a1\\ b2 = a2 - a1\\ b3 = a3 - a2\\ .\\.\\. b1=a1b2=a2a1b3=a3a2...
4、核心操作:只要 b i + c b_i + c bi+c 则从 a i a_i ai 开始往后的所有数都加上了c

12、二维差分数组

1、思想:和一维差分数组雷同。
在这里插入图片描述
在A点增加C的影响就是整个ACIG都被加了C,但是我们只希望ABDE被加C所以应该让BCIH和DFIG减去C,由于EFIG被减了两次所以再让它加上C。公式: s [ x 1 ] [ y 1 ] + = c s [ x 2 + 1 ] [ y 1 ] − = c s [ x 1 ] [ y 2 + 1 ] − = c s [ x 2 + 1 ] [ y 2 + 1 ] + = c s[x1][y1] += c\\ s[x2+1][y1]-=c\\s[x1][y2+1]-=c\\ s[x2+1][y2+1]+=c s[x1][y1]+=cs[x2+1][y1]=cs[x1][y2+1]=cs[x2+1][y2+1]+=c

13、双指针算法

1、精髓:优化暴力枚举,两个指针分别最多只遍历一边数组

14、离散化

1、概念:将N个在数轴上分布很稀疏的数映射到一个N维数组

2、作用:降低空间复杂度

3、基本步骤:

首先创建一个空的vector,把数据一次放入,完成映射

查找时,采用二分法即可。

4、代码注意点:

(1)离散化是保序的,记得映射完了之后要进行排序,否则很难查找。

15、区间合并

1、代码注意点:

(1)不要忘记合并最后的一个区间!!!


http://chatgpt.dhexx.cn/article/PxyOjdZ9.shtml

相关文章

算法基础知识

一、算法的定义 算法&#xff1a;对特定问题求解步骤的一种描述&#xff0c;是为解决一个或一类问题给出的一个确定的、有限长的操作序列。 二、算法与程序的区别与联系 区别&#xff1a; 程序&#xff1a;与某种编程语言有关&#xff0c;能直接在机器上运行。 算法&#xff1a…

算法基础简介

一、什么是算法 在数学领域&#xff0c;算法是为了解决某一类问题的公式和思想。 在计算机领域&#xff0c;本质是一些计算机指令&#xff0c;解决特定运算和逻辑问题。 算法的掌握程度&#xff0c;一方面可以检验程序员对计算机底层的了解&#xff0c;一方面也…

Unity 移动的几种方法(从某一点移动到另外一点)

对于unity的几种移动方法,在以下给出整理 1 方向*速度 2 vector.lerp 与目标点永远不会重合 3 vector.MoveTowards 会与目标点重合 4 translate方法 纯移动 5 WASD键盘方法 刚 体方法 7.鼠标方法 捕鱼达人 8.射线方法(指哪到哪) Controll…

Unity 控制物体移动

目录 1、通过改变物体的位置使物体移动 2、通过给物体施加力使物体移动 3、移动characterController以及碰撞检测 一、相关代码展示 1、通过改变物体的位置使物体移动 using System.Collections; using System.Collections.Generic; using UnityEngine;public class move …

unity3D人物移动的实现(一)

人物的移动&#xff0c;首先要考虑人物与地面的碰撞&#xff0c;碰撞发生的条件是&#xff0c;两者必须都为碰撞体&#xff0c;且至少有一方为刚体&#xff0c;为了方便&#xff0c;我们就给人物加上刚体属性和碰撞体。 1首先是碰撞体属性&#xff0c;人形使用胶囊碰撞体&#…

Unity让物体跟随鼠标移动

前言 最近在学习Unity&#xff0c;记录下学习的成果吧。本文最终结果是要实现一个小飞机跟随鼠标移动的效果。看下图片。 向量 在Unity中&#xff0c;每个对象都有自己的位置属性&#xff0c;组件叫做Transform,通过Transform可以获取对象的位置属性。在上面的实例中&#…

01_Unity常用的移动方法

文章目录 基础框架匀速移动变速移动自定义变速运动总结&#xff1a; 在制作一款游戏的时候&#xff0c;经常需要对物体的位置进行移动&#xff0c;我们希望这个移动是具有多样性的&#xff0c;并且可操作的。 C#中提供了非常丰富的移动代码工具&#xff0c;通过这些工具我们可以…

Unity点击物体后,移动到物体所在位置

Unity点击物体后&#xff0c;移动到物体所在位置 方法一&#xff1a;OnMouse检测&#xff08;需要Collider组件&#xff09; 脚本挂在被点击的物体上 using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement;/// <summary> /// 缺点…

Unity2D教程:人物移动

关注专栏&#xff0c;持续更新哦 教程总目录 按键 自带的Input有GetAxisRaw来获取按下按键后所对应的值&#xff0c;Input.GetAxisRaw(“Horizontal”)在按下D或右箭头返回1&#xff0c;A或左箭头返回-1&#xff1b;Input.GetAxisRaw(“Vertical”)同理。 Input.GetAxis会根…

Unity物体跟随鼠标移动

刚开始在将鼠标点转换为世界坐标时&#xff0c;我以为可以直接使用Unity的Camera.main.ScreenToWorldPoint( Input.mousePosition ) 就完事了&#xff0c;事实证明我想的太简单了。在我们使用这个API将鼠标屏幕点&#xff08;Screen&#xff09;转换成世界坐标&#xff08;Worl…

Unity中物体移动方法详解

一&#xff1a;Transform ——transform.Translate&#xff1a;不会考虑到碰撞transform.Translate(Vector3 targetPos&#xff0c;指定参照坐标系(默认为Space.Self)) ——transform.position&#xff1a;直接改变物体的坐标 二&#xff1a;刚体 ——MovePosition ——veloc…

【Unity】如何优雅地移动物体-8个方法

在游戏开发中&#xff0c;如何移动物体&#xff1f;是我们需要思考的事情。 Unity 引擎也提供了众多的方法&#xff0c;每个开发者的使用习惯也各不相同&#xff0c;所以往往不是很清楚在这种场景下哪种方式最好的或者最有效的。 那么&#xff0c;这篇文章&#xff0c;我想分享…

详解Unity的几种移动方式实现

前言 最近在学习如何制作 FPS 游戏&#xff0c;学习了如何使用角色控制器来控制角色的移动跳跃等等&#xff0c;结合之前学到的使用 transform&#xff0c;刚体等使物体移动&#xff0c;不同的移动方式适用于不同的场景&#xff0c;今天就来简要盘点一下各种移动方式以及其优劣…

unity物体四种移动方法总结

目录 一.通过修改位置来实现移动 二.通过物理系统实现位移 三.通过输入控制物体移动 一.通过修改位置来实现移动 利用修改Transform组件的position的两种常用方法。 1.使用Translate&#xff08;&#xff09;函数。 2.&#xff0c;直接指定新的位置 将上述两种方法在void …

详解Unity的移动控制实现

前言 上一篇写了数种Unity中的移动方式&#xff0c;有物理移动&#xff0c;有非物理移动等&#xff0c;这篇我们来谈谈Unity中的移动控制方式&#xff0c;来结合上一篇所说的方法&#xff0c;用起来。一般控制是通过获取用户输入来处理角色移动逻辑的&#xff0c;而用户输入的…

JSON数据和解析

JSON> JavaScript Object Notation JSON是一个字符串 常常用于网络传输数据的一种字符 json数据是一种轻量级的数据交换格式&#xff0c;它基于一个子集&#xff0c;采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语…

Android开发之JSON数据解析详解(一)

&#xfeff;&#xfeff; 今天很高兴和大家一起学习Android的JSON数据解析,可能对于学习安卓的朋友都知道JSON在数据解析方面已经很普遍了.所以也是我们必定要了解的知识 ,下面让我们了解一下JSON的发展历程. XML——这种用于表示客户端与服务器间数据交换有效负载的格式&am…

Android开发json数据解析

在Android开发过程中&#xff0c;或更新数据&#xff0c;或为减轻手机负担将大部分复杂运算交由服务器来进行&#xff0c;都需要与服务器之间进行数据交互&#xff0c;数据交互中&#xff0c;使用的较为频繁的格式变为json数据&#xff0c;书写便捷&#xff0c;操作方便&#x…

JSON解析data数据

之前 是用JSONObject去解析data后来就报错 com.alibaba.fastjson.JSONException: expect : at 0, actual

JSON数据解析 之JSONPath

一&#xff1a;JSONPath说明&#xff1a; JSONPath是一种通过配置正则表达式语法&#xff0c;抽取json中的指定数据的一种类库&#xff1b; 二&#xff1a;需要的jar依赖&#xff08;依赖阿里巴巴的fastjson.jar&#xff09; maven用户可通过maven远程仓库获取配置地址 <…