深度优先DFS搜索算法

news/2024/7/24 2:19:12 标签: 搜索, 算法, 深度优先搜索, DFS

深度优先DFS搜索


什么是深度优先搜索

深度优先搜索DFS ,Depth-First Search)是搜索手段之一。它从某个状态,不断地转移状态直到无法转移,然后回退到前一步的状态,继续转移到其他状态,如此不断重复,直到找到最终的解。


如何实现深度优先搜索


根据深度优先搜索的特点,采用递归函数实现比较简单。


算法实例


实例一:若干数和为k的问题。


题干:给定整数a1,a2......an。判断是否可以从中选出若干数,使他们的和为k(数不能加重复的)

限制条件:

1<=n<=20

-10^8<=ai<=10^8

-10^8<=k<=10^8

样例1:

输入:

n=4

a={1,2,4,7}

k=13

输出:

Yes(13=2+4+7)


样例二:

输入:

n=4

a={1,2,4,7}

k=15

输出:

No

分析:咋一看看确实很难实现:因为从a1开始按顺序决定每一个数加还是不加,这样一来每个数只有两种状态,加和不加。那么最终的算法复杂度就是O(2^n)。

只用普通的算法确实很难实现,但是用上递归问题就迎刃而解了。(ps:下面代码很不规范,命名尽量不要使用中文,我是为了自己好找到以前写的代码才这样做的)

完整代码如下:

package com.renyou.算法;

import java.util.Scanner;

public class 若干数的和为K递归问题 {
	private int n,k;
	private int[]a;
	public static void main(String[] args) {
        new 若干数的和为K递归问题().递归();
	}

	private void 递归() {
		Scanner scanner=new Scanner(System.in);
		k=scanner.nextInt();//若干数的和
		n=scanner.nextInt();//数的个数
		a=new int[n];
		for(int i=0;i<n;i++){
			a[i]=scanner.nextInt();
		}
		
		if(dfs(0,0)){
			System.out.println("yes");
		}else{
			System.out.println("no");
		}
	}

	private boolean dfs(int i, int sum) {
		if(i==n)return sum==k;
		
		if(dfs(i+1,sum))//不加上a[i]
			return true;
		if(dfs(i+1,sum+a[i]))//加上a[i]
			return true;
		return false;
	}
}

实例二:雨天积水数量问题。


题干:有一个大小为N*M的园子,雨后积水。八连通的积水被认为是连接在了一起。请求出园子里一共有多少水洼?

(八连通是指下图中相对*的w部分)

www

w*w

www

限制条件:

N,M<=100

输入:

N=5

M=5

园子如下图(w表示积水,*表示没有积水)

**w**

**w**

*****

***w*

**w**

输出:2

分析:

从任意的w开始,不停地把邻接的部分用‘*’代替。1次DFS后与初始的这个w连接的所有w就被替换成了*。因此知道图中没有w了,总共进行了几次的DFS就是积水的个数了。

8个方向对应8种状态转移,所以复杂度是O(8*N*m)=O(n^2)

完整代码如下:

package com.renyou.算法;

import java.util.Random;
import java.util.Scanner;

public class 积水个数的深度优先搜索DFS算法 {
	private char[][] field;
    private int width,height;
    
	public static void main(String[] args) {
		new 积水个数的深度优先搜索DFS算法().solve();
	}

	private void solve() {
		/************ 控制台输入数据 ********************/
		Scanner scanner = new Scanner(System.in);
		width = scanner.nextInt();
		height = scanner.nextInt();
		field = new char[width][height];
		/************* char数组赋值 ********************/
		Random random = new Random();
		int num;
		for (int i = 0; i < width; i++) {
			for (int j = 0; j < height; j++) {
				num = random.nextInt(100);
				if (num % 5 == 0) {//因为输入太麻烦,自己随机生成
					field[i][j] = 'w';
				} else {
					field[i][j] = '.';
				}
			}
		}
		/************ 自动生成field数组元素 *********************/
		for (int i = 0; i < width; i++) {
			for (int j = 0; j < height; j++) {
				System.out.print(field[i][j]);
			}
			System.out.println();
		}
		
		
		/********* 开始遍历计算field *********/
		int res = 0;
		for (int i = 0; i < width; i++) {
			for (int j = 0; j < height; j++) {
				if (field[i][j] == 'w') {
					dfs(i, j);
					res++;
				}
			}
		}
		System.out.println("积水个数" + res);
	}

	private void dfs(int i, int j) {
		field[i][j] = '.';//很重要
		for (int dx = -1; dx <= 1; dx++) {
			for (int dy = -1; dy <= 1; dy++) {
                 int nx=i+dx;
                 int ny=j+dy;
                 //如果在field内并且有积水继续深度搜索
                 if(nx>=0&&nx<width&&ny>=0&&ny<height&&field[nx][ny]=='w'){
                	 dfs(nx,ny);
                 }
			}
		}
	}

}





http://www.niftyadmin.cn/n/1037869.html

相关文章

宽度优先搜索BFS算法

宽度优先搜索BFS算法 什么是宽度优先搜索&#xff1f; 宽度优先搜索&#xff08;BFS,Breadth_First Search&#xff09;总是优先搜索距离初始状态近的状态&#xff0c;也就是说&#xff0c;他是按照开始状态->只需一次转移就可以到达的所有状态->只需两次转移就可以到达…

vue学习---mockjs

什么是mockjs&#xff1f; Mockjs是一款模拟数据生成器&#xff0c;它可以帮助前段工程师独立于后端进行开发&#xff0c;帮助编写单元测试。Mockjs能做什么&#xff1f; 提供了游侠模拟功能&#xff1a; 1、模拟数据模板生成模拟数据&#xff1b; 2、模拟ajax请求&#xff0c;…

基于bfs搜索算法的迷宫最短路径游戏

基于bfs搜索算法的迷宫最短路径游戏 废话不多说&#xff1a;因为在我的上一篇博客里已经提到了bfs算法.花了一天的时间写的一个小游戏&#xff0c;虽然界面不怎么样&#xff0c;但是算法确实很难写。因为不知道怎么上传文件&#xff08;不然我就整个项目上传了&#xff09;直接…

ubuntu更改源的方法(下载软件加快)

ubuntu更改源的方法 1.备份原来的源&#xff08;以后可能有用&#xff09; sudo cp /etc/apt/sources.list /etc/apt/sources_init.list2.更换源 sudo gedit /etc/apt/sources.list使用gedit打开文档&#xff0c;将下边的阿里源复制进去&#xff0c;然后点击保存关闭。 deb…

Android Mvp架构设计与性能优化

Android Mvp架构设计与性能优化 什么是mvp架构设计&#xff1f; MVP是模型&#xff08;Model&#xff09;、视图&#xff08;View&#xff09;、主持人&#xff08;Presenter&#xff09;的缩写&#xff0c;分别代表项目中3个不同的模块。 模型&#xff08;Model&#xff09;&…

vmware中让页面全屏的方法

首先点击虚拟机——>安装vmware tools&#xff1b;安装完成后&#xff0c;会在ubuntu中看到这样一个压缩文件&#xff1b; 将该压缩文件复制到你认为可以安装的地方&#xff0c;然后点击右键——>提取到此处&#xff1b;这里也可以cd到这个文件夹&#xff0c;然后用tar命…

android网络访问框架OkHttp的进一步封装

android网络访问框架OkHttp的进一步封装 概述&#xff1a; android网络框架之OKhttp[1]一个处理网络请求的开源项目,是安卓端最火热的轻量级框架,由移动支付Square公司贡献(该公司还贡献了Picasso)[2]用于替代HttpUrlConnection和Apache HttpClient(android API23 6.0里已移除H…

android三级缓存访问网络图片

android三级缓存访问网络图片 什么是三级缓存&#xff1f; 第一级&#xff1a;内存缓存(优先从内存中加载图片&#xff0c;速度最快&#xff0c;不浪费流量) 第二级&#xff1a;本地缓存&#xff08;其次从本地加载图片&#xff0c;速度快&#xff0c;不浪费流量&#xff09; 第…