首页 > 其他分享 >代码随想录day52 || 图论3

代码随想录day52 || 图论3

时间:2024-09-06 11:13:55浏览次数:5  
标签:图论 int graph 随想录 dfs next var visited day52

岛屿最大的孤岛面积

package main

import "fmt"

var dirPath = [4][2]int{{0, -1}, {1, 0}, {0, 1}, {-1, 0}}
var visited [][]bool
var flag bool
var res int

func main() {
	var x, y int
	fmt.Scanf("%d %d", &x, &y)

	// x 行y 列初始化临界矩阵
	var graph = make([][]int, x)

	for i := 0; i < x; i++ {
		var a, b, c, d, e int
		fmt.Scanf("%d %d %d %d %d", &a, &b, &c, &d, &e)
		graph[i] = []int{a, b, c, d, e}
	}

	visited = make([][]bool, x)
	for i, _ := range visited {
		visited[i] = make([]bool, y)
	}
	fmt.Println(graph)

	var sum int
	for i := 0; i < x; i++ {
		for j := 0; j < y; j++ {
			if !visited[i][j] && graph[i][j] == 1 {
				flag = false
				res = 1
				dfs(graph, i, j)
				if !flag {
					sum += res
				}
			}
		}
	}
	fmt.Println(sum)
}

func dfs(graph [][]int, x, y int) {
	if graph[x][y] == 0 || visited[x][y] {
		visited[x][y] = true
		return
	}
	visited[x][y] = true

	for _, dir := range dirPath {
		next_x, next_y := x+dir[0], y+dir[1]
		if next_x < 0 || next_x >= len(graph) || next_y < 0 || next_y >= len(graph[0]) {
			flag = true // 标记岛屿挨到了边缘,不算做孤岛
			continue
		}
		if !visited[next_x][next_y] && graph[next_x][next_y] == 1 {
			if !flag {
				res += 1
			} else {
				res = 0
			}
			dfs(graph, next_x, next_y)
		}
	}
}


沉没孤岛

本题和上题基本一致,上题目标记了孤岛,完全可以开辟一个二维数组存储岛屿的陆地,如果不是孤岛,清空数组,如果是,按照数组标记,将graph对应位置改为0 沉没 即可

水流问题

本质上判断每一个元素,(左 or 上) and (右 or 下) 满足单调递减,中间可以出现相邻元素相等
暴力解法思路,双循环遍历整个m*n矩阵,递增判断函数isordered   
if (ir(graph[i][0 : j+1]) || ir(graph[0: i+1][j])) && (ir(graph[i][j : leg-1]) || ir(graph[i: wid-1][j]))
满足条件放入结果集
时间复杂度,遍历m*n*(m+n)


优化的思路
分别从上下边界出发,标记到两个数组first, second,标记规则是,从首个节点触发,能够逆流而上达到的节点(相邻节点小于等于)(使用dfs 或者 bfs)
然后左右边界出发,对同样的两个数组操作,这样first,second分别保存了第一、第二边界能够到达的所有节点

通过对比两个数组,如果节点能够同时满足第一第二边界到达,那么就收入结果集
时间复杂度m*(m*n) + n*(m*n) 这种分析是错误的

真正的时间复杂度为 由于使用了visited数组,保证了每个节点都只遍历了一次,所以应该是m*n + m*n

最大人工岛

暴力思路,分别遍历整个m*n 矩阵,尝试将每一个0 改成1 然后计算最大面积,总复杂度是m*n 次修改 * 每次修改dfs搜索拿到最大的面积 = m*m*n*n

优化思路
1,向dfs一次,为每一个岛屿打上标记(eg, 将graph数组对应陆地修改为岛屿编号)并计算面积, 这样可以得到一个map[k][v] k,v分别是岛屿编号以及岛屿面积
此时的graph也将对应的岛屿编号放入了对应的陆地中

2,暴力m*n 尝试修改每一个0 --> 1(水修改为陆地),检查修改后的四周,如果出现了岛屿编号,代表接壤了,那么计算一个新的面积为 1 + 所有接壤的岛屿面积和,对比更新最大值

总时间复杂度m*n + m*n*4(遍历每一个水改为陆地,然后向四周探查接壤) = m*n


标签:图论,int,graph,随想录,dfs,next,var,visited,day52
From: https://www.cnblogs.com/zhougongjin55/p/18399872

相关文章

  • 【代码随想录训练营第42期 Day51打卡 - 岛屿问题 - 卡码网 99. 岛屿数量 100. 岛屿的
    目录一、做题心得二、题目与题解题目一:99.岛屿数量题目链接题解1:DFS 题解2:BFS 题目二:100.岛屿的最大面积题目链接题解:DFS 三、小结一、做题心得今天打卡的是经典的岛屿问题:分别从两个方向进行探讨--深搜(DFS)与广搜(BFS)。作为这两大基本搜索最经典的例题,今天......
  • 第十一章 图论 Part2
    目录任务200.岛屿数量思路695.岛屿的最大面积思路任务200.岛屿数量给你一个由'1'(陆地)和'0'(水)组成的的二维网格,请你计算网格中岛屿的数量。岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。此外,你可以假设该网格的四条边均被水包围。思......
  • 代码随想录day52 || 图论搜索 岛屿数量,岛屿的最大面积
    图遍历dfs深度优先搜索bfs广度优先搜索200岛屿数量(dfs)vardirPath=[][]int{{0,-1},{1,0},{0,1},{-1,0}}//上,右,下,左varvisited[][]boolfuncnumIslands(grid[][]byte)int{ //dfs深度优先遍历,对于每一个节点,按照上下左右四个固定顺序遍历,然后到下......
  • 搜索与图论
    这部分内容要用到树的数据结构,我们有以下几种方式来存储节点邻接表邻接表就是用类似链表的结构来存储数据,先创建一个数组h,每一个位置都有一个表头。然后e数组和ne数组分别表示节点的值是多少,节点的下一个节点的编号是多少,这种方式一般用在稠密图中,也就是节点数跟边数相差很大。......
  • 图论连通性相关
    并查集普通并查集:路径压缩写法:structUnion_Find_Set{ intf[N]; inlinevoidinit(){ for(inti=1;i<=n;++i) f[i]=i; } inlineintfind(intx){ if(x!=f[x])f[x]=find(f[x]); returnf[x]; } inlinevoidmerge(inta,intb){ intx......
  • 代码随想录算法训练营|Day07 LeetCode 344.反转字符串 ,541.反转字符串||,卡玛网54.替换
    344.反转字符串344.反转字符串-力扣(LeetCode)classSolution{public:voidreverseString(vector<char>&s){intlens=s.size();intright,left;if(lens%2!=0)//奇数个{right=lens/2+1;left=l......
  • 代码随想录训练营 Day50打卡 图论part01 理论基础 98. 所有可达路径
    代码随想录训练营Day50打卡图论part01一、理论基础DFS(深度优先搜索)和BFS(广度优先搜索)在图搜索中的核心区别主要体现在搜索策略上:1、搜索方向:DFS:深度优先,一条路走到黑。DFS从起点开始,选择一个方向深入到底,遇到死胡同再回溯,换一个方向继续探索。这种方式适合解决路径......
  • [Python图论]在用图nx.shortest_path求解最短路径时,节点之间有多条边edge,会如何处理?
    问:在使用图求最短路径时,如果节点之间有多条路径,shortest_route=nx.shortest_path(G,source=start_node,target=end_node,weight='length')会如何处理,会自动选择最短那条吗?#输出图G各节点之间有多少条边edge,并给出其长度Edgesbetween103928and25508583:共2条Edge......
  • 给自己复盘的随想录笔记-字符串练习题
    反转字符串344.反转字符串-力扣(LeetCode)双指针+元素交换 classSolution{publicvoidreverseString(char[]s){chartemp;intl=0,r=s.length-1;while(l<r){temp=s[l];s[l]=s[r];s[r]=temp;l++;......
  • 第十一章 图论 Part1
    任务797.所有可能的路径给你一个有n个节点的有向无环图(DAG),请你找出所有从节点0到节点n-1的路径并输出(不要求按特定顺序)graph[i]是一个从节点i可以访问的所有节点的列表(即从节点i到节点graph[i][j]存在一条有向边)。思路题目所给的图的表示是邻接表,题意就是找到......