深度优先搜索之偏爱时间复杂度

题目要求给你一些数字 , 其中的一些数字相加能不能等于已经给定的数字 sum ? 对这个问题我写了一个程序 , 然而总是超时 , 无药可救但是 看了别人的 程序 , 人家的程序运行得效率特别高 , 然后分析了一下 , 颇有感想决定记录下来        给出一组数据 例如  1  2  4  7    给定总和为 13   问在这几个数字中有没有几个数字的和 等于 所给数字 13的  然后我就没耽误事 开始暴力搜索了 ...    下面附上代码和分析

 1 void DFS(int n,int sum)
 2 {
 3     for(int i=0;i<n;i++)
 4     {
 5         if(mark)
 6             return ;
 7         if(!visited[i])   //  如果该数字 没有被使用过的话
 8         {
 9             visited[i]=1;
10             maxn=maxn+a[i];
11             if(maxn==sum)
12             {
13                 mark=1;
14                 break;
15             }
16             DFS(n,sum);
17             maxn=maxn-a[i];
18             visited[i]=0;
19         }
20     }
21 }

我的代码 时间复杂度极高  将所有的可能性都列出来 并且还是 , 当顺序不一样其中元素一样的时候 我也列了出来  . . . . . . 我知道你和我同样的无语 , 这样的时间复杂度真是高的可怕 .  以前的时候 自己太懒   学了 对于图的搜索之后 就开始按照同样的套路开始对  数列进行 搜索 , 一直都会有超时情况的出现  ,  但是一直都是  新三年旧三年缝缝补补又三年 .....   今天就好好的总结一下经验教训  解决了这个问题   . . .

下面附上 , 一个学姐写的代码

 1 bool DFS(int i,int m)
 2 {
 3     if(i==n)
 4         return sum==m;
 5     else
 6         if(sum<m)
 7         return false;
 8     if(DFS(i+1,m))
 9         return true;
10     if(DFS(i+1,a[i]+m))
11         return true;
12     return false;
13 }

学姐的代码 , 虽然也是将所有的情况都列出来 ( 不可能的时候有剪枝 ) , 但是学姐的代码 顺序不一样但是元素一样 的情况是没有出现的 .    这样就高效的很

时间: 2024-10-28 13:49:33

深度优先搜索之偏爱时间复杂度的相关文章

图的遍历之深度优先搜索(DFS)

深度优先搜索(depth-first search)是对先序遍历(preorder traversal)的推广.”深度优先搜索“,顾名思义就是尽可能深的搜索一个图.想象你是身处一个迷宫的入口,迷宫中的路每一个拐点有一盏灯是亮着的,你的任务是将所有灯熄灭,按照DFS的做法如下: 1. 熄灭你当前所在的拐点的灯 2. 任选一条路向前(深处)走,每经过一个拐点将灯熄灭直到与之相邻的拐点的灯全部熄灭后,原路返回到某个拐点的相邻拐点灯是亮着的,走到灯亮的拐点,重复执行步骤1 3. 当所有灯熄灭时,结束 将

[复习]深度优先搜索

深度优先搜索(dfs)是利用递归完成的以搜索深度优先的搜索 通常大概是这样的: 1 void search(int vi){ 2 if( 达到目标 ){ //边界 3 if( 不满足要求 ) return ; 4 //(和最优解比较) 5 //当比当前最优解更优时 6 //更新当前最优解 7 return ;//必须返回 8 } 9 for( int i = ...; i <= ... ; i++ ){ //枚举 10 //保存结果 11 search(vi); 12 //清除刚刚保存的结果 1

图的深度优先搜索及拓扑排序

本文将介绍图的深度优先搜索,并实现基于深度优先搜索的拓扑排序(拓扑排序适用于有向无环图,下面详细介绍). 1. 图的深度优先遍历要解决的问题 图的深度优先搜索与树的深度优先搜索类似,但是对图进行深度优先搜索要解决一个问题,那就是顶点的重复访问,假设图中存在一个环路A-B-C-A,那么对顶点A进行展开后得到B,对B进行展开后得到C,然后对C进行展开后得到A,然后A就被重复访问了... 这显然是不对的!我们需要用一个状态变量来记录一个顶点被访问和被展开的状态.在<算法导论>中,作者使用3种颜色来对

图的优先遍历:广度优先搜索和深度优先搜索

广度优先搜索,该算法是将已发现结点和未发现结点之间的边界,沿着其广度方向向外扩展,算法需要发现所有距离源结点 s 为 k 的所有结点之后,才会发现距离源结点 s 为 k+1 的其他结点.如果结点都被访问,算法终止. 此过程需要先构建一颗广度优先树.一开始,该树只有根结点 s (源节点).在扫描已发现结点 s 的邻接表时,每发现一个白色结点 v,就把结点染黑(这是为了记录访问的痕迹),并把它们之间的边(u, v)加入广度优先树. 该算法使用了一个具有 FIFO 特性的队列来管理已知和未知两个集合之

深度优先搜索与广度优先搜索算法理解

深度优先搜索算法和广度优先搜索算法是图论中两个有意思也很实用的算法,下面我们来看看这两个算法. 严书中,给出的利用深度优先搜索(Deep First Search)算法进行图的遍历伪码如下 1 Boolean visited[MAX]; //标志数组 2 Status (*VisitFunction)(int v); //访问函数 3 4 void DFSTraverse(Graph G, Status (*Visit)(int v)) 5 { 6 VisitFunction = Visit;

图论 深度优先搜索 广度优先搜索的非递归实现

深度优先遍历 1.深度优先遍历的递归定义 假设给定图G的初态是所有顶点均未曾访问过.在G中任选一顶点v为初始出发点(源点),则深度优先遍历可定义如下:首先访问出发点v,并将其标记为已访问过:然后依次从v出发搜索v的每个邻接点w.若w未曾访问过,则以w为新的出发点继续进行深度优先遍历,直至图中所有和源点v有路径相通的顶点(亦称为从源点可达的顶点)均已被访问为止.若此时图中仍有未访问的顶点,则另选一个尚未访问的顶点作为新的源点重复上述过程,直至图中所有顶点均已被访问为止. 图的深度优先遍历类似于树的

深度优先搜索

在图中的深度优先搜索,由于避免回路的产生,设置visit数组. 有两种深度优先的应用场景.一种是用于最优解的寻找,即到达目的地的最优解.这时需要设置全局的一个数组,还有变量,来储存路径.通过与别的方法的比较,获取最优解. 第二种是染色问题,只要求全部遍历,没有最优的要求. 还有哈希的用法.当需要记录拥有共同数字特征的一些属性时,就可以使用哈希数组.使用时按照属性的含义寻找.如二叉树某层的数量.

深度优先搜索(dfs)

关于深度优先搜索的总结: 1 dfs 的基本结构:  void dfs(int x){ if( x 超出边界){ return ; }else{ for(遍历){ if(未访问过){ 访问         ; 打上标记    ; dfs(x + 1) ; 去掉标记    ; //极易忘记 } } } return; } 2 用dfs求全排列: 本来好好的,结果sizeof(pointer) 就完蛋了.神秘的内存错误,而且还能正常的跑出一个不正常的结果出来. 想了解sizeof这个小妖精的看这里

深度优先搜索思想初体验

1.求数字 1~n 的全排列 import java.util.Scanner ; public class Permutation{ //求数字 1~n 的全排列: int[] array ; int[] book ; int n ; public void permutation(int step){ // 深度优先搜索思想: if (step==n+1) { for (int i=1;i<=n;i++) { System.out.print(array[i] + " ")