算法自解
最新版见:https://www.jianshu.com/p/252346e3497b
(更新中……)
努力让自己熟练编程,关键代码,然后快速入门。
数据结构等各种知识点屡看屡忘的我,为以后整理的笔记……
以《算法全解》《挑战程序设计竞赛 算法与数据结构》等为基础
常用的数据结构
stack
1 | 入栈,如例:s.push(x); |
queue
1 | 入队,如例:q.push(x); 将x 接到队列的末端。 |
vector
1 | vector< vector<int> > m; |
数组
1 | C++不易获得数组长度,因此建议把数组长度传入方法里。 |
输入输出与具体方法
pintf函数是每次输出结果;
print,cout最好不要混用,print是即时刷新,等效cout<<flush;混用有时会表现顺序输出不同。
(%与/的应用)
日期差值
输入两个日期:YYYYMMDD格式,得到两个日期之间的差值。
对于一个整数,%100:得到整数后两位 /100得到整数除后两位的。
1 | // ConsoleApplication1.cpp: 定义控制台应用程序的入口点。 |
进制转换
P进制转十进制y
$a_1a_2\dots a_n\to a_1P^{n-1}+\dots+a_2P^{1}+a_1$
1 | int y=0,product=1; |
十进制数y转换成Q进制数z
1 | int z[40],num=0; |
这样z数组从高位z[num-1]到低位z[0]即为Q进制z,进制转换完成。
字符串
对于回文串的处理:1.根据对称性;2.利用for循环,从后向前遍历(逻辑性比较简单)
思路1.
假设字符串str的下标从0开始,由于“回文串”是正读和反读都一样的字符串,因此只需要遍历字符串的前一半(注意:不需要取到i==len/2),如果出现字符str[i]不等于其对称位置str[len-1-i],就说明这个字符串不是“回文串”;如果前一半的所有字符str[i]都等于对称位置 str[len-1-i],则说明这个字符串是回文串。
1 |
|
全排列
(略)
二分查找
这里没有用递归(事实上是可以用递归的),这里是动态改变left和right的值。注意传入参数为A[]
思想,只要left木有大于right,就接着找,but根据大于小于动态变化mid为right或者left
1 |
|
排序
快排
注意,数组传 a[]或者*a
解析:1.递归程序。
结束标准:left>right
2.选定基准 a[left] 标兵 i和j
3.i和j比较换位。i和j相遇的条件:因为i和j分开运算,j先减,i后加,因为while小于的限制,i不可能超过j,
j停止的位置一定小于基准数(因为需要和i换)
i停止的位置可能大于基准数(和j换),可能=j(i,j条件的限制)
1 | void quicksort(int a[],int left,int right){//x,起始点,y,长度 递归实现的快排,好像是这样的QAQ |
冒泡排序&选择排序
冒泡和选择的区别:
选择循环a[i]和a[j]
冒泡循环a[j]和a[j+1],外面大层是i
1 | void xuanze(int *a){//由大到小 |
归并排序
先搞定递归的,日后再搞定非递归的。
(《算法笔记》)
1 | const int maxn=100; |
堆
堆
完全二叉树,左孩子2i位,右孩子2i+1位
树中每个节点的值都不小于(或不大于)其左右孩子节点的值。
完全二叉树一般用数组存储
这里是较小堆,主要方法是向上或向下调整,都有low(向下调整的点),high(next)
增添是添到末尾,向上调整,注意边界条件,比上2时刻大于low;
删除是把末尾放在堆顶,向下调整,注意边界条件,*2小于high,需要比较左右孩子。
堆支持以下的基本操作:
- build:建立一个空堆;
- insert:向堆中插入一个新元素;【向上调整堆】
- update:将新元素提升使其符合堆的性质;
- get:获取当前堆顶元素的值;
- delete:删除堆顶元素;【向下调整堆】
- heapify:使删除堆顶元素的堆再次成为堆
标程(百练上对应题目AC代码)
PKU2017年夏令营机试题
定义一个数组,初始化为空。在数组上执行两种操作:
1、增添1个元素,把1个新的元素放入数组。
2、输出并删除数组中最小的数。
使用堆结构实现上述功能的高效算法。
输入
第一行输入一个整数t,代表测试数据的组数。
对于每组测试数据,第一行输入一个整数n,代表操作的次数。
每次操作首先输入一个整数type。
当type=1,增添操作,接着输入一个整数u,代表要插入的元素。
当type=2,输出删除操作,输出并删除数组中最小的元素。
1<=n<=100000。
输出
每次删除操作输出被删除的数字。
样例输入
1 | 2 |
样例输出
1 | 1 |
1 |
|
链表
二叉树
【有时间得写一写基本功能实现】
[C++实现(指针的用法和解析)和java实现]
基本结构(数组)
1.利用左孩子和右孩子分别是2i,和2i+1,轻松实现。
2.单纯构造node数组(from 《挑战程序设计语言》)
基本结构(链表):
1 | struct node{ |
中序:左中右 后序:左右中
1 | //层序 |
遍历的非递归实现
思想:
1 | vector<int> proorder(Node* root){ |
(二叉搜索树 二叉树链表具体实现)一种链表实现
1 |
|
叶子节点路径
二叉树根到叶子节点每一条路径【求二叉树是否存在和值为N的路径】
1 |
|
dfs&bfs&dijiesiqula算法
快排 bfs dfs 图算法【算法课本、书】 dijiesiqula算法
1 | void dfs(G){ |
并查集(最小生成树)
【回顾博客上的那篇文章】https://www.jianshu.com/p/25b08412e313
G题
1 |
|
动态规划
设计一个简单的任务队列, 要求分别在 1,3,4 秒后打印出 “1”, “2”, “3”
字典序
给你一个数字n(n < 1e9), 再给你一个数字k(k < n), 要求你找到1, 2, 3, … n按照字典序排序后, 第k大的数字 【看算法书】