算法-16-并查集

news2024/11/28 10:39:57

并查集简介 

并查集:一开始,把a,b,c放入并查集,a自己一个集合,b自己一个,c自己一个

提供的方法        1.boolean isSameSet(a,b),判断ab是否在同一个集合

                          2.void union(a,b),把a所在集合的全部,和b所在集合的全部,两个大集合合并

怎么实现的方法一

对于每个元素,都有一个指针指向自己

 查询a,b是否在同一个集合,对于a,a往上到不能再往上的节点就是他的代表节点,也就是a

b同理,代表节点不同,所以ab所在的集合不同

我们把一个节点往上找,找到不能再往上的那个节点叫集合的代表节点

那如何实现union合并呢

并查集有自己的机制,记录每一个集合大小是多少

然后union(a,e)时,把b的指针直接挂到a后面,union(a,c)时,小的挂到大的上,c挂到a后面

如果再union(b,d)然后union(d,e)怎么union,先顺着d往上找找到b,然后顺着e往上找找到a,小的挂大的,只需改代表节点b->a,欧了

import java.util.HashMap;
import java.util.List;
import java.util.Stack;

public class Code05_UnionFind {

	public static class Node<V> {
		V value;

		public Node(V v) {
			value = v;
		}
	}

	public static class UnionFind<V> {//搞三张表
		public HashMap<V, Node<V>> nodes;
		public HashMap<Node<V>, Node<V>> parents;//parent表,key是儿子,value是父亲,儿子父亲一一对应
		public HashMap<Node<V>, Integer> sizeMap;//代表节点和大小size对应

		public UnionFind(List<V> values) {//初始化
			nodes = new HashMap<>();
			parents = new HashMap<>();
			sizeMap = new HashMap<>();
			for (V cur : values) {
				Node<V> node = new Node<>(cur);
				nodes.put(cur, node);
				parents.put(node, node);
				sizeMap.put(node, 1);
			}
		}

		// 给你一个节点,请你往上到不能再往上,把代表返回
		//找代表节点要用很多次,所以把一次找一个爹优化成直接找祖宗,沿一条链压入栈,
		//一个一个弹出,只要不是栈顶就挂到祖宗后面
		public Node<V> findFather(Node<V> cur) {
			Stack<Node<V>> path = new Stack<>();
			while (cur != parents.get(cur)) {
				path.push(cur);
				cur = parents.get(cur);
			}//推出的时候cur = parents.get(cur)
			while (!path.isEmpty()) {
				parents.put(path.pop(), cur);
			}
			return cur;
		}

		public boolean isSameSet(V a, V b) {
			return findFather(nodes.get(a)) == findFather(nodes.get(b));
		}

		public void union(V a, V b) {
			Node<V> aHead = findFather(nodes.get(a));
			Node<V> bHead = findFather(nodes.get(b));
			if (aHead != bHead) {
				int aSetSize = sizeMap.get(aHead);
				int bSetSize = sizeMap.get(bHead);
				Node<V> big = aSetSize >= bSetSize ? aHead : bHead;//就是if(a>b),big=a,small=b
				Node<V> small = big == aHead ? bHead : aHead;
				parents.put(small, big);//小集合的头部(父亲)设成大集合
				sizeMap.put(big, aSetSize + bSetSize);//大集合变大
				sizeMap.remove(small);
			}
		}

		public int sets() {
			return sizeMap.size();
		}

	}
}

并查集应用

1.表示任务关系,1代表认识,0代表不认识

一定是正方形N*N,且m[i][j]=1,那么m[j][i]=1,大正方形是对称的

求有多少个联通区(朋友圈,互相认识的域)

用并查集,从0开始,0认识2认识4,一合并【0.2.4】,从1开始【1.3】一共两个朋友圈

// 本题为leetcode原题
// 测试链接:https://leetcode.com/problems/friend-circles/
// 可以直接通过
public class Code01_FriendCircles {

	public static int findCircleNum(int[][] M) {
		int N = M.length;
		// 初始化{0} {1} {2} {N-1}每个数据单独成一个集合
		UnionFind unionFind = new UnionFind(N);
		for (int i = 0; i < N; i++) {	//行
			for (int j = i + 1; j < N; j++) {//列,for循环只用便利右上部分,因为1认识2,2就认识1
				if (M[i][j] == 1) { // i和j互相认识
					unionFind.union(i, j);//i,j合并
				}
			}
		}
		return unionFind.sets();
	}

	public static class UnionFind {//用数组代替哈希表,更快
		// parent[i] = k : i的父亲是k
		private int[] parent;
		// size[i] = k : 如果i是代表节点,size[i]才有意义,否则无意义
		// i所在的集合大小是多少
		private int[] size;
		// 辅助结构,作栈用
		private int[] help;
		// 一共有多少个集合
		private int sets;
			//初始化
		public UnionFind(int N) {
			parent = new int[N];
			size = new int[N];
			help = new int[N];
			sets = N;
			for (int i = 0; i < N; i++) {
				parent[i] = i;	//i的父亲节点就是自己
				size[i] = 1;	//i自己就是代表节点,大小为1
			}
		}

		// 从i开始一直往上,往上到不能再往上,代表节点,返回
		// 这个过程要做路径压缩
		private int find(int i) {
			int hi = 0;
			while (i != parent[i]) {//i不等于自己的父亲,i往上 
				help[hi++] = i;//help作栈
				i = parent[i];
			}//直到i=parent[i]也就是代表节点了
			for (hi--; hi >= 0; hi--) {
				parent[help[hi]] = i;
			}
			return i;
		}

		public void union(int i, int j) {
			int f1 = find(i);
			int f2 = find(j);
			if (f1 != f2) {
				if (size[f1] >= size[f2]) {
					size[f1] += size[f2];
					parent[f2] = f1;
				} else {
					size[f2] += size[f1];
					parent[f1] = f2;
				}
				sets--;
			}
		}

		public int sets() {
			return sets;
		}
	}

}

岛问题

给定一个二维数组matrix,里面的值不是1就是0

上或下或左或右相邻的1认为是一片岛

返回matrix中岛的数量,求几片1

思路,从左往右依次遍历,不是1就跳过,是一就调用infection函数,把与这个一相邻的1全部变成2,然后往后走不是1就跳

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Stack;

// 本题为leetcode原题
// 测试链接:https://leetcode.com/problems/number-of-islands/
// 所有方法都可以直接通过
public class Code02_NumberOfIslands {

	public static int numIslands3(char[][] board) {
		int islands = 0;
		for (int i = 0; i < board.length; i++) {
			for (int j = 0; j < board[0].length; j++) {
				if (board[i][j] == '1') {//遍历,是1岛的数量++然后调用感染函数
					islands++;
					infect(board, i, j);
				}
			}
		}
		return islands;
	}

	// 从(i,j)这个位置出发,把所有练成一片的'1'字符,变成0,不是0字符而是0阿斯克码值
	public static void infect(char[][] board, int i, int j) {
		if (i < 0 || i == board.length || j < 0 || j == board[0].length || board[i][j] != '1') {
			return;
		}
		board[i][j] = 0;//一定要改,否则无限递归
		infect(board, i - 1, j);
		infect(board, i + 1, j);
		infect(board, i, j - 1);
		infect(board, i, j + 1);
	}

	public static int numIslands1(char[][] board) {
		int row = board.length;
		int col = board[0].length;
		Dot[][] dots = new Dot[row][col];
		List<Dot> dotList = new ArrayList<>();
		for (int i = 0; i < row; i++) {
			for (int j = 0; j < col; j++) {
				if (board[i][j] == '1') {
					dots[i][j] = new Dot();
					dotList.add(dots[i][j]);
				}
			}
		}
		UnionFind1<Dot> uf = new UnionFind1<>(dotList);
		for (int j = 1; j < col; j++) {//第零行没有上,单独拿出来
			// (0,j)  (0,0)跳过了  (0,1) (0,2) (0,3)
			if (board[0][j - 1] == '1' && board[0][j] == '1') {//自己是1,右边也是1就合并
				uf.union(dots[0][j - 1], dots[0][j]);
			}
		}
		for (int i = 1; i < row; i++) {{//第零列没有左,单独拿出来
			if (board[i - 1][0] == '1' && board[i][0] == '1') {
				uf.union(dots[i - 1][0], dots[i][0]);
			}
		}
		for (int i = 1; i < row; i++) {//既有左又有上
			for (int j = 1; j < col; j++) {
				if (board[i][j] == '1') {
					if (board[i][j - 1] == '1') {
						uf.union(dots[i][j - 1], dots[i][j]);
					}
					if (board[i - 1][j] == '1') {
						uf.union(dots[i - 1][j], dots[i][j]);
					}
				}
			}
		}
		return uf.sets();
	}

	public static class Dot {

	}

	public static class Node<V> {

		V value;

		public Node(V v) {
			value = v;
		}

	}

	public static class UnionFind1<V> {
		public HashMap<V, Node<V>> nodes;
		public HashMap<Node<V>, Node<V>> parents;
		public HashMap<Node<V>, Integer> sizeMap;

		public UnionFind1(List<V> values) {
			nodes = new HashMap<>();
			parents = new HashMap<>();
			sizeMap = new HashMap<>();
			for (V cur : values) {
				Node<V> node = new Node<>(cur);
				nodes.put(cur, node);
				parents.put(node, node);
				sizeMap.put(node, 1);
			}
		}

		public Node<V> findFather(Node<V> cur) {
			Stack<Node<V>> path = new Stack<>();
			while (cur != parents.get(cur)) {
				path.push(cur);
				cur = parents.get(cur);
			}
			while (!path.isEmpty()) {
				parents.put(path.pop(), cur);
			}
			return cur;
		}

		public void union(V a, V b) {
			Node<V> aHead = findFather(nodes.get(a));
			Node<V> bHead = findFather(nodes.get(b));
			if (aHead != bHead) {
				int aSetSize = sizeMap.get(aHead);
				int bSetSize = sizeMap.get(bHead);
				Node<V> big = aSetSize >= bSetSize ? aHead : bHead;
				Node<V> small = big == aHead ? bHead : aHead;
				parents.put(small, big);
				sizeMap.put(big, aSetSize + bSetSize);
				sizeMap.remove(small);
			}
		}

		public int sets() {
			return sizeMap.size();
		}

	}

	public static int numIslands2(char[][] board) {
		int row = board.length;
		int col = board[0].length;
		UnionFind2 uf = new UnionFind2(board);
		for (int j = 1; j < col; j++) {
			if (board[0][j - 1] == '1' && board[0][j] == '1') {
				uf.union(0, j - 1, 0, j);
			}
		}
		for (int i = 1; i < row; i++) {
			if (board[i - 1][0] == '1' && board[i][0] == '1') {
				uf.union(i - 1, 0, i, 0);
			}
		}
		for (int i = 1; i < row; i++) {
			for (int j = 1; j < col; j++) {
				if (board[i][j] == '1') {
					if (board[i][j - 1] == '1') {
						uf.union(i, j - 1, i, j);
					}
					if (board[i - 1][j] == '1') {
						uf.union(i - 1, j, i, j);
					}
				}
			}
		}
		return uf.sets();
	}

	public static class UnionFind2 {//把二维数组转成一维,对二维数组(i,j)->i*列+j
		private int[] parent;
		private int[] size;
		private int[] help;
		private int col;//列
		private int sets;//集合数量

		public UnionFind2(char[][] board) {
			col = board[0].length;
			sets = 0;
			int row = board.length;
			int len = row * col;//一共有几个数
			parent = new int[len];
			size = new int[len];
			help = new int[len];
			for (int r = 0; r < row; r++) {//初始化
				for (int c = 0; c < col; c++) {
					if (board[r][c] == '1') {
						int i = index(r, c);
						parent[i] = i;
						size[i] = 1;
						sets++;
					}
				}
			}
		}

		// (r,c) -> i,用i代替(r,c)
		private int index(int r, int c) {//r行c列对应的下标
			return r * col + c;
		}

		// 原始位置 -> 下标
		private int find(int i) {
			int hi = 0;
			while (i != parent[i]) {
				help[hi++] = i;
				i = parent[i];
			}
			for (hi--; hi >= 0; hi--) {
				parent[help[hi]] = i;
			}
			return i;
		}

		public void union(int r1, int c1, int r2, int c2) {
			int i1 = index(r1, c1);
			int i2 = index(r2, c2);
			int f1 = find(i1);
			int f2 = find(i2);
			if (f1 != f2) {
				if (size[f1] >= size[f2]) {
					size[f1] += size[f2];
					parent[f2] = f1;
				} else {
					size[f2] += size[f1];
					parent[f1] = f2;
				}
				sets--;
			}
		}

		public int sets() {
			return sets;
		}

	}

	// 为了测试
	public static char[][] generateRandomMatrix(int row, int col) {
		char[][] board = new char[row][col];
		for (int i = 0; i < row; i++) {
			for (int j = 0; j < col; j++) {
				board[i][j] = Math.random() < 0.5 ? '1' : '0';
			}
		}
		return board;
	}

	// 为了测试
	public static char[][] copy(char[][] board) {
		int row = board.length;
		int col = board[0].length;
		char[][] ans = new char[row][col];
		for (int i = 0; i < row; i++) {
			for (int j = 0; j < col; j++) {
				ans[i][j] = board[i][j];
			}
		}
		return ans;
	}

	// 为了测试
	public static void main(String[] args) {
		int row = 0;
		int col = 0;
		char[][] board1 = null;
		char[][] board2 = null;
		char[][] board3 = null;
		long start = 0;
		long end = 0;

		row = 1000;
		col = 1000;
		board1 = generateRandomMatrix(row, col);
		board2 = copy(board1);
		board3 = copy(board1);

		System.out.println("感染方法、并查集(map实现)、并查集(数组实现)的运行结果和运行时间");
		System.out.println("随机生成的二维矩阵规模 : " + row + " * " + col);

		start = System.currentTimeMillis();
		System.out.println("感染方法的运行结果: " + numIslands3(board1));
		end = System.currentTimeMillis();
		System.out.println("感染方法的运行时间: " + (end - start) + " ms");

		start = System.currentTimeMillis();
		System.out.println("并查集(map实现)的运行结果: " + numIslands1(board2));
		end = System.currentTimeMillis();
		System.out.println("并查集(map实现)的运行时间: " + (end - start) + " ms");

		start = System.currentTimeMillis();
		System.out.println("并查集(数组实现)的运行结果: " + numIslands2(board3));
		end = System.currentTimeMillis();
		System.out.println("并查集(数组实现)的运行时间: " + (end - start) + " ms");

		System.out.println();

		row = 10000;
		col = 10000;
		board1 = generateRandomMatrix(row, col);
		board3 = copy(board1);
		System.out.println("感染方法、并查集(数组实现)的运行结果和运行时间");
		System.out.println("随机生成的二维矩阵规模 : " + row + " * " + col);

		start = System.currentTimeMillis();
		System.out.println("感染方法的运行结果: " + numIslands3(board1));
		end = System.currentTimeMillis();
		System.out.println("感染方法的运行时间: " + (end - start) + " ms");

		start = System.currentTimeMillis();
		System.out.println("并查集(数组实现)的运行结果: " + numIslands2(board3));
		end = System.currentTimeMillis();
		System.out.println("并查集(数组实现)的运行时间: " + (end - start) + " ms");

	}

}

拓展:如果matrix极大 设计一种可行的并行方案

空降问题 

 

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

// 本题为leetcode原题
// 测试链接:https://leetcode.com/problems/number-of-islands-ii/
// 所有方法都可以直接通过
public class Code03_NumberOfIslandsII {

	public static List<Integer> numIslands21(int m, int n, int[][] positions) {
		UnionFind1 uf = new UnionFind1(m, n);
		List<Integer> ans = new ArrayList<>();
		for (int[] position : positions) {
			ans.add(uf.connect(position[0], position[1]));
		}
		return ans;
	}

	public static class UnionFind1 {
		private int[] parent;
		private int[] size;//区别,变化之后不在抹去size,因为要用size做标记
		//size=0代表没有初始化过,没有空降过1
		private int[] help;
		private final int row;
		private final int col;
		private int sets;

		public UnionFind1(int m, int n) {
			row = m;
			col = n;
			sets = 0;
			int len = row * col;
			parent = new int[len];
			size = new int[len];
			help = new int[len];
		}

		private int index(int r, int c) {
			return r * col + c;
		}

		private int find(int i) {
			int hi = 0;
			while (i != parent[i]) {
				help[hi++] = i;
				i = parent[i];
			}
			for (hi--; hi >= 0; hi--) {
				parent[help[hi]] = i;
			}
			return i;
		}

		private void union(int r1, int c1, int r2, int c2) {
			if (r1 < 0 || r1 == row || r2 < 0 || r2 == row || c1 < 0 || c1 == col || c2 < 0 || c2 == col) {
				return;//检查越界
			}
			int i1 = index(r1, c1);
			int i2 = index(r2, c2);
			if (size[i1] == 0 || size[i2] == 0) {
				return;
			}
			int f1 = find(i1);
			int f2 = find(i2);
			if (f1 != f2) {
				if (size[f1] >= size[f2]) {
					size[f1] += size[f2];
					parent[f2] = f1;
				} else {
					size[f2] += size[f1];
					parent[f1] = f2;
				}
				sets--; 
		}

		public int connect(int r, int c) {
			int index = index(r, c);
			if (size[index] == 0) {//为零代表第一次来到这个位置 
				parent[index] = index;
				size[index] = 1;
				sets++;
				union(r - 1, c, r, c);
				union(r + 1, c, r, c);
				union(r, c - 1, r, c);
				union(r, c + 1, r, c);
			}
			return sets;
		}

	}

	// 课上讲的如果m*n比较大,会经历很重的初始化,而k比较小,怎么优化的方法
	public static List<Integer> numIslands22(int m, int n, int[][] positions) {
		UnionFind2 uf = new UnionFind2();
		List<Integer> ans = new ArrayList<>();
		for (int[] position : positions) {
			ans.add(uf.connect(position[0], position[1]));
		}
		return ans;
	}

	public static class UnionFind2 {//m*n很大,key相对不大
		private HashMap<String, String> parent;//字符串他爹
		private HashMap<String, Integer> size;
		private ArrayList<String> help;
		private int sets;

		public UnionFind2() {
			parent = new HashMap<>();
			size = new HashMap<>();
			help = new ArrayList<>();
			sets = 0;
		}

		private String find(String cur) {
			while (!cur.equals(parent.get(cur))) {
				help.add(cur);
				cur = parent.get(cur);
			}
			for (String str : help) {
				parent.put(str, cur);
			}
			help.clear();
			return cur;
		}

		private void union(String s1, String s2) {
			if (parent.containsKey(s1) && parent.containsKey(s2)) {
				String f1 = find(s1);
				String f2 = find(s2);
				if (!f1.equals(f2)) {
					int size1 = size.get(f1);
					int size2 = size.get(f2);
					String big = size1 >= size2 ? f1 : f2;
					String small = big == f1 ? f2 : f1;
					parent.put(small, big);
					size.put(big, size1 + size2);
					sets--;
				}
			}
		}

		public int connect(int r, int c) {
			String key = String.valueOf(r) + "_" + String.valueOf(c);
			if (!parent.containsKey(key)) {//之前没空降过的
				parent.put(key, key);
				size.put(key, 1);
				sets++;
				String up = String.valueOf(r - 1) + "_" + String.valueOf(c);
				String down = String.valueOf(r + 1) + "_" + String.valueOf(c);
				String left = String.valueOf(r) + "_" + String.valueOf(c - 1);
				String right = String.valueOf(r) + "_" + String.valueOf(c + 1);
				union(up, key);
				union(down, key);
				union(left, key);
				union(right, key);
			}
			return sets;
		}

	}

}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1448325.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

红日靶场(初学)

按照以前的来说一般是有两层网络的内网和外网 这个也是这样的 所以需要两张网卡&#xff0c;一个用来向外网提供web服务&#xff0c;一个是通向内网 以下就是配置 以下就是一些相关信息 外网网段是写成了192.168.111.1/24 WEB PC DC kali 开始扫描 nmap -sS -sV -Pn -T4 19…

软件实例分享,茶楼收银软件管理系统,支持计时计费商品销售会员管理定时语音提醒功能

软件实例分享&#xff0c;茶楼收银软件管理系统&#xff0c;支持计时计费商品销售会员管理定时语音提醒功能 一、前言 以下软件教程以 佳易王茶社计时计费管理系统软件V18.0为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 问&#xff1a;这个软…

顶级思维方式——认知篇四(全局各个角度考虑结果)

目录 1、空城计司马懿看穿了吗 2、胡宗宪是彻底铲除倭寇、还是要特意留些残余&#xff1f; 3、 都是站在各自的利益、位置上分析问题 4、 识人 5、不要给别人陷害你的机会 6、 最高领导人/管理者&#xff0c;他需要 维护自己英明决策领导、高大形象 7、对领导的投其所好…

C#,数值计算,矩阵的行列式(Determinant)、伴随矩阵(Adjoint)与逆矩阵(Inverse)的算法与源代码

本文发布矩阵&#xff08;Matrix&#xff09;的一些初级算法。 一、矩阵的行列式&#xff08;Determinant&#xff09; 矩阵行列式是指矩阵的全部元素构成的行列式&#xff0c;设A(a)是数域P上的一个n阶矩阵&#xff0c;则所有A(a)中的元素组成的行列式称为矩阵A的行列式&…

【MySQL】待修改

外键约束 含义 外键&#xff1a;用来让两张表的数据之间建立连接&#xff0c;从而保证数据的完整性和一致性。 员工表emp&#xff08;子表&#xff09; idnameagejobsalaryentrydatemanageriddept_id1金庸66总裁200002000-01-01null52张无忌20项目经理125002005-12-05113杨…

栈和队列循环队列(C/C++)

本篇将用数组实现栈、链表实现队列以及使用数组实现循环队列&#xff0c;然后实现了用栈实现队列和用队列实现栈以及一些其他的栈和队列的习题&#xff0c;加深队栈和队列的理解。 若只看对应所需&#xff0c;可直接看文章旁的目录。 1.栈 1.1栈的概念及结构 栈&#xff1a;一…

8.JS中的== 操作符的强制类型转换规则

对于 来说&#xff0c;如果对比双方的类型不一样&#xff0c;就会进行类型转换。假如对比 x 和 y 是否相同&#xff0c;就会进行如下判断流程&#xff1a; 首先会判断两者类型是否相同&#xff0c;类型相同的话就比较两者的大小&#xff1b;类型不相同的话&#xff0c;就会进…

【lesson52】 线程概念

文章目录 线程学习前的了解知识理解线程 线程学习前的了解知识 线程在进程内部执行&#xff0c;是OS调度的基本单位 OS可以做到让进程对进程地址空间进行资源的细粒度划分 比如malloc一块内存空间&#xff0c;我们拿到的一般都是起始位置&#xff0c;但是最终位置我们一般都不…

突发!AI大牛Andrej Karpathy离开OpenAI

刚刚&#xff0c;AI大牛Andrej Karpathy官宣了一条重要消息&#xff1a;他昨天已经从OpenAI离职&#xff0c;不过这中间没有什么戏剧性冲突&#xff0c;他只是想去尝试一下自己的个人项目。 Karpathy在官宣离职的推文中写道&#xff0c;「是的&#xff0c;我昨天离开了OpenAI。…

base64------ “ )!@#$%^*( ”代换 “0-9”

“ )!#$%^&*( ”代换 “0-9” ——[安洵杯 2019]JustBase 题目&#xff1a; VGhlIGdlbxvZ#kgbYgdGhlIEVhcnRoJ#Mgc#VyZmFjZSBpcyBkb!pbmF)ZWQgYnkg dGhlIHBhcnRpY#VsYXIgcHJvcGVydGllcyBvZiB#YXRlci$gUHJlcVudCBvbiBFYXJ)aCBp biBzbxpZCwgbGlxdWlkLCBhbmQgZFzZW(!…

celery异步框架的使用

文章目录 celery的介绍celery的架构celery的快速使用celery 包结构celery 定时 异步 延迟任务django使用celery celery的介绍 celery是什么&#xff1f; -翻译过来是芹菜 -官网&#xff1a;https://docs.celeryq.dev/en/stable/ -吉祥物&#xff1a;芹菜 -分布式的异步任务框架…

计算机网络概述习题拾遗

学习目标&#xff1a; 自下而上第一个提供端到端服务的层次 路由器、交换机、集线器实现的功能层 TCP/IP体系结构的网络接口层对应OSI体系结构的哪两个层次 分组数量对总时延的影响 如果这篇文章对您有帮助&#xff0c;麻烦点赞关注支持一下动力猿吧&#xff01; 学习内容…

《剑指 Offer》专项突破版 - 面试题 44 : 二叉树中每层的最大值(两种方法 + C++ 实现)

目录 前言 一、只用一个队列 二、使用两个队列 前言 题目链接&#xff1a;LCR 044. 在每个树行中找最大值 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 输入一棵二叉树&#xff0c;请找出二叉树中每层的最大值。例如&#xff0c;输入下图中的二叉树&#x…

VueCLI核心知识综合案例TodoList

目录 1 拿到一个功能模块首先需要拆分组件&#xff1a; 2 使用组件实现静态页面的效果 3 分析数据保存在哪个组件 4 实现添加数据 5 实现复选框勾选 6 实现数据的删除 7 实现底部组件中数据的统计 8 实现勾选全部的小复选框来实现大复选框的勾选 9 实现勾选大复选框来…

RIDERS: Radar-Infrared Depth Estimation for Robust Sensing

RIDERS: 恶劣天气及环境下鲁棒的密集深度估计 论文链接&#xff1a;https://arxiv.org/pdf/2402.02067.pdf 作者单位&#xff1a;浙江大学, 慕尼黑工业大学 代码链接&#xff1a;https://github.com/MMOCKING/RIDERS 1. 摘要&#xff08;Abstract&#xff09; 恶劣的天气条件, …

Spring Boot 笔记 019 创建接口_文件上传

1.1 创建阿里OSS bucket OSS Java SDK 兼容性和示例代码_对象存储(OSS)-阿里云帮助中心 (aliyun.com) 1.2 编写工具类 package com.geji.utils;import com.aliyun.oss.ClientException; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun…

Waymo数据集下载与使用

在撰写论文时&#xff0c;接触到一个自动驾驶数据集Waymo Dataset 论文链接为&#xff1a;https://arxiv.org/abs/1912.04838v7 项目链接为&#xff1a;https://github.com/waymo-research/waymo-open-dataset 数据集链接为&#xff1a;https://waymo.com/open waymo提供了两种…

K8sGPT 的使用

K8sGPT 介绍 k8sgpt 是一个扫描 Kubernetes 集群、诊断和分类问题的工具。它将 SRE 经验编入其分析器中&#xff0c;并帮助提取最相关的信息&#xff0c;通过人工智能来丰富它。它还可以与 OpenAI、Azure、Cohere、Amazon Bedrock 和本地模型结合使用。 K8sGPT Github 地址 …

助眠神器小程序源码|白噪音|小睡眠|微信小程序前后端开源

安装要求和说明后端程序运行环境&#xff1a;NginxPHP7.4MySQL5.6 PHP程序扩展安装&#xff1a;sg11 网站运行目录设置为&#xff1a;public 伪静态规则选择&#xff1a;thinkphp 数据库修改文件路径&#xff1a;/config/database.php需要配置后端的小程序配置文件&#xff0c;…

Java中锁的应用

文章目录 前言一、场景描述二、加锁1.synchronized2.ReentrantLock 三、扩展1.ThreadLocal 总结 前言 在多线程场景下&#xff0c;多个线程同时对共享变量进行操作是存在风险的&#xff0c;这时候就需要加锁来保证数据的正确性。 一、场景描述 我这里有5个无人机,准备卖到乌克…