深度优先和广度优先(JAVA算法)

1.钥匙和房间

(力扣题目)
有 N 个房间,开始时你位于 0 号房间。每个房间有不同的号码:0,1,2,…,N-1,并且房间里可能有一些钥匙能使你进入下一个房间。

对于每个房间 i 都有一个钥匙列表 rooms[i],每个钥匙 rooms[i][j] 由 [0,1,…,N-1] 中的一个整数表示,其中 N = rooms.length。 钥匙 rooms[i][j] = v 可以打开编号为 v 的房间。
最初,除 0 号房间外的其余所有房间都被锁住。
你可以自由地在房间之间来回走动。
如果能进入每个房间返回 true,否则返回 false。

示例 1:

输入: [[1],[2],[3],[]]
输出: true
解释:
我们从 0 号房间开始,拿到钥匙 1。
之后我们去 1 号房间,拿到钥匙 2。
然后我们去 2 号房间,拿到钥匙 3。
最后我们去了 3 号房间。
由于我们能够进入每个房间,我们返回 true。

示例 2:
输入:[[1,3],[3,0,1],[2],[0]]
输出:false
解释:我们不能进入 2 号房间。

深度优先

通用思路:
利用压栈(先进后出):stack— LinkedList
push: addFirst
peek: getFirst
pop: removeFirst

import java.util.List;

public class Solution {
	static int n;
	static boolean[] vis;
	static int num;
	
	public static boolean visitRooms(List<List<Integer>> rooms) {
		//房间数
		n = rooms.size();
		num = 0;
		vis = new boolean[n]; //用于记录房间访问状态
		dfs(rooms, 0);  //深度优先搜索
		return num==n;
	}
	
	public static void dfs(List<List<Integer>> rooms, int x) {
		//变更访问状态
		vis[x] = true;
		num++;  //记录访问的房间数
		for(int i:rooms.get(x)) { //拿出房间的钥匙
			if(!vis[i]) {
				dfs(rooms, i);
			}
		}
	}
}

广度优先

通用思路:
利用队列(先进先出):queue— LinkedList
offer: addLast
poll: removeFirst

import java.util.LinkedList;
import java.util.List;

public class Solution {
	static int n;
	static boolean[] vis;
	static int num;

	public static boolean visitRooms(List<List<Integer>> rooms) {
		// 房间数
		n = rooms.size();
		num = 0;
		vis = new boolean[n]; // 用于记录房间访问状态
		LinkedList<Integer> que = new LinkedList<Integer>();

		vis[0] = true; // 初始化第0个房间
		que.offer(0); // 两者都是往队列尾部插入元素
		while (!que.isEmpty()) {
			int x = que.poll(); // 移除第一个元素
			num++;
			for (int i : rooms.get(x)) {
				if (!vis[i]) {
					vis[i] = true;
					que.offer(i);
				}
			}
		}

		return num == n;

	}

}

2.图的遍历

在这里插入图片描述
深度搜索

package adv;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

public class dfs_图表遍历 {
	static int T, N, M, result;
	static int[][] arr;
	static int[] visit;
	static LinkedList<Integer> stack;
	static List<Integer> list;
	
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		T = sc.nextInt();
		for(int tc=1;tc<=T;tc++) {
			N = sc.nextInt();
			M = sc.nextInt();
			
			arr = new int[N+1][N+1];
			visit  = new int[N+1];
			
			for(int m=0;m<M;m++) {
				int x = sc.nextInt();
				int y = sc.nextInt();
				arr[x][y] = 1;
				//arr[y][x] = 1;  是否有向
			}
			stack = new LinkedList<Integer>();
			list = new ArrayList<Integer>();
			dfs(1);
			System.out.println("#" + tc + " " + list.get(list.size()-1));
		}
	}
	
	
	public static void dfs(int node) {
		if(visit[node]==0) {
			stack.push(node);
			visit[node] = 1;
			list.add(node);
		}
		while(!stack.isEmpty()) {
			int top = stack.peek();
			int next_node = getUnvisit(top);
			if(next_node==-1) {
				stack.pop();
			}else {
				stack.push(next_node);
				visit[next_node] = 1;
				list.add(next_node);
			}
		}
	}
	
	public static int getUnvisit(int top) {
		for(int n=1;n<=N;n++) {
			if(visit[n]==0 && arr[top][n]==1) {
				return n;
			}
		}
		return -1;
	}
	
}

//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

广度搜索

package adv;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

public class bfs_图表遍历 {

	static int T, N, M;
	static int[][] arr;
	static int[] visit;
	static LinkedList<Integer> queue;
	static List<Integer> list;
	
	public static void main(String [] args) {
		Scanner sc = new Scanner(System.in);
		T = sc.nextInt();
		
		for(int tc=1; tc<=T; tc++) {
			N = sc.nextInt();
			M = sc.nextInt();
			
			arr = new int[N+1][N+1];
			visit = new int[N+1];
			
			for(int m=0;m<M;m++) {
				int x = sc.nextInt();
				int y = sc.nextInt();
				arr[x][y] = 1;
				//arr[y][x] = 1;  是否有向
			}
			list = new ArrayList<Integer>();
			queue = new LinkedList<Integer>();
			bfs(1);
			System.out.println(list);
			
		}
	}
	
	public static void bfs(int node) {
		if(visit[node]==0) {
			queue.offer(node);
			visit[node] = 1;
			list.add(node);
		}
		while(!queue.isEmpty()) {
			System.out.println(queue);
			int top = queue.poll();
			getUnvisit(top);
		}
	}
	
	
	public static void getUnvisit(int node) {
		for(int n=1;n<=N;n++) {
			if(arr[node][n]==1 && visit[n]==0) {
				queue.offer(n);
				visit[n] = 1;
				list.add(n);
			}
		}
	}
}

//[1, 2, 5, 6, 9, 3, 4, 7, 10, 8]

3. 最短路径问题

package adv;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;


public class bfs_旅游 {

	static int T, N, M, count;
	static int[][] arr;
	static int[] visit;
	static LinkedList<Integer> queue;
	static List<Integer> list;
	static Map<Integer, Integer> temp_map;
	
	public static void main(String [] args) {
		Scanner sc = new Scanner(System.in);
		T = sc.nextInt();
		
		for(int tc=1; tc<=T; tc++) {
			N = sc.nextInt();
			M = sc.nextInt();
			
			arr = new int[N+1][N+1];
			visit = new int[N+1];
			
			for(int m=0;m<M;m++) {
				int x = sc.nextInt();
				int y = sc.nextInt();
				arr[x][y] = 1;
				arr[y][x] = 1;
			}
			count = 0;
			temp_map = new HashMap<Integer, Integer>();
			list = new ArrayList<Integer>();
			queue = new LinkedList<Integer>();
			bfs(1);
//			System.out.println(list);
//
//			System.out.println(temp_map);
			System.out.println("最远路线所用时间:" + temp_map.get(list.get(list.size()-1)));
			
		}
	}
	
	public static void bfs(int node) {
		if(visit[node]==0) {
			queue.offer(node);
			visit[node] = 1;
			list.add(node);
			temp_map.put(node, count);
			count++;
		}
		while(!queue.isEmpty()) {
			int top = queue.poll();
			getUnvisit(top);
		}
	}
	
	
	public static void getUnvisit(int node) {
		List<Integer> ll = new ArrayList<Integer>();
		for(int n=1;n<=N;n++) {
			if(arr[node][n]==1 && visit[n]==0) {
				queue.offer(n);
				visit[n] = 1;
				list.add(n);
				ll.add(n);
				//记录每个地点所在层数
				temp_map.put(n, temp_map.get(node)+1);
			}
		}

	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值