算法
和平精英总指挥
学材料的柱子
展开
-
归并排序
先拆后合分为两部分,两部分都有序后再合并终止条件:left = right//作者:蒋伟泉#include <iostream>#include <ctime>#include <vector>using namespace std;const int MAX_SIZE = 15;const int NUM = 100;vector<int> generate(){//for test srand(time(NULL)); vector原创 2020-10-06 10:22:13 · 84 阅读 · 0 评论 -
2020-09-30
1.1001个数在范围[1,1000],只有一个数出现两次,其余都出现一次,找出这个数,时间o(N) 且不使用额空间。思路:把[1,1000]这1000个数目标的1001个数异或 所得值就是目标答案。(相同数^为0)#include <iostream>#include<algorithm>#include<ctime>using namespace std;const int N = 1000;int array[N + 2] = { 0 };void原创 2020-09-30 19:17:37 · 88 阅读 · 0 评论 -
01矩阵中最大子矩阵
问题:一个矩阵只含有0 1两种元素,求只包含1的最大子矩阵大小(大小用包含的1的个数表示)假设矩阵大小为N x M, 要求时间复杂度为O(N x M)例如给定如下矩阵:1 0 1 0 01 0 1 1 11 1 1 1 11 0 0 1 0Return 61 1 1 1 11 0 0 1 0Return 51 0 1 0 01 0 1 1 1Return 3解这个问题...原创 2020-04-16 13:13:57 · 716 阅读 · 0 评论 -
直方图最大矩阵面积
题目给定一个直方图,求这个直方图中最大矩阵对应的面积是多少?比如有个图如下 (对应的数组为:[2,1,5,6,2,3])那么对应的最大矩形的面积应该为 10:解使用单调栈可以使时间复杂度为O(N)分别以数组中的每个元素作为边,确定其对应矩阵的大小如2 对应矩阵大小为21对应矩阵大小为65对应矩阵大小为106应矩阵大小为62对应矩阵大小为83对应矩阵大小为3最大值即为解...原创 2020-04-16 12:39:26 · 196 阅读 · 0 评论 -
单调栈结构
题目:给定一个不含重复数值的数组,找到每一个i位置左右两边第一个比arr[i]小的值的下标。如果不存在则下标为-1解暴力解:时间复杂度为n^2进阶:使用单点栈结构,时间复杂度为 O(n)单调栈找小的,栈底放较小值;找大的栈底放较大值。如题,找相邻最近较小,所以栈底到栈顶升序。遍历数组,如果栈为空,直接入栈,如果当前元素大于栈顶元素,入栈。如果当前元素小于栈顶元素,说明此元素是栈顶...原创 2020-04-16 11:44:40 · 97 阅读 · 0 评论 -
生成最大窗口数组
题目:有一个整型数组 arr 和一个大小为 w 的窗口从数组的最左边滑倒最右边,窗口每次向右边划一个位置。例如:数组为 [4,3,5,4,3,3,6,7],窗口大小为3时:[4 3 5] 4 3 3 6 7 窗口的最大值为54[3 5 4] 3 3 6 7 窗口的最大值为54 3[5 4 3] 3 6 7 窗口的最大值为54 3 5[4 3 3] 6 7 窗口的最大值为44 3 5...原创 2020-04-16 11:23:27 · 174 阅读 · 0 评论 -
二叉树非递归(迭代)方法遍历
二叉树非递归(迭代)方法遍历前序遍历运用栈来实现二叉树的前序遍历while(栈不为空或结点不为空){1.若结点不为空(从根结点开始) 入栈 打印2.while(根的左儿子不为空) 入栈 打印3.if(根的左儿子为空 )记录栈顶结点top 出栈 判断top的右儿子若top的右儿子为空 继续出栈 判断下一个top的右儿子若top的右儿子不为空 返回第一步}出栈的顺序和中序...原创 2019-09-07 15:51:45 · 150 阅读 · 0 评论 -
用递归和栈的操作函数实现栈的逆序
用递归和栈的操作函数实现栈的逆序,要求不能使用额外的辅助空间。int getandremovelastnum(stack<int>&s){//得到并删除栈底的元素 int ret = s.top(); s.pop(); if (s.empty()){ return ret; } else{ int last = getandremovelastnum(s)...原创 2020-04-05 15:48:07 · 131 阅读 · 0 评论 -
复制含有随机指针节点的链表
复制含有随机指针节点的链表【题目】 一种特殊的链表节点类描述如下:public class Node {public int value;public Node next;public Node rand;public Node(int data){ this.value = data; }}Node类中的value是节点值,next指针和正常单链表中next指针的意义 一 样,都...原创 2020-04-05 11:27:28 · 115 阅读 · 0 评论 -
将单向链表按某值划分成左边小、中间相等、右边大的形式
将单向链表按某值划分成左边小、中间相等、右边大的形式【题目】 给定一个单向链表的头节点head,节点的值类型是整型,再给定一个 整 数pivot。实现一个调整链表的函数,将链表调整为左部分都是值小于 pivot 的节点,中间部分都是值等于pivot的节点,右部分都是值大于 pivot的节点。 除这个要求外,对调整后的节点顺序没有更多的要求。 例如:链表9->0->4->5- &...原创 2020-04-05 11:11:44 · 130 阅读 · 0 评论 -
判断一个链表是否为回文结构
判断一个链表是否为回文结构【题目】 给定一个链表的头节点head,请判断该链表是否为回 文结构。 例如: 1->2->1,返回true。 1->2->2->1,返回true。 15->6->15,返回true。 1->2->3,返回false。 进阶: 如果链表长度为N,时间复杂度达到O(N),额外空间复杂 度达到O(1)。普通算法:运用栈...原创 2020-04-04 22:46:29 · 101 阅读 · 0 评论 -
打印两个有序链表的公共部分
打印两个有序链表的公共部分【题目】 给定两个有序链表的头指针head1和head2,打印两个 链表的公共部分。思路:找到两个链表第一个公共节点即可,求出两个链表的长度差,即可找到第一个公共结点。本题因为给定是有序链表,则更加简单,如果两个head的数据域不等,则让小的后移一个,数据域相等时则是第一个公共点。void print(Node*p){ while (p != NULL){ c...原创 2020-04-04 22:26:12 · 105 阅读 · 0 评论 -
翻转单链表
【要求】 如果链表长度为N,时间复杂度要求为O(N),额外空间 复杂度要求为O(1)思路一:创建一个新的节点指向第一个节点,以这个节点为头,采用头插法,将链表的所有节点插入void insert_head(Node*p, Node*obj){ obj->_next = p->_next; p->_next = obj;}void reverse(Node*&p...原创 2020-04-04 22:12:58 · 69 阅读 · 0 评论 -
“之”字形打印矩阵
“之”字形打印矩阵【题目】 给定一个矩阵matrix,按照“之”字形的方式打印这 个矩阵,例如:1 2 3 45 6 7 89 10 11 12 “之”字形打印的结果为:1,2,5,9,6,3,4,7,10,11, 8,12【要求】 额外空间复杂度为O(1)。思路:同样是通过两点来确定范围,每次打印的斜线实际上是两个点所在直线上的所有点,再用一个bool变量来觉定从打印的方向。当从0,...原创 2020-04-04 21:30:14 · 95 阅读 · 0 评论 -
旋转正方形矩阵
旋转正方形矩阵【题目】 给定一个整型正方形矩阵matrix,请把该矩阵调整成 顺时针旋转90度的样子。 【要求】 额外空间复杂度为O(1)。思路:和绕圈打印矩阵的思路一样以左上和右下两个点确定矩阵的边,然后两个点向中间靠拢void rotate(vector<vector<int>>&obj, int top_row, int top_line, int en...原创 2020-04-04 21:18:33 · 115 阅读 · 0 评论 -
转圈打印矩阵
转圈打印矩阵【题目】 给定一个整型矩阵matrix,请按照转圈的方式打印它。 例如:1 2 3 45 6 7 89 10 11 1213 14 15 16 打印结果为:1,2,3,4,8,12,16,15,14,13,9, 5,6,7,11, 10 【要求】 额外空间复杂度为O(1)。思路:以上题为列,第一回合打印以1和16两个点决定的矩形边第二回合打印以6和11决定的矩形边voi...原创 2020-04-04 21:15:31 · 89 阅读 · 0 评论 -
栈实现队列和队列实现栈
如何仅用队列结构实现栈结构?用两个队列实现栈class mystack_by_queue{public: void pop(){ q1.pop(); } void push(int data){ int temp; while (!q1.empty()){ temp = q1.front(); q1.pop(); q2.push(temp); } ...原创 2020-04-04 21:04:28 · 95 阅读 · 0 评论 -
特殊的栈
实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返 回栈中最小元素的操作。 【要求】 1.pop、push、getMin操作的时间复杂度都是O(1)。 2.设计的栈类型可以使用现成的栈结构。思路:用两个栈,左边栈正常存储,右边栈保存当前最小元素值,每次入栈时和栈顶元素比较如果比栈顶小入栈,否则将栈顶的元素再入栈一次。class mystack{public: void push(int...原创 2020-04-04 19:57:58 · 160 阅读 · 0 评论 -
数组以n分为大于小于n的左右两部分
给定一个数组arr,和一个数num,请把小于等于num的数放在数 组的左边,大于num的数放在数组的右边。 要求额外空间复杂度O(1),时间复杂度O(N)思路:两个指针void part_num(int arr[], int num, int len){//方法1 int pre = -1; int now = 0; while (now < len){ if (arr[no...原创 2020-04-04 18:31:33 · 456 阅读 · 0 评论 -
小和问题和逆序对问题
小和问题和逆序对问题小和问题在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。求一个数组 的小和。 例子: [1,3,4,2,5] 1左边比1小的数,没有; 3左边比3小的数,1; 4左边比4小的数,1、3; 2左边比2小的数,1; 5左边比5小的数,1、3、4、2; 所以小和为1+1+3+1+1+3+4+2=16 要求复杂度小于O(n^2)思路:归并的方法,找出左边...原创 2020-04-04 16:54:53 · 129 阅读 · 0 评论 -
拓扑排序
针对的是有向无环图,且一定要为有向无环图,总体思路为:找到入度为0的点从图中去除以改点为弧尾的弧,循环到步骤1.原创 2020-04-01 21:57:53 · 79 阅读 · 0 评论 -
深度优先生成树和广度优先生成树
生成树详细介绍关键:检测是否是第一次访问,是 则指向左孩子 不是则指向兄弟void MGraph::DFSTree(int i, CSTree&T){ //将正在访问的该顶点的标志位设为true visited[i] = true; bool first = true; CSTree q = NULL; //依次遍历该顶点的所有邻接点 for (int w = FirstA...原创 2020-04-01 21:11:27 · 2695 阅读 · 1 评论 -
深度优先搜索DFS和广度优先搜索BFS
DFS详细介绍DFS——不断回溯的过程。类似于树的先序遍历,从任一未被遍历过的点开始,将改点标记为visited,然后去找改点连通的点,如果没有被遍历则标记为visited,然后继续探索。。。。当没有可以探索的点时,则回溯到上一个点。以上图为例,遍历过程为:v1 v2 v4 v 8 v 5 v3 v6 v7注意:DFS结果不是唯一的,看自己是如何设定的,以下也可以使DFS遍历的结果v1...原创 2020-04-01 20:51:46 · 155 阅读 · 0 评论 -
最小生成树——克鲁斯卡尔算法(Kruskal算法)
克鲁斯卡尔算法(Kruskal算法)对于n个顶点的连通图而言,其生成的最小生成树有n-1条边,即可以保证从任一点出发可以到达任一点且不产生回路。克鲁斯卡尔算法(Kruskal算法):对每条边的权值进行从小到大排序,然后从小到大取权值最小的边,如取出的边会在树中产生回路则舍去,取下一条;若不会产生回路则加入到树中。因此Kruskal算法的关键问题就是:如何判断新加入的边是否会产生回路。判断是...原创 2020-03-30 17:03:02 · 4356 阅读 · 0 评论 -
最小生成树——普里姆算法(Prim算法)
普里姆算法:普里姆算法在找最小生成树时,将顶点分为两类,一类是在查找的过程中已经包含在树中的(假设为 A 类),剩下的是另一类(假设为 B 类)。对于给定的连通网,起始状态全部顶点都归为 B 类。在找最小生成树时,选定任意一个顶点作为起始点,并将之从 B 类移至 A 类;然后找出 B 类中到 A 类中的顶点之间权值最小的顶点,将之从 B 类移至 A 类,如此重复,直到 B 类中没有顶点为止。所...原创 2020-03-30 16:40:51 · 7275 阅读 · 1 评论 -
矩阵的n次幂
问题:给定任一矩阵,求其n次幂,复杂度小于O(n)提示:矩阵相乘,用左边的行乘以右边的列再分析这个问题前,先思考如何对矩阵进行乘操作,为了使问题更具普遍性,我们来分析行列式相乘的问题用(x1,y1)的行列式乘以(x2,y2)的行列式行列式相乘两个行列式能够相乘 axb 必须满足:a的行等于b的列,最后得到的结果形式和a一模一样(行列和a相等)用三个for循环 void ret(co...原创 2020-03-23 15:17:27 · 5035 阅读 · 1 评论 -
一个数的N次幂
问题:求解X^Y,XY都为整数,且Y非负。要求时间复杂度小于O(N)常规算法O(N)for循环从0到Y-1每次都累乘X得到结果,复杂度显然为n归并将X^Y问题进行划分,等价于:Y为偶数时 X^(Y/2) * X^(Y/2) 即 (X^(Y/2))平方Y为奇数时(X^(Y/2))平方*Xint nth_power2(int x, int y){ if (!x) retur...原创 2020-03-23 11:17:45 · 1021 阅读 · 0 评论 -
回溯/递归——八皇后
问题描述:在8X8的棋盘上放置八个皇后,任意两个皇后都不能处于同一行、列或者同一斜线上。分析:每行只能放一个,每列只能放一个。如何判段在当前位置是否可以防止皇后行和列的判断很简单,主要是对角线的判断在 / 对角线上的点:行 + 列相等在 \ 对角线上的点:行 - 列相等通过建立皇后对象的结构体,重载==实现两个皇后相等的判断 bool operator==(const Queen&a...原创 2020-03-22 22:30:06 · 139 阅读 · 0 评论 -
回溯——迷宫问题
问题描述:用一个N 阶矩阵来表示一个迷宫,该矩阵包含元素 0 1 -2 -3分别表示通道、墙、入口、出口。从入口处开始沿着通道行经,判断是否恩能够到达出口。思路分析:问题的关键包括以下几个部分建立迷宫包括墙、通道、入口、出口点的移动走过的路径如何处理当前路径不可行后如何回溯终止条件如何建立迷宫用二维数组建立一个N阶矩阵,数组中的成员为结构体Point(表示点),每个点包含坐标(...原创 2020-03-22 21:25:13 · 145 阅读 · 0 评论 -
翻转单链表
结点类型class list{public: list(int num = 0){ this->m_num = num; this->m_next = NULL; }public: int m_num; list*m_next;};实现:(不含头结点)代码模板化 很固定方法1:vodi reverse(list*node){ list*ptr = ...原创 2020-03-14 21:53:22 · 63 阅读 · 0 评论 -
排序
直接排序方法:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列应用场景 :接近有序 数据量较少接近有序:小的元素在前 大的在后 不大不小的在中间空间复杂度:O( 1) 不需要额外的空间时间复制度:O(n^2) 最坏情况下 为:1+2+3+4········+n稳定性:稳定(稳定性的定义: 假定在待排序的记...原创 2019-09-10 22:07:15 · 129 阅读 · 0 评论 -
对数器
当我们想出一个复杂度低算法时,如何对算法的准确性进行判断呢?使用对数器方法:你想要测试的方法a觉得正确不考虑复杂度的算法b产出随机样本用b和a对样本进行处理比对处理结果反复进行3~5 当样本足够多时 可以认为正确产生随机数的方法使用rand函数配合srand使用random库函数说下第二种头文件 < random > static default_r...原创 2020-03-09 16:52:03 · 74 阅读 · 0 评论 -
递归
什么问题可以用递归?当前问题可以进行拆分,拆分为子问题。子问题的本质和父问题是一样的,解决了子问题,父问题也就迎刃而解。同时子问题可以继续向下分解。例如:数组排序问题分解为数组左边部分排序和又边部分排序找数组最大数问题找数组左边最大数和数组右边最大数,然后返回最大的那一个求 n 的阶乘等价于求(n-1)的阶乘再乘以n n-1的阶乘等于n-2的阶乘再乘以n-1递归行为递归行为在程序...原创 2020-03-09 16:31:57 · 91 阅读 · 0 评论