(bfs)leetcode Dificultad 127. Solitario Word

tema

La secuencia de transformaciones de las palabras beginWord y endWord en el diccionario wordList es una secuencia beginWord -> s1 -> s2 -> … -> sk formada con la siguiente especificación:

Cada par de palabras adyacentes se diferencia por una sola letra.
Para 1 <= i <= k, cada si está en listapalabras. Tenga en cuenta que beginWord no necesita estar en wordList.
sk == endWord
le da dos palabras beginWord y endWord y una lista de palabras del diccionario que devuelve el número de palabras en la secuencia de transición más corta de beginWord a endWord. Devuelve 0 si no existe tal secuencia de transición.

Ejemplo 1:

Entrada: beginWord = "hit", endWord = "cog", wordList = ["hot", "dot", "dog", "lot", "log", "cog"]
Salida: 5
Explicación: Una secuencia de transición más corta es "hit" -> "hot" -> "dot" -> "dog" -> "cog", devolviendo su longitud 5.
Ejemplo 2:

Entrada: beginWord = "hit", endWord = "cog", wordList = ["hot", "dot", "dog", "lot", "log"]
Salida: 0
Explicación: endWord "cog" no está en el diccionario, por lo que no se puede realizar ninguna conversión.

insinuación:

1 <= beginWord.length <= 10
endWord.length == beginWord.length
1 <= wordList.length <= 5000
wordList[i].length == beginWord.length
beginWord, endWord y wordList[i] consisten en letras minúsculas en inglés
beginWord != endWord
todas las cadenas en wordList son diferentes entre sí

Fuente: LeetCode
Enlace: https://leetcode-cn.com/problems/word-ladder Los
derechos de autor pertenecen a LeetCode.com. Para reimpresiones comerciales, comuníquese con la autorización oficial y para reimpresiones no comerciales, indique la fuente.

analizar

El título es limitado, la conversión de palabras requiere que estas dos palabras difieran en una letra. Si hay varias palabras, a qué palabra debemos convertir, de modo que la cantidad de veces para alcanzar el objetivo sea la más pequeña, entonces podemos atravesar el palabras que se pueden convertir y, a continuación, recorra la palabra convertida para ver si hay una palabra objetivo. Si no, continúe recorriendo las palabras que se pueden convertir por la palabra actual hasta que se encuentre el objetivo o finalice el recorrido. En este punto, se puede determinar que esta es una pregunta bfs
. En primer lugar, determine la diferencia entre las palabras Relación, en qué palabras se puede convertir cada palabra directamente, estas palabras deben vincularse y almacenarse con esta palabra (lista de adyacencia)
y luego bfs en la lista de adyacencia, cuando se encuentra el objetivo, es el número de respuestas

sección de código

1. Cree e inicialice la lista de adyacencia

Queremos vincular una cadena a una cadena que se pueda convertir directamente, por lo que aquí se usan el mapa y el par, el par se usa para vincular la cadena actual y la matriz de cadenas.

		map<string,vector<string> > graph;	//邻接表 
		wordList.push_back(beginWord);
		
		for(int i=0;i<wordList.size();i++)	//初始化 
		{
    
    
			graph[wordList[i]]=vector<string>();
		}
		
		for(int i=0;i<wordList.size();i++)		//构建邻接表 
		{
    
    
			for(int j=i+1;j<wordList.size();j++)
			{
    
    
				if(check(wordList[i],wordList[j]))
				{
    
    
					graph[wordList[i]].push_back(wordList[j]);
					graph[wordList[j]].push_back(wordList[i]);
				}
			}
		}
2.bfs parte

Lo que tenemos que hacer es recorrer cada capa hasta que se encuentre la respuesta o se completen todos los recorridos, bfs usa la cola, cuál debería ser la composición de cada elemento en la cola, primero la cadena actual, luego el paso actual Necesitamos para escribir el número (la respuesta lo necesita), así que aquí cada elemento de nuestra cola es un par <string,int>
y luego necesitamos una matriz para almacenar las cadenas por las que caminamos para evitar un bucle infinito, aquí usamos set para almacenar e ir La cadena aprobada
muestra el elemento que queda atrás cada vez, lo asigna a la cadena actual para que se procese, y luego empuja todas las cadenas conectadas a él, lo marca como aprobado y juzga el carácter actual cada vez aparece Si la cadena es la cadena de destino, si es así, devuélvala directamente y luego devuelva 0 al final del bucle. Aquí, la cadena de destino no se encuentra, lo que indica que la cadena de destino no está en la matriz de cadenas, o no hay una cadena que se pueda convertir directamente en el carácter de destino.

	int bfs(string beginWord, string endWord,
	vector<string>& wordList,map<string,vector<string> > &graph)
	{
    
    
		//出口
		
		//现在能做的事情
		queue<pair<string,int> > Q;		//搜索队列 顶点,步数
		Q.push(make_pair(beginWord,1));
		set<string> vis;		//记录走过单词
		vis.insert(beginWord);
		
		while(!Q.empty())
		{
    
    
			string node=Q.front().first;	//顶点 
			int step=Q.front().second;		//步数
			Q.pop();
			if(node==endWord)
				return step;
			const vector<string> neighbors=graph[node]; 
			for(int i=0;i<graph[node].size();i++)
			{
    
    
				if(vis.find(neighbors[i])==vis.end())
				{
    
    
					vis.insert(neighbors[i]);
					Q.push(make_pair(neighbors[i],step+1));
				}
			} 
		} 
		
		return 0;
	}

código completo

#include <bits/stdc++.h>
using namespace std;

class Solution {
    
    
public:
	bool check(string s1,string s2)
	{
    
    
		int cnt=0;
		for(int i=0;i<s1.size();i++)
			if(s1[i]!=s2[i])
				cnt++;
				
		return cnt==1;
	}
	
	
	int bfs(string beginWord, string endWord,
	vector<string>& wordList,map<string,vector<string> > &graph)
	{
    
    
		//出口
		
		//现在能做的事情
		queue<pair<string,int> > Q;		//搜索队列 顶点,步数
		Q.push(make_pair(beginWord,1));
		set<string> vis;		//记录走过单词
		vis.insert(beginWord);
		
		while(!Q.empty())
		{
    
    
			string node=Q.front().first;	//顶点 
			int step=Q.front().second;		//步数
			Q.pop();
			if(node==endWord)
				return step;
			const vector<string> neighbors=graph[node]; 
			for(int i=0;i<graph[node].size();i++)
			{
    
    
				if(vis.find(neighbors[i])==vis.end())
				{
    
    
					vis.insert(neighbors[i]);
					Q.push(make_pair(neighbors[i],step+1));
				}
			} 
		} 
		
		return 0;
	}
	
	
    int ladderLength(string beginWord, string endWord,
	 vector<string>& wordList) {
    
    
		map<string,vector<string> > graph;	//邻接表 
		wordList.push_back(beginWord);
		
		for(int i=0;i<wordList.size();i++)	//初始化 
		{
    
    
			graph[wordList[i]]=vector<string>();
		}
		
		for(int i=0;i<wordList.size();i++)		//构建邻接表 
		{
    
    
			for(int j=i+1;j<wordList.size();j++)
			{
    
    
				if(check(wordList[i],wordList[j]))
				{
    
    
					graph[wordList[i]].push_back(wordList[j]);
					graph[wordList[j]].push_back(wordList[i]);
				}
			}
		} 

/*		
		//输出构造好的邻接表 
		for(int i=0;i<wordList.size();i++)
		{
			cout<<wordList[i]<<": ";
			const vector<string> neighbors=graph[wordList[i]];
			for(int j=0;j<neighbors.size();j++)
			{
				cout<<neighbors[j]<<" ";
			}
			cout<<endl;
		}
*/		
		
		int ans=bfs(beginWord,endWord,wordList,graph);
		
		return ans;
    }
};

int main (void)
{
    
    
	string beginWord = "hit", endWord = "cog";
	vector<string> wordList={
    
    "hot","dot","dog","lot","log","cog"};
	Solution s;
	cout<<s.ladderLength(beginWord,endWord,wordList);
	
	return 0;
}

Resumir

Cuando encuentre un problema de búsqueda, primero debe determinar qué método es más adecuado, bfs o dfs o dfs con memorización, esta pregunta es obviamente más adecuada para usar bfs, qué cadena de destino encontrada primero al atravesar la capa debe ser El número de pasos es lo menos Al principio, usé el bfs memorizado y solo pasé la mitad de los casos de uso.

Supongo que te gusta

Origin blog.csdn.net/weixin_46035615/article/details/123936886
Recomendado
Clasificación