递归、搜索与回溯算法 - 3 ( floodfill 记忆化搜素 9000 字详解 )
一:floodfill 算法
1.1 图像渲染
题目链接:图像渲染

class Solution {// 首先先定义四个方向的向量int[] dx = {0, 0, 1, -1};int[] dy = {1, -1, 0, 0};// 接着用 m 记录行数,n 记录列数,prev 记录 (sr, sc) 位置的原始数值int m, n, prev;public int[][] floodFill(int[][] image, int sr, int sc, int color){// 如果起始像素的颜色已经是目标颜色,则无需填充if (image[sr][sc] == color) return image;// 先初始化一下 m,n 和 prevm = image.length;n = image[0].length;prev = image[sr][sc];// 接着调用 dfs 函数,调用后直接返回 image 即可dfs(image, sr, sc, color);return image;}public void dfs(int[][] image, int i, int j, int color){// 首先先把当前位置的值修改成 color 的值image[i][j] = color;// 接着开始遍历这个位置的四个方向for(int k = 0; k < 4; k++){int x = dx[k] + i, y = dy[k] + j;// 判断新位置是否合法:在边界内且颜色与初始颜色相同if (x >= 0 && x < m && y >= 0 && y < n && image[x][y] == prev) dfs(image, x, y, color); }}
}

1.2 岛屿数量
题目链接:岛屿数量


class Solution {// 先定义四个方向int[] dx = {0, 0, 1, -1};int[] dy = {1, -1, 0, 0};// 再定义一个 vis 数组,用于标记当前的陆地是否被访问过, m 记录行数,n 记录列数boolean[][] vis;int m, n;public int numIslands(char[][] grid){// 接着先初始化一下 m, n 以及 vis ,并定义一个 ret 用于记录最终的结果m = grid.length;n = grid[0].length;vis = new boolean[m][n];int ret = 0;// 接着开始遍历网格中的每一个陆地,当遍历一个陆地后把这个陆地所属的岛屿的陆地全部标记为已访问的状态for(int i = 0; i < m; i++){for(int j = 0; j < n; j++){if(!vis[i][j] && grid[i][j] == '1'){ret++;dfs(grid, i, j);}}}return ret;}public void dfs(char[][] grid, int i, int j){// 首先先把当前位置标记为已访问的状态vis[i][j] = true;// 接着去处理这个位置的四个方向for(int k = 0; k < 4; k++){int x = i + dx[k], y = j + dy[k];// 如果 x 和 y 不越界,并且 (i, j) 位置没有被访问过且这个位置是陆地,那么就继续递归,把这个位置当作新的起点if(x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && grid[x][y] == '1') dfs(grid, x, y); }}
}

1.3 岛屿的最大面积
题目链接:岛屿的最大面积


class Solution {// 先定义四个方向以及 vis 数组,vis 数组用于标记当前陆地是否被访问过, count 用于记录当前岛屿的面积,m 用于记录行数,n 用于记录列数int[] dx = {1, -1, 0, 0};int[] dy = {0, 0, 1, -1};boolean[][] vis;int count, m ,n;public int maxAreaOfIsland(int[][] grid){// 先初始化一下全局变量,并定义 ret 用于记录最终的结果m = grid.length;n = grid[0].length;vis = new boolean[m][n];int ret = 0;for(int i = 0; i < m; i++){for(int j = 0; j < n; j++){if(grid[i][j] == 1 && !vis[i][j]){// 每次循环都把 count 重新弄为0count = 0;dfs(grid, i, j);// 调用完 dfs 函数后开始更新 ret 的值ret = Math.max(ret, count);}}}return ret; // 循环结束后返回 ret}public void dfs(int[][] grid, int i, int j){// 首先把当前位置标记为已访问过的状态,并增加计数vis[i][j] = true;count++;// 接着开始处理这个位置的四个方向for(int k = 0; k < 4; k++){int x = dx[k] + i, y = dy[k] + j;if(x >=0 && x < m && y >= 0 && y < n && grid[x][y] == 1 && !vis[x][y]){dfs(grid, x, y); // 递归处理这个位置的四个方向}}}
}

1.4 被围绕的区域
题目链接:被围绕的区域


class Solution {// 先定义四个方向,并用 m 记录行数,n 记录列数int[] dx = {1, -1, 0, 0};int[] dy = {0, 0, 1, -1};int m, n;public void solve(char[][] board){// 初始化一下 m 和 nm = board.length;n = board[0].length;// 下面处理一下 board 的边界 0,首先处理第一行和最后一行for(int j = 0; j < n; j++){if (board[0][j] == 'O') dfs(board, 0, j);if (board[m - 1][j] == 'O') dfs(board, m - 1, j);}// 接着处理第一列和最后一列for(int i = 0; i < m; i++){if(board[i][0] == 'O') dfs(board, i, 0);if(board[i][n - 1] == 'O') dfs(board, i, n - 1);}// 处理完边界情况后开始正常处理 board 中的 0,找到 0 后进行深度优先遍历即可for(int i = 0; i < m; i++){for(int j = 0; j < n; j++){if(board[i][j] == '.') board[i][j] = 'O';else if(board[i][j] == 'O') board[i][j] = 'X';}}}public void dfs(char[][] board, int i, int j){// 首先先把当前位置标记为 . board[i][j] = '.';// 接着去处理这个位置的四个方向for(int k = 0; k < 4; k++){int x = dx[k] + i, y = dy[k] + j;if(x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'O'){dfs(board, x, y);}}}
}

1.5 太平洋大西洋水流问题
题目链接:太平洋大西洋水流问题


class Solution {// 首先定义一下四个方向,并定义一下行数 m 和列数 nint[] dx = {1, -1, 0, 0};int[] dy = {0, 0, 1, -1};int m, n;public List<List<Integer>> pacificAtlantic(int[][] heights){// 初始化一下 m 和 n,再根据 m 和 n 初始化一下两个标记数组m = heights.length;n = heights[0].length;// pac 数组的值为 true 代表从太平洋出发,能到达这个点boolean[][] pac = new boolean[m][n];boolean[][] atl = new boolean[m][n];// 接着先遍历太平洋的边,即第一行和第一列for(int j = 0; j < n; j++) dfs(heights, 0, j, pac);for(int i = 0; i < m; i++) dfs(heights, i, 0, pac);// 接着再遍历大西洋的边,即最后一行和最后一列for(int j = 0; j < n; j++) dfs(heights, m - 1, j, atl);for(int i = 0; i < m; i++) dfs(heights, i, n - 1, atl);// 接着提取结果List<List<Integer>> ret = new ArrayList<>();for(int i = 0; i < m; i++){for(int j = 0; j < n; j++){if(pac[i][j] == true && atl[i][j] == true){List<Integer> tmp = new ArrayList<>();tmp.add(i);tmp.add(j);ret.add(tmp);}}}return ret;}/*** 深度优先搜索 (DFS):标记能流入某个洋的格子* @param h 高度矩阵* @param i 当前格子的行坐标* @param j 当前格子的列坐标* @param vis 标记数组(用于标记是否能流入太平洋或大西洋)*/public void dfs(int[][] h, int i, int j, boolean[][] vis){// 首先先把当前位置标记为 true vis[i][j] = true;// 接着处理一下这个位置的四个方向for(int k = 0; k < 4; k++){int x = dx[k] + i, y = dy[k] + j;if(x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && h[x][y] >= h[i][j]){dfs(h, x, y, vis);}}}
}

1.6 扫雷游戏
题目链接:扫雷游戏


class Solution {// 定义八个方向的移动向量,用于表示上下左右以及四个对角线方向int[] dx = {0, 0, 1, -1, 1, 1, -1, -1};int[] dy = {1, -1, 0, 0, 1, -1, 1, -1};int m, n;public char[][] updateBoard(char[][] board, int[] click){// 先初始化一下 m 和 n,接着获取一下点击位置的坐标m = board.length;n = board[0].length;int x = click[0], y = click[1];// 接着判断一下这个点是地雷还是空白字符if(board[x][y] == 'M'){board[x][y] = 'X';return board; // 直接结束游戏}else{// 否则挖到的是空白方块dfs(board, x, y);return board; // 返回更新过后的 board}}/*** 深度优先搜索 (DFS):更新棋盘* @param board 当前的扫雷棋盘* @param i 当前的行坐标* @param j 当前的列坐标*/public void dfs(char[][] board, int i, int j){// 首先统计一下当前位置旁边的地雷个数int count = 0;for(int k = 0; k < 8; k++){int x = dx[k] + i, y = dy[k] + j;if(x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'M') count++;}// 接着根据 count 的个数分情况讨论,如果为 0 则修改成 B 如果不为 0 则修改成数字if(count == 0){board[i][j] = 'B'; // 标记当前格子为空白for(int k = 0; k < 8; k++){int x = dx[k] + i, y = dy[k] + j;if(x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'E'){dfs(board, x, y);}}}else{// 将当前位置标记为周围地雷的数量('1'-'8')board[i][j] = (char) ('0' + count);return; // 如果是数字就不再递归了}}
}

1.7 衣橱整理
题目链接:衣橱整理


class Solution {int m, n, k; // 网格的行数、列数以及限制条件 kboolean[][] vis; // 用于记录某个位置是否已被访问int ret; // 记录可以到达的格子数量int[] dx = {1, -1, 0, 0}; int[] dy = {0, 0, 1, -1}; public int wardrobeFinishing(int _m, int _n, int _k) {// 初始化全局变量m = _m;n = _n;k = _k;vis = new boolean[m][n]; // 从起点 (0, 0) 开始深度优先搜索dfs(0, 0);return ret;}/*** 深度优先搜索 (DFS):从当前格子开始递归探索可达的格子* @param i 当前格子的行坐标* @param j 当前格子的列坐标*/public void dfs(int i, int j) {// 访问当前格子,增加计数,并标记当前格子为已访问ret++;vis[i][j] = true; // 接着遍历四个方向for (int k = 0; k < 4; k++) {int x = i + dx[k]; int y = j + dy[k]; if (x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && check(x, y)) {dfs(x, y); }}}/*** 判断某个格子的坐标是否满足位数和限制条件* @param i 行坐标* @param j 列坐标* @return 如果位数和小于等于 k,则返回 true,否则返回 false*/public boolean check(int i, int j) {int tmp = 0; // 存储行坐标和列坐标的位数和// 计算行坐标的各位数字之和while (i != 0) {tmp += i % 10;i /= 10;}// 计算列坐标的各位数字之和while (j != 0) {tmp += j % 10;j /= 10;}// 如果位数和小于等于 k,则返回 truereturn tmp <= k;}
}

二:记忆化搜索
2.1 斐波那契数列 (必看)
题目链接:斐波那契数列 (必看)



class Solution {// 记忆化搜索实现int[] memo; // 备忘录public int fib(int n) {memo = new int[n + 1];for (int i = 0; i <= n; i++) memo[i] = -1; // 初始化备忘录为 -1return dfs(n);}public int dfs(int n) {if (memo[n] != -1) return memo[n]; // 如果已经计算过,直接返回备忘录中的值if (n == 0 || n == 1) {memo[n] = n; // 边界情况return n;}memo[n] = dfs(n - 1) + dfs(n - 2); // 递归返回时把结果放在备忘录里return memo[n];}
}
class Solution {// 动态规划实现public int fib(int n) {if (n == 0) return 0;if (n == 1) return 1;int[] dp = new int[n + 1]; // 用于存储子问题的结果dp[0] = 0;dp[1] = 1;// 计算斐波那契数列for (int i = 2; i <= n; i++) {dp[i] = dp[i - 1] + dp[i - 2];}return dp[n];}
}

2.2 不同路径
题目链接:不同路径


class Solution {public int uniquePaths(int m, int n){// 记忆化搜索解法// 先创建一个备忘录 memo int[][] memo = new int[m + 1][n + 1];return dfs(m, n, memo);}// 递归函数:计算到达位置 (i, j) 的路径数public int dfs(int i, int j, int[][] memo){// 首先先看看备忘录中有没有if(memo[i][j] != 0) return memo[i][j];// 处理一下越界的情况if(i == 0 || j == 0) return 0;// 处理一下起点if(i == 1 && j == 1) return 1;// 如果备忘录没有就开始递归,递归前记录一下值memo[i][j] = dfs(i - 1, j, memo) + dfs(i, j - 1, memo);return memo[i][j];}
}

2.3 最长递增子序列
题目链接:最长递增子序列


class Solution {public int lengthOfLIS(int[] nums){// 记忆化搜索实现// 先根据 nums 的长度初始化 memo 数组int n = nums.length;int[] memo = new int[n];// 接着枚举一下每个位置的 dfs 值,把较大的值放入 ret 中int ret = 0;for(int i = 0; i < n; i++){ret = Math.max(ret, dfs(i, nums, memo));}return ret;}// 递归函数:计算从位置 pos 开始的最长上升子序列长度public int dfs(int pos, int[] nums, int[] memo){// 首先先看看备忘录里有没有这个 dfs 值if(memo[pos] != 0) return memo[pos];int ret = 1; // 因为路径是包含自己的,所以我们从 1 开始计数// 向后递归一下,把较大的值赋值给 retfor(int i = pos + 1; i < nums.length; i++){if(nums[i] > nums[pos]){ret = Math.max(ret, dfs(i, nums, memo) + 1);}}// 记录当前计算结果memo[pos] = ret;return ret;}
}
class Solution {public int lengthOfLIS(int[] nums) {// 动态规划实现int n = nums.length;// dp[i] 表示以 nums[i] 作为结尾的最长上升子序列的长度int[] dp = new int[n];// 初始化 dp 数组,每个位置最少包含自身一个元素Arrays.fill(dp, 1);int ret = 0; // 记录最长上升子序列的长度// 从后往前填表for (int i = n - 1; i >= 0; i--) {// 从 i 的后一个元素开始遍历for (int j = i + 1; j < n; j++) {// 如果 nums[j] > nums[i],说明可以将 nums[j] 接在 nums[i] 后面if (nums[j] > nums[i]) {// 更新 dp[i],选择最长的子序列dp[i] = Math.max(dp[i], dp[j] + 1);}}ret = Math.max(ret, dp[i]);}return ret;}
}

2.4 猜数字大小 II
题目链接:猜数字大小 II


class Solution {// 用于存储递归结果的备忘录数组,memo[i][j] 表示区间 [i, j] 的最小代价int[][] memo;public int getMoneyAmount(int n) {// 先初始化备忘录memo = new int[n + 1][n + 1];// 从 [1, n] 开始return dfs(1, n);}// 递归函数:计算区间 [left, right] 的最小代价public int dfs(int left, int right) {// 如果左边界大于或等于右边界,说明只剩一个数字或者范围无效,代价为 0if (left >= right) return 0;// 如果该区间已经计算过,直接返回备忘录中的值if (memo[left][right] != 0) {return memo[left][right];}int ret = Integer.MAX_VALUE;// 枚举当前区间 [left, right] 中的所有数字作为猜测点for (int head = left; head <= right; head++) {// 递归计算左区间 [left, head - 1] 的最小代价int x = dfs(left, head - 1);// 递归计算右区间 [head + 1, right] 的最小代价int y = dfs(head + 1, right);// 选择左区间和右区间中较大的代价,并加上当前猜测点的代价int cost = Math.max(x, y) + head;// 更新当前区间的最小代价ret = Math.min(ret, cost);}// 将结果存入备忘录中memo[left][right] = ret;// 返回当前区间的最小代价return ret;}
}

2.5 矩阵中的最长递增路径
题目链接:矩阵中的最长递增路径


class Solution {// 先定义一下四个方向,并用·m 记录行号,n 记录列号,用 memo 当作一个备忘录,用于存储从每个点开始的最长递增路径的长度int m, n;int[] dx = {1, -1, 0, 0};int[] dy = {0, 0, 1, -1};int[][] memo;public int longestIncreasingPath(int[][] matrix){// 先初始化一下 m,n 和 memom = matrix.length;n = matrix[0].length;memo = new int[m][n];// 暴力枚举所有位置的长度,接着取出最大值int ret = 0;for(int i = 0; i < m; i++){for(int j = 0; j < n; j++){ret = Math.max(ret, dfs(matrix, i, j));}}return ret;}// 深度优先搜索函数:计算从位置 (i, j) 开始的最长递增路径的长度public int dfs(int[][] matrix, int i, int j){// 先判断一下备忘录里有没有这个值if(memo[i][j] != 0) return memo[i][j];// ret 初始化为 1 ,因为自己也算int ret = 1;for(int k = 0; k < 4; k++){int x = dx[k] + i, y = dy[k] + j;if (x >= 0 && x < m && y >= 0 && y < n && matrix[x][y] > matrix[i][j]){ret = Math.max(ret, dfs(matrix, x, y) + 1);}}// 结果返回前先把结果存入备忘录中memo[i][j] = ret;return ret;}
}

相关文章:
递归、搜索与回溯算法 - 3 ( floodfill 记忆化搜素 9000 字详解 )
一:floodfill 算法 1.1 图像渲染 题目链接:图像渲染 class Solution {// 首先先定义四个方向的向量int[] dx {0, 0, 1, -1};int[] dy {1, -1, 0, 0};// 接着用 m 记录行数,n 记录列数,prev 记录 (sr, sc) 位置的…...
YOLOv9改进,YOLOv9引入CAS-ViT(卷积加自注意力视觉变压器)中AdditiveBlock模块,二次创新RepNCSPELAN4结构
摘要 CAS-ViT 是一种为高效移动应用设计的视觉Transformer。模型通过结合卷积操作与加性自注意机制,在保持高性能的同时显著减少计算开销,适合资源受限的设备如手机。其核心组件 AdditiveBlock 通过多维度信息交互和简化的加性相似函数,实现了高效的上下文信息整合,避免了…...
HDLCPPP原理与配置
前言: 广域网中经常会使用串行链路来提供远距离的数据传输,高级数据链路控制HDLC( High-Level Data Link Control )和点对点协议PPP( Point to Point Protocol)是两种典型的串口封装协议。 HDLC协议: 原理…...
react + vite 中的环境变量怎么获取
一、Vite 环境变量基础 创建一个.env文件,Vite 定义的环境变量需要以VITE_开头。 VITE_API_URL "http://localhost:3000/api" 生产模式创建.env.production。 VITE_API_URL "https://production-api-url.com/api" 二、在 React 组件中获…...
知识蒸馏中有哪些经验| 目标检测 |mobile-yolov5-pruning-distillation项目中剪枝知识分析
项目地址:https://github.com/Syencil/mobile-yolov5-pruning-distillation 项目时间:2022年 mobile-yolov5-pruning-distillation是一个以yolov5改进为主的开源项目,主要包含3中改进方向:更改backbone、模型剪枝、知识蒸馏。这里…...
Oracle 19c RAC单节点停机维护硬件
背景 RAC 环境下一台主机硬件光纤卡不定时重启,造成链路会间断几秒,期间数据库会话响应时间随之变长,该光纤卡在硬件厂商的建议下,决定停机更换备件,为保证生产影响最小,决定停掉该节点,另外节…...
Linux系统 进程
Linux系统 进程 进程私有地址空间用户模式和内核模式上下文切换 进程控制系统调用错误处理进程控制函数获取进程 ID创建和终止进程回收子进程让进程休眠加载并运行程序 进程 异常是允许操作系统内核提供进程(process)概念的基本构造块,进程是…...
机载视频流回传+编解码方案
无线网络,低带宽场景。不能直接转发ROS raw image(10MB/s),而要压缩(编码)后再传输。可以用rtsp的udp传输或者直接传输话题,压缩方法有theora(ROS image_transport默认支持ÿ…...
Ubuntu 20.04 Server版连接Wifi
前言 有时候没有网线口插网线或者摆放电脑位置不够时,需要用Wifi联网。以下记录Wifi联网过程。 环境:Ubuntu 20.04 Server版,无UI界面 以下操作均为root用户,如果是普通用户,请切换到root用户,或者在需要权…...
【VRChat 改模】开发环境搭建:VCC、VRChat SDK、Unity 等环境配置
一、配置 Unity 相关 1.下载 UnityHub 下载地址:https://unity.com/download 安装打开后如图所示: 2.下载 VRChat 官方推荐版本的 Unity 跳转界面(VRChat 官方推荐页面):https://creators.vrchat.com/sdk/upgrade/…...
人工智能的微积分基础
目录 编辑 引言 微积分的基本概念 1. 导数 2. 积分 3. 微分方程 微积分在人工智能中的应用 1. 机器学习中的优化 2. 反向传播算法 3. 概率与统计 4. 控制理论 5. 自然语言处理中的梯度 6. 计算机视觉中的积分 7. 优化算法中的微积分 8. 微分几何在深度学习中的…...
Android 基础类(01)- Thread类 - readyToRun和threadLoop
一、前言: 在阅读AOSP代码过程中,我们经常会看到Thread子类重写两个方法:readyToRun和threadLoop,不清楚的同学,可能在这儿连调用逻辑都搞不清楚了,因为找不到谁调用了它。我这儿先不去深究Thread内部逻辑…...
C++设计模式之构造器
动机 在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。 如何…...
红日靶场-5
环境搭建 这个靶场相对于前几个靶场来说较为简单,只有两台靶机,其中一台主机是win7,作为我们的DMZ区域的入口机,另外一台是windows2008,作为我们的域控主机,所以我们只需要给我们的win7配置两张网卡&#…...
做异端中的异端 -- Emacs裸奔之路3: 上古神键Hyper
谈一下快捷捷冲突的问题。 Emacs几乎穷尽所有组合键 我用下面命令,在Fundamental模式下,枚举所有绑定。 (defun keymap-lookup-test-fn(); printable keys(setq printable-chars (number-sequence 33 126))(setq i 0)(while (< i (length printable…...
Java多线程介绍及使用指南
“多线程”:并发 要介绍线程,首先要区分开程序、进程和线程这三者的区别。 程序:具有一定功能的代码的集合,但是是静态的,没有启动运行 进程:启动运行的程序【资源的分配单位】 线程:进程中的…...
HarmonyOS 5.0应用开发——列表(List)
【高心星出品】 文章目录 列表(List)列表介绍列表布局设置主轴方向设置交叉轴方向 列表填充分组列表填充 滚动条位置设置滚动位置滚到监听 列表项侧滑 列表(List) 列表介绍 列表作为一种容器,会自动按其滚动方向排列…...
自动化电气行业的优势和劣势是什么
优势 市场需求广泛: 自动化电气技术广泛应用于电力系统、制造业、交通、农业等多个领域,随着智能化、数字化趋势的加强,其市场需求持续增长。在智能制造、智能电网等领域,自动化电气技术更是发挥着关键作用,推动了行业…...
第 42 章 - Go语言 设计模式
在Go语言中,设计模式是一种被广泛接受的解决常见问题的最佳实践。这些模式可以分为三类:创建型模式、结构型模式和行为型模式。下面我将结合案例以及源代码对这三种类型的设计模式进行详细讲解。 创建型模式 创建型模式主要关注对象的创建过程…...
【机器学习】---大语言模型
引言:开启大语言模型的奇幻旅程 近年来,人工智能(AI)领域正在经历一场前所未有的技术革命,而其中最耀眼的明星莫过于大语言模型(Large Language Models, LLMs)。这些模型,犹如现代科…...
地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...
