首页 > 其他分享 >代码随想录day 53 || 图论4

代码随想录day 53 || 图论4

时间:2024-09-07 11:47:24浏览次数:4  
标签:string int graph 随想录 53 queue var visited day

字符串接龙

image


var queue *list.List
var visitMap map[string]bool

func main() {
	var count int
	fmt.Scanf("%d", &count)
	var startStr, endStr string
	fmt.Scanf("%s %s", &startStr, &endStr)

	var strList = make([]string, count)
	for i := 0; i < count; i++ {
		var str string
		fmt.Scanf("%s", &str)
		strList[i] = str
	}
	fmt.Println(startStr, endStr, strList)

	queue = list.New()
	queue.PushBack(startStr)
	visitMap = make(map[string]bool, len(strList)) // 存放字符的使用状态
	for _, v := range strList {
		visitMap[v] = false
	}

	bfs(endStr, strList)
}

func bfs(target string, strList []string) {
	// 本题的思路是构建无向图,然后广搜得到最短路径
	// 但是具体怎么实现?先构建再广搜?并不是,是一边广搜一边半构建
	// 具体过程是,从startStr出发,对于每一个字符,尝试使用26个字母替换,如果替换后的新字串出现在strlist中,那么加入队列,路径+1,直到最终找到endStr
	
	// todo: 广搜如何记录层数,也就是路径深度,应该是每一层都标记一下入队长度,如果该层完全出队,层度+1,太长就不写了

	for queue.Len() > 0 {
		node := queue.Remove(queue.Front()).(string)
		nodeRune := []rune(node)
		for idx, _ := range nodeRune {
			for i := 0; i < 26; i++ {
				newStr := nodeRune
				newStr[idx] = rune(i + 'a')

				// 如果直接变成target,返回
				if string(newStr) == target {
					count++
					return
				}

				// 遇到字典元素, 并且没有使用过
				if v, ok := visitMap[string(newStr)]; ok && !v {
					visitMap[string(newStr)] = true
					queue.PushBack(string(newStr))
				}
			}

		}
	}

}


有向图完全可达性

package main

import (
	"container/list"
	"fmt"
)

var queue *list.List
var visited []bool

func main() {
	//var c, l int
	//fmt.Scanf("%d %d", &c, &l)
	//
	//// 构建邻接矩阵存储图
	//var graph = make([][]int, c)
	//for i, _ := range graph {
	//	graph[i] = make([]int, c)
	//}
	//for i := 0; i < l; i++ {
	//	var x, y int
	//	fmt.Scanf("%d %d", &x, &y)
	//	graph[x-1][y-1] = 1
	//}
	//for _, v := range graph {
	//	fmt.Println(v)
	//}

	c := 4
	//l := 4
	graph := [][]int{{0, 1, 1, 0}, {1, 0, 0, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}}

	// dfs
	// 本题原理就是找到首个节点到所有节点是否路径可达,所以dfs判断两个节点是否存在路径(路径可达)
	for i := 1; i < c; i++ {
		visited = make([]bool, c)
		if dfs(0, i, graph) == false { // 任意一个节点不可达,就是false
			fmt.Printf("dfs %d false\n", i)
			break
		}
	}

	// bfs
	for i := 1; i < c; i++ {
		visited = make([]bool, c)
		visited[0] = true
		queue = list.New()
		queue.PushBack(0)
		if bfs(graph, i) == false {
			fmt.Printf("bfs %d false\n", i)
			break
		}
	}
	fmt.Println("true")
}

func dfs(start, stop int, graph [][]int) bool {
	// 递归终止条件,空,或者找到了target
	visited[start] = true // 标记节点已经遍历过
	if start == stop {
		return true
	}

	for idx, v := range graph[start] {
		if v == 1 && !visited[idx] {
			res := dfs(idx, stop, graph)
			if res { // 某次递归出现了目标,直接返回true
				return true
			}
		}
	}

	// 回溯
	visited[start] = false
	return false
}

func bfs(graph [][]int, target int) bool {
	for queue.Len() > 0 {
		node := queue.Remove(queue.Front()).(int)
		if node == target {
			return true
		}
		for i, v := range graph[node] {
			if v == 1 && !visited[i] {
				visited[i] = true
				queue.PushBack(i)
			}
		}
	}

	return false
}


463 岛屿周长

var dirPath = [4][2]int{{0,1}, {0,-1}, {1,0}, {-1,0}}
var sum int // 周长
var visited [][]bool
func islandPerimeter(grid [][]int) int {
	// 很简单的思路,计算所有的陆地,然后区分不同的周长
	// 三面环水,周长为3,两面,周长是2... 四周几格水周长就是几,边界也算作水
	sum = 0
	visited = make([][]bool, len(grid))
	for i, _ := range visited {
		visited[i] = make([]bool, len(grid[0]))
	}

	for i:=0; i<len(grid); i++ {
		for j:=0; j<len(grid[0]); j++ {
			if grid[i][j] == 1 && !visited[i][j] {
				dfs(i, j, grid)
			}
		}
	}
	return sum
}

func dfs(x, y int, graph [][]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_y<0 || next_x >= len(graph) || next_y >= len(graph[0]) {
			sum += 1  // 当前陆地的周边是边界,视为水,周长+1
			continue
		}
		if graph[next_x][next_y] == 0 { // 当前陆地的周边是水,周长+1
			sum += 1
		}
		if graph[next_x][next_y] == 1 && !visited[next_x][next_y] {
			// 是新大陆
			dfs(next_x, next_y, graph)
		}
	}
}

标签:string,int,graph,随想录,53,queue,var,visited,day
From: https://www.cnblogs.com/zhougongjin55/p/18401501

相关文章

  • 【读书笔记-《30天自制操作系统》-16】Day17
    本篇内容开始进入一个新的主题——命令行,这是一个操作系统很基本的功能。本篇中首先实现命令行窗口的显示,做到能切换到窗口以及实现向窗口输入内容。接下来在之前键盘输入的基础上,增加对符号以及大小写字母的输入。最后再加入对其他锁定键的支持。1.创建命令行窗口与窗口......
  • 代码随想录算法训练营第五十天 | 98. 所有可达路径
    目录98.所有可达路径思路图的存储邻接矩阵         邻接表深度优先搜索1.确认递归函数,参数2.确认终止条件3.处理目前搜索节点出发的路径方法一:邻接矩阵写法方法二:邻接表写法98.所有可达路径题目链接:卡码网题目链接(ACM模式)文章讲解:代码随想录 ......
  • Day03.HelloWorld
    HelloWorld新建一个文件夹,存放代码新建一个Java文件>文件后缀名为.java(系统未显示文件后缀名>查看>显示>文件扩展名)编写代码publicclassHello{publicstaticvoidmain(String[]args){System.out.print("Hell......
  • 网络编程day02(字节序、TCP编程)
    目录【1】字节序1》大小端转换2》端口转换  3》IP地址转换主机字节序转换为网络字节序(小端序->大端序)网络字节序转换为主机字节序(大端序->小端序) 【2】TCP编程1》流程2》函数接口1> socket2>bind3>listen4>accept 5>recv 6>connect7>send 3》代......
  • CF1534(模拟赛记录)
    比赛页面ABCD都打的可以,然而E的+10直接葬送了大概率过的F1……先猜了个\(n-k+1\)的结论,但是没有写搜索查正确性(事实上确实不正确),于是两次罚时,第一次是交互格式错了。然后又猜了个\(\min(n-k+1,(n-1)/(k-1))\)的结论,过了几个小的搜索数据(\(n\le6\))的,大一点的没跑,于......
  • Day Inf
    Day12新知识:Dsuontree。在计算树上路径问题中,亦可使用点分治。思想就是每次只保留重儿子的信息且回溯给父亲,其它点的信息暴力计算然后最后删除。如果是路径问题,记得加入一个子树过后要统一计算一次答案。复杂度是线对,证明考虑一个点被暴力加的次数为对数次即可(假设加入删除......
  • 太原市公共自行车租赁管理系统的设计与实现 毕业设计源码25530
                                       目 录摘要1绪论1.1研究意义1.2公共自行车租赁管理系统现状1.3ssm框架介绍1.4论文结构与章节安排2 太原市公共自行车租赁管理系统系统分析2.1......
  • 20240906_144853 python 应用题 工作统计
    ......
  • 代码随想录算法训练营第十天| 232.用栈实现队列 、 225. 用队列实现栈 、20. 有效的括
    学习文章链接:代码随想录文章目录一、232.用栈实现队列二、225.用队列实现栈三、20.有效的括号四、1047.删除字符串中的所有相邻重复项一、232.用栈实现队列题目链接:232.用栈实现队列栈的操作:stack<int>s;s.empty();//如果栈为空则返回true,......
  • Day 8:77 组合
    77组合1.题目描述2.解题思路3.代码实现4.回溯模板1.题目描述77组合2.解题思路该题可以使用回溯类型的模板来解决,注意到可以进行剪枝操作。3.代码实现classSolution{vector<vector<int>>res;vector<int>path;public:vector<vector<i......