![](https://img-blog.csdnimg.cn/20201014180756928.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
算法刷题
一些算法题
红尘不染
我想把代码写的像诗一样优雅
展开
-
回溯法基本思想
回溯算法:回溯算法是一种选优搜索法,按照选优条件深度优先搜索,以达到目标。当发现某一步不是最优,就退回一步重新选择。解空间:所有可能解组成的空间,解空间越小,搜索效率越高,解空间越大,搜索效率越低。解空间的组织结构:按一定的组织结构搜索最优解,如果把这种组织结构用树表达出来,就是解空间树显约束:对解分量的取值范围的限定。搜索解空间:隐约束指对能否得到问题的可行解或最优解做出的约束,如果...原创 2019-04-30 11:06:15 · 13570 阅读 · 0 评论 -
最优三角部分
最优三角部分:几个概念:凸多边形不相邻的两个顶点的连线称为凸多边形的弦凸多边形的三角部分是将一个凸多边形分割互不相交的三角形的弦的集合三角形上权值之和是指三角形的三条边上权值之和W(Vi Vk Vj) = |ViVk|+|VkVj|+|ViVj|最优三角形部分就是划分的各三角形上权函数之和最小的三角部分解题步骤:分析最优子结构:假设在第K个顶点会得到最优解,那么原问题就变成了两个子...原创 2019-04-17 18:00:12 · 277 阅读 · 0 评论 -
游艇租赁问题
游艇租赁问题:n个游艇租赁站,出租站i到游艇出租站j之间的租金为r(i,j),1<= i< j <= n;计算从出租站i,到出租站j需要的最少租金用 r[i][j]表示i站到j站的租金用 m[i][j] 表示从i站到j站的最优值当 j = i ,只有一个站点m[i][j] = 0 ;当 j = i+1 时,只有两个站点m[i][j] = r[i][j]当 有3个...原创 2019-04-15 17:48:30 · 1667 阅读 · 0 评论 -
最短编辑距离
字符串的编辑距离:就是一个字符变换为另一个字符的最小编辑操作给定两个序列 X = {x1,x2,x3,…,xn},Y = {y1,y2,y3,…,ym}找出两个子序列的最小编辑距离解题步骤1.假设已知最优解;dp[i][j]是Xi与Yj的编辑距离2.求出递归式两个序列对齐有3种对齐方式;需要删除Xi :dp[i][j] = dp[i-1][j]+1需要插入Yj :dp[i][j] ...原创 2019-04-15 16:24:30 · 347 阅读 · 0 评论 -
最长公共子序列
动态规划(dynamic Programming):是一种表格法,把每一步的子问题结果存储在表格里,每次遇到该子问题,直接查表动态规划把原问题分解为若干子问题,然后自底向上,先求解最小问题的解,结果存储在表格,再求解大的子问题时,直接从表格中查询小的子问题的解,避免重复运算。使用动态规划的两个性质:最优子结构:是指问题的最优解包含其子问题的最优解。子问题重叠:在求解子问题的时候,大量的...原创 2019-04-15 14:59:41 · 92 阅读 · 0 评论 -
矩阵连乘问题
矩阵连乘问题:给定n个连乘的矩阵,找出一种加括号的方法,使得矩阵连乘的计算量(乘法次数)最小矩阵可乘:第一个矩阵的列等于第2矩阵的行时,那么这这两个矩阵是可乘的多个矩阵相乘的结果矩阵,其行,列分别等于第一个矩阵的行,最后一个矩阵的列;最优值递归式m[i][j],当i = j m[i][j] = 0当i<j时,m[i][j] = min{m[i][k]+m[k+1][i]+p[i...原创 2019-04-17 11:48:46 · 834 阅读 · 1 评论 -
斐波那契数列问题
题目:一个台阶有n级,一次只能跳1级或者2级,求有多少种跳法;当 n = 1 时,有一种跳法;当 n = 2 时,有两种跳法;当 n > 2 时,f(n-1)+ f(n-2);当每次选择跳1级或2级时,都对后面的跳法产生影响;long long Fibonacci(int n){ int result[3] = {0,1,2}; // n 为 0,1,2 时候的解 if(n&...原创 2018-12-21 17:24:55 · 306 阅读 · 0 评论 -
查找数组中出现次数超过一半的数
查找数组中出现次数超过一半的数解法一 对数组运用快排,取 n/2处的数为超过一半的数解法二 用空间换时间,以散列表中存储出现过的数据,和出现的次数解法三 每次 删除数组中两个不同的数,剩下的那个数就是出现次数超过一半的数解法四 保存两个值 ,candidate用来保存数组中遍历的某个数,nTimes 用来保存遍历到的数出现的次数int findOneNumber(int *a,int n...原创 2019-03-16 18:52:53 · 297 阅读 · 0 评论 -
奇偶数排序
题目:给定一个整数数组,调整数组中数的顺序,使得所有奇数位于数组的前半部分,所有 偶数位于数组的后半部分。思路一:使用两个指针,从两边向中间遍历,发现条件不满足,交换bool IsOddNumber(int data){ return (data&1==1);}void OddEvenSort(int data[],int length){ if(data == NULL...原创 2018-12-22 19:35:11 · 437 阅读 · 0 评论 -
荷兰国旗
题目:有n个蓝白红的球,乱序排放,现在要求以红白蓝的顺序排放;红色用0表示,蓝色用1表示,白色用2表示void DutchSort(int data[],int n){ int begin,centre,end; // 三个指针,前,中,后 begin = centre =0; end = n-1; while(centre <= end) { if(data[centr...原创 2018-12-22 20:52:54 · 183 阅读 · 0 评论 -
寻找和为定值的两个数
思路一:排序夹逼:把数组排好序,使用两个指针,begin = 0,end = n -1;从两头向中间扫描如果 a[begin] + a[end] < sum ; 让begin++ ,end 不动如果a[begin] + a[end] > sum ; 让 end-- ,begin 不动void TwoSum(int S[],int N,int Sum){ int beg...原创 2018-12-19 17:36:46 · 141 阅读 · 0 评论 -
找到一组数中最小的K个数
题目:找到一组数中最小的K个数思路一:将这组数从大到小排序,输出前K个数// 使用快速排序int median3(int s[],int left,int right) // 找到主元{ int centre; centre = (right-left)/2; if(s[left] > s[centre]) { swap(s[left],s[centre]); } ...原创 2018-12-19 16:20:59 · 491 阅读 · 0 评论 -
动态规划解决换硬币问题
题解:钱的总数为sum ,有 n 中不同面值的零钱,问有多少种兑换方式// sum 总钱数 , n 为零钱的种类数目#define MaxSum 1000 // 最大兑换钱数#define MaxNum 10 // 最大零钱总数int dp[MaxNum][MaxSum]; // 求解数组, //其中MaxNum代表可以兑换成硬币的种类,//MaxSum代表所兑换成的金额,...原创 2018-12-21 18:05:36 · 1863 阅读 · 0 评论 -
完美洗牌
题目:有一个长度为2n的数组{a1,a2,a3,…,an,b1,b2,b3,…,b4};排序后为{a1,b1,a2,b2,a3,b3,…,an,bn}方法一:让b1,b2,b3,…bn;步步前移,移到正确的位置void solution(int *a,int n){ int i,j,k,tmp; for(i=0;i&lt;n;i++) { tmp = a[n+i]; k =...原创 2018-12-25 15:52:06 · 204 阅读 · 0 评论 -
寻找和为定值的多个数
题解:输入两个整数 n ,sum, 从1,2,3,…,n 。中随意提取几个数,和为sum;思路,取第 n 个数 ,可以有两种可能,取得 n ,使其加入,和为sum;继续递归调用函数(sum-n,n-1)不取n , 继续递归调用函数(sum,n-1);list&amp;lt;int&amp;gt; list // 存放nvoid SumOfkNumber(int sum,int n){ if(sum&amp;...原创 2018-12-20 21:15:05 · 433 阅读 · 0 评论 -
最大连续子列和
动态规划int MaxSubArray(int S[],int n){ int Max = S[0]; // 保存最大子列和 currMax = 0; // 元素头到当前的和 for(int i=0;i<n;i++) { if(currMax>=0) // 当前和大于0,可以继续放入 { currMax += S[i]; } else // 小于0...原创 2018-12-20 23:56:58 · 122 阅读 · 0 评论 -
二分查找
二分查找可以用来解决已排序数组的查找问题。二分查找步骤:1.查找范围覆盖整个数组2.将数据与中间项比较,如果比中间项大,则向数组的后半部分查找,反之,向前查找3.每次查找都可以缩小一半的范围,最终找到数据,或者数据不在数组中要写出没有bug的二分查找算法,要注意两点:判断循环终止语句的编写,边界值left,right,区间值的一致;如果令 right = n-1;则循环条件要写为lef...原创 2019-03-15 20:28:51 · 222 阅读 · 0 评论 -
行列递增矩阵的查找
将查找的位置定位到最右上角的元素,如果这个元素比要查找的元素小row++;如果这个元素比要查找的元素大 column–;bool Find(int *a,int rows,int cols,int value){ int row = 0; int col = cols - 1; bool find = false; if (a != NULL &amp;&amp; rows &gt; ...原创 2019-03-15 23:31:16 · 268 阅读 · 0 评论 -
二叉树的操作
二叉树的常用的遍历方法 :先序遍历: 先访问根节点,左孩子 , 右孩子;中序遍历:先访问左孩子,根节点, 右孩子;后序访问 :先访问左孩子,右孩子,根节点;层次遍历:从上到下,从左到右,依次遍历;各种访问遍历的路线一样只是访问的顺序不一样;建立二叉树BTree makeEmpty(){BTree p;int c;scanf_s(&amp;quot;%d&amp;quot;, &amp;amp;amp;c);if原创 2018-10-31 10:34:24 · 122 阅读 · 0 评论 -
寻找树中和为定值的路径
输入一个整数和一颗二叉树,从树的根节点开始往下访问,一直到叶节点,形成一条路径,打印出所有节点形成的路径//全局变量, 保存遍历到路径的值vector<int> path;vector<vector<int>> rec; // 保存符合条件的路径void fun(BTS T,int num){ if(T==NULL) { return; ...原创 2018-12-20 14:57:48 · 258 阅读 · 0 评论 -
二叉搜索树的操作
二叉树的常用操作二叉树的结构typedef struct node* BST;typedef struct node* position;struct node{ int data; position Left; position Right;};建立空树BST makeEmpty(BST T) //建立一颗空的二叉搜索树 ,如果二叉树不为空,可以清空树;{ if(T...原创 2018-11-01 22:16:05 · 98 阅读 · 0 评论 -
堆的操作
堆是一个优先队列;取出元素的顺序是依照优先值大小;堆是一个用数组存储的完全二叉树,任何一个节点是其子树的所有节点的最大值(最小值);堆的结构typedef struct Node* Heap;#define MAXDATA 1000struct Node{ int* data; // 存储堆的数据 int size; // 当前数组的大小 int Maxsize; //数组容量的...原创 2018-11-07 14:32:43 · 287 阅读 · 0 评论 -
KMP算法
串的简单匹配将主串中的第 J 个字符与子串中的第一个字符比较若相等 ,继续比较后面的字符串若不相等,从 J + 1 的位置继续与子串中的第一个字符比较如果能从主串中找到子串,则返回值为主串中子串的第一个字符的位置若没找到,返回空值算法缺点:每次主串指针都回溯,子串指针回溯到第一个字符;KMP 算法 :最大限度的减少指针回溯,通过分析模式串,得到一个next数组,该数组的内容是在匹...原创 2018-11-29 17:00:11 · 102 阅读 · 0 评论 -
字符串相等
题解:两个字符串中的字符一样,出现次数一样,只是顺序不一样,那么这两个字符串相等;方法1:字符串排序后,顺序比较;bool StringEquality(string &a, string &b){ if (a.length() == b.length()) { sort(a.begin(), a.end()); sort(b.begin(), b.end()...原创 2018-12-12 11:01:45 · 1345 阅读 · 0 评论 -
最长回文串
找出一个字符串中,最长的回文字符串方法1:每次拿 i 为回文位置中心,向两边扩展,枚举字符串的每一个位置,得到最长的字符串int LongestPalindrome(const char *s,int n){ int i,j,c,max; if(s == NULL || n&lt;1) { return 0; } max = 0; for(i = 0; i&lt;n; ++i...原创 2018-12-14 16:36:34 · 133 阅读 · 0 评论 -
字符串包含
参考书籍: 编程之法若B中的所有字符都可以在A中找到,A包含B;方法1:暴力求解bool StringContain(string &a,string &b){ for(int i=0;i<b.length();i++) { for(int j=0;j<a.length()&&(b[i]!=a[j]);j++); if(j>=...原创 2018-12-12 10:41:50 · 179 阅读 · 0 评论 -
字符串的组合
组合:字符串abc a、b、c、ab、ac、bc、abc方法一:// n 表示当前字符串的长度void CombinationResult(string S,int n,vector&amp;lt;char&amp;gt; result){ if(n == 0) { for(autp iter = result.begin();iter!=result.end();iter++) {...原创 2018-12-13 15:19:40 · 252 阅读 · 0 评论 -
字符串的查找
问题:有一个文本串S和一个模式串P,要查找P在S中的位置蛮力匹配方法:如果 S[i] == P[j] , 则 i++ , j++;继续匹配下一个字符串如果S[i] != P[j] , 则 i = i - j + 1; j = 0;i 指针回溯;int ViolentMatch(char *S,int *P){ int sLen = strlen(S); int pLen = strl...原创 2019-03-16 23:19:17 · 97 阅读 · 0 评论 -
字符串的全排列
参考书籍 : 编程之法 july字符的全排列;字符串abc的所有排列方式:abc,acb,bac,bca,cab,cba;递归求解:void CalcAllPermutation(string &s,int begin,int end){ if(end<=1) { return; } else if(begin == end) { for(int i = ...原创 2018-12-12 17:25:10 · 106 阅读 · 0 评论 -
字符串回文判断
回文:指正读和反读都一样的字符串;判断字符串是不是回文,方法:从字符串的头和尾,向中间扫描;判断头和尾指针内容是否一样;bool IsPalindrome(char *str,int n){ if(str == NULL || n&amp;lt;1) { return false; } char *front,*rear; // 定义头指针,尾指针 front = str; rear...原创 2018-12-13 17:59:06 · 230 阅读 · 0 评论 -
字符串反转
方法1:把要移位的字符,复制到 a 中,s 中的字符串前移,把a中的字符移动到s的后面// n 移位的个数,m 字符串总个数void fun(char *s, int n, int m){ char *a = (char*)malloc(sizeof(char)*n); int i, j; for (i = 0; i < n; i++) { a[i] = s[i]; }...原创 2018-12-12 09:24:06 · 145 阅读 · 0 评论 -
字符串转换整数
参考书籍 :编程之法int StrtoInt(char *str){ int Max = (unsigned)~0>>1; // 最大值 int Min = -(int)((unsigned)~0>>1)-1;//最小值 unsigned int n =0; // 保存结果 if(str==NULL) { return 0; } while(isspa...原创 2018-12-13 17:34:01 · 97 阅读 · 0 评论