算法笔记-lc-827. 最大人工岛
给你一个大小为 n x n 二进制矩阵 grid 。最多 只能将一格 0 变成 1 。
返回执行此操作后,grid 中最大的岛屿面积是多少?
岛屿 由一组上、下、左、右四个方向相连的 1 形成。
示例 1:
输入: grid = [[1, 0], [0, 1]]
输出: 3
解释: 将一格0变成1,最终连通两个小岛得到面积为 3 的岛屿。
示例 2:
输入: grid = [[1, 1], [1, 0]]
输出: 4
解释: 将一格0变成1,岛屿的面积扩大为 4。
示例 3:
输入: grid = [[1, 1], [1, 1]]
输出: 4
解释: 没有0可以让我们变成1,面积依然为 4。
n == grid.length
n == grid[i].length
1 <= n <= 500
grid[i][j] 为 0 或 1
首先跑一次dfs找到所有的联通块,统计每个点所属的联通块标号以及该联通块下点的个数。之后枚举所有为0的点,拓展四周为1的点,进行合并判断。
class Solution {
int[][] grid;
int flag=0;
public int largestIsland(int[][] grid) {
this.grid=grid;
for(int i=0;i<grid.length;i++){
for(int j=0;j<grid[0].length;j++){
if(grid[i][j]==1){
flag=0;
bfs(i,j);
}
}
}
int max=0;
for(int i=0;i<grid.length;i++){
for(int j=0;j<grid[0].length;j++){
if(grid[i][j]==0){
int flag=1-add(i-1,j)-add(i+1,j)-add(i,j-1)-add(i,j+1);
max=Math.max(max,flag);
}
}
}
return max;
}
public void bfs(int i,int j){
if(i<0||i>=grid.length){
return;
}
if(j<0||j>=grid[0].length){
return;
}
if(grid[i][j]==1){
flag++;
bfs(i+1,j);
bfs(i-1,j);
bfs(i,j+1);
bfs(i,j-1);
grid[i][j]=-flag;
}
}
public int add(int i,int j){
if(i<0||i>=grid.length){
return 0;
}
if(j<0||j>=grid[0].length){
return 0;
}
return grid[i][j];
}
}
由于数据范围,递归的时候会栈溢出,所以可以采用栈或队列辅助优化,复杂度分析
时间复杂度:O(n²),其中 n 是 grid 的长与宽。使用深度优先搜索获取岛屿面积时,总共访问不超过 n^2个点。
空间复杂度:O(n²),保存 tag 与area 需要 O(n^2)O(n²) 的空间。
为了方便,我们令 grid 为 g。
根据题意,容易想到通过「并查集」来维护所有连通块大小,再通过「枚举」来找最优翻转点。
具体的,我们可以先使用「并查集」维护所有 g[i][j] = 1g[i][j]=1 的块连通性,并在维护连通性的过程中,使用 sz[idx] 记录下每个连通块的大小(注意:只有连通块根编号,sz[idx] 才有意义,即只有 sz[find(x)] 才有意义)。
随后我们再次遍历 g,根据原始的 g[i][j]g[i][j] 的值进行分别处理:
若 g[i][j] = 1g[i][j]=1,该位置不会作为翻转点,但真实最大面积未必是由翻转后所导致的(可能取自原有的连通块),因此我们需要将 sz[root] 参与比较,其中 root 为 (i, j)(i,j) 所属的连通块根节点编号;
若 g[i][j] = 0g[i][j]=0,该位置可作为翻转点,我们可以统计其四联通位置对应的连通块大小总和 tot(注意若四联通方向有相同连通块,只统计一次),那么 tot + 1tot+1 即是翻转该位置所得到的新连通块大小。
最后对所有连通块大小取最大值即是答案。
一些细节:为了方便,我们令点 (i,j) 的编号从 11 开始;
同时由于我们本身就要用 sz 数组,因此我们可以随手把并查集的「按秩合并」也加上。体现在 union 操作时,我们总是将小的连通块合并到大的连通块上,从而确保我们并查集单次操作即使在最坏情况下复杂度仍为O(α(n))(可看作常数)。需要注意只有同时应用「路径压缩」和「按秩合并」,并查集操作复杂度才为 O(α(n))。
class Solution {
static int N = 510;
static int[] p = new int[N * N], sz = new int[N * N];
int[][] dirs = new int[][]{{1,0},{-1,0},{0,1},{0,-1}};
int find(int x) {
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
void union(int a, int b) {
int ra = find(a), rb = find(b);
if (ra == rb) return ;
if (sz[ra] > sz[rb]) {
union(b, a);
} else {
sz[rb] += sz[ra]; p[ra] = p[rb];
}
}
public int largestIsland(int[][] g) {
int n = g.length;
for (int i = 1; i <= n * n; i++) {
p[i] = i; sz[i] = 1;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (g[i][j] == 0) continue;
for (int[] di : dirs) {
int x = i + di[0], y = j + di[1];
if (x < 0 || x >= n || y < 0 || y >= n || g[x][y] == 0) continue;
union(i * n + j + 1, x * n + y + 1);
}
}
}
int ans = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (g[i][j] == 1) {
ans = Math.max(ans, sz[find(i * n + j + 1)]);
} else {
int tot = 1;
Set<Integer> set = new HashSet<>();
for (int[] di : dirs) {
int x = i + di[0],y = j + di[1];
if (x < 0 || x >= n || y < 0 || y >= n || g[x][y] == 0) continue;
int root = find(x * n + y + 1);
if (set.contains(root)) continue;
tot += sz[root];
set.add(root);
}
ans = Math.max(ans, tot);
}
}
}
return ans;
}
}
时间复杂度:O(n^2)
空间复杂度:O(n^2)
目录一.加解密算法数字签名对称加密DES(DataEncryptionStandard)3DES(TripleDES)AES(AdvancedEncryptionStandard)RSA加密法DSA(DigitalSignatureAlgorithm)ECC(EllipticCurvesCryptography)非对称加密签名与加密过程非对称加密的应用对称加密与非对称加密的结合二.数字证书图解一.加解密算法加密简单而言就是通过一种算法将明文信息转换成密文信息,信息的的接收方能够通过密钥对密文信息进行解密获得明文信息的过程。根据加解密的密钥是否相同,算法可以分为对称加密、非对称加密、对称加密和非
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
我需要用任何语言编写一个算法,根据3个因素对数组进行排序。我以度假村为例(如Hipmunk)。假设我想去度假。我想要最便宜的地方、最好的评论和最多的景点。但是,显然我找不到在所有3个中都排名第一的方法。Example(assumingthereare20importantattractions):ResortA:$150/night...98/100infavorablereviews...18of20attractionsResortB:$99/night...85/100infavorablereviews...12of20attractionsResortC:$120/night
下面有没有更优雅的方法来实现这个:输入:array=[1,1,1,0,0,1,1,1,1,0]输出:4我的算法:streak=0max_streak=0arr.eachdo|n|ifn==1streak+=1elsemax_streak=streakifstreak>max_streakstreak=0endendputsmax_streak 最佳答案 类似于w0lf'sanswer,但通过从chunk返回nil来跳过元素:array.chunk{|x|x==1||nil}.map{|_,x|x.size}.max
1.问题描述使用Python的turtle(海龟绘图)模块提供的函数绘制直线。2.问题分析一幅复杂的图形通常都可以由点、直线、三角形、矩形、平行四边形、圆、椭圆和圆弧等基本图形组成。其中的三角形、矩形、平行四边形又可以由直线组成,而直线又是由两个点确定的。我们使用Python的turtle模块所提供的函数来绘制直线。在使用之前我们先介绍一下turtle模块的相关知识点。turtle模块提供面向对象和面向过程两种形式的海龟绘图基本组件。面向对象的接口类如下:1)TurtleScreen类:定义图形窗口作为绘图海龟的运动场。它的构造器需要一个tkinter.Canvas或ScrolledCanva
写在之前Shader变体、Shader属性定义技巧、自定义材质面板,这三个知识点任何一个单拿出来都是一套知识体系,不能一概而论,本文章目的在于将学习和实际工作中遇见的问题进行总结,类似于网络笔记之用,方便后续回顾查看,如有以偏概全、不祥不尽之处,还望海涵。1、Shader变体先看一段代码......Properties{ [KeywordEnum(on,off)]USL_USE_COL("IsUseColorMixTex?",int)=0 [Toggle(IS_RED_ON)]_IsRed("IsRed?",int)=0}......//中间省略,后续会有完整代码 #pragmamulti_c
TCL脚本语言简介•TCL(ToolCommandLanguage)是一种解释执行的脚本语言(ScriptingLanguage),它提供了通用的编程能力:支持变量、过程和控制结构;同时TCL还拥有一个功能强大的固有的核心命令集。TCL经常被用于快速原型开发,脚本编程,GUI和测试等方面。•实际上包含了两个部分:一个语言和一个库。首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一些互交程序如文本编辑器、调试器和shell。由于TCL的解释器是用C\C++语言的过程库实现的,因此在某种意义上我们又可以把TCL看作C库,这个库中有丰富的用于扩展TCL命令的C\C++过程和函数,所以,Tcl是
2022年底,OpenAI的预训练模型ChatGPT给人工智能领域的爱好者和研究人员留下了深刻的印象和启发,他展现的惊人能力将人工智能的研究和应用热度推向高潮,网上也充斥着和ChatGPT的各种聊天,他可以作诗、写小说、写代码、讨论疫情问题等。下面就是一些他的神回复:人命关天的坑: 写歌,留给词作者的机会不多了。。。 回答人类怎么样面对人工智能: 什么是ChatGPT?借用网上的一段介绍,ChatGPT是由人工智能研究实验室OpenAI在2022年11月30日发布的全新聊天机器人模型,一款人工智能技术驱动的自然语言处理工具。它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动
我一直在尝试用Ruby实现Luhn算法。我一直在执行以下步骤:该公式根据其包含的校验位验证数字,该校验位通常附加到部分帐号以生成完整帐号。此帐号必须通过以下测试:从最右边的校验位开始向左移动,每第二个数字的值加倍。将乘积的数字(例如,10=1+0=1、14=1+4=5)与原始数字的未加倍数字相加。如果总模10等于0(如果总和以零结尾),则根据Luhn公式该数字有效;否则无效。http://en.wikipedia.org/wiki/Luhn_algorithm这是我想出的:defvalidCreditCard(cardNumber)sum=0nums=cardNumber.to_s.s
下面是我写的一个计算斐波那契数列中的值的方法:deffib(n)ifn==0return0endifn==1return1endifn>=2returnfib(n-1)+(fib(n-2))endend它工作到n=14,但在那之后我收到一条消息说程序响应时间太长(我正在使用repl.it)。有人知道为什么会这样吗? 最佳答案 Naivefibonacci进行了大量的重复计算-在fib(14)fib(4)中计算了很多次。您可以将内存添加到您的算法中以使其更快:deffib(n,memo={})ifn==0||n==1returnnen