单词梯形
给定两个单词(开始和结束)和一个字典,
查找从开始到结束的所有最短转换序列,
以便:
每次只能更改一个字母,每个中间单词必须存在于字典中
例如,
给定:start=“hit”
end=“cog”
dict=[“hot”,“dot”,“dog”,“lot”,“log”]
返回
[
["hit","hot","dot","dog","cog"],
["hit","hot","lot","log","cog"]
]
注意:
所有单词长度相同。
所有单词只包含小写字母字符。
我个人认为,这个算法的时间复杂度取决于输入(start,end,dict),不能写出像时间复杂度=O(?)。
这个解决方案的思想:BFS(Map)+DFS.[C++]
#include <vector>
#include <unordered_map>
#include <deque>
#include <string>
using namespace std;
struct Node {
string val;
int level;
vector<Node *> prevs;
Node (string val, int level): val(val), level(level) {};
};
class Solution {
public:
vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
vector<vector<string>> list;
// Input validation.
if (start.compare(end) == 0) {
vector<string> subList = {start, end};
list.push_back(subList);
return list;
}
deque<string> queue;
unordered_map<string, Node *> map;
queue.push_back(start);
Node *start_node = new Node(start, 0);
map.emplace(start, start_node);
while (!queue.empty()) {
// Dequeue.
string curr_string = queue.front();
queue.pop_front();
Node *curr_node = map.find(curr_string)->second;
int curr_level = curr_node->level;
int len = curr_string.length();
if (curr_string.compare(end) == 0) {
// Find the end.
vector<string> subList;
subList.push_back(curr_node->val);
getAllPathes(curr_node, list, subList);
return list;
}
// Iterate all children.
for (int i = 0; i < len; i ++) {
char curr_original_char = curr_string[i];
// Have a try.
for (char c = 'a'; c <= 'z'; c ++) {
if (c == curr_original_char) continue;
curr_string[i] = c;
if (dict.find(curr_string) != dict.end()) {
if (map.find(curr_string) == map.end()) {
// The new string has not been visited.
Node *child = new Node(curr_string, curr_level + 1);
// Add the parents of the current into prevs.
child->prevs.push_back(curr_node);
// Enqueue.
queue.push_back(curr_string);
map.emplace(curr_string, child);
} else {
// The new string has been visited.
Node *child = map.find(curr_string)->second;
if (child->level == curr_level + 1) {
child->prevs.push_back(curr_node);
}
}
}
}
// Roll back.
curr_string[i] = curr_original_char;
}
}
return list;
}
void getAllPathes(Node *end, vector<vector<string>> &list, vector<string> &subList) {
// Base case.
if (end == NULL) {
// Has been get to the top level, no topper one.
vector<string> one_rest(subList);
list.push_back(one_rest);
return;
}
vector<Node *> prevs = end->prevs;
if (prevs.size() > 0) {
for (vector<Node *>::iterator it = prevs.begin();
it != prevs.end(); it ++) {
// Have a try.
subList.insert(subList.begin(), (*it)->val);
// Do recursion.
getAllPathes((*it), list, subList);
// Roll back.
subList.erase(subList.begin());
}
} else {
// Do recursion.
getAllPathes(NULL, list, subList);
}
}
};
让我们将其复杂性分为三个部分:
设n
是给定单词的长度,n
是字典中的单词数。我们还假设字典是排序的。
然后,您可以在O(n8·26·log(n))=O(n log n)
步骤中找到下一个单词。
n
单词中可以更改的字符。26
每个字符可能发生的更改。日志(N)
要查找,如果字典中存在此单词。一个最短的转化序列能有多长?
示例:让开始词是“aa”,结束词是“zz”,字典
[“ab”,“bb”,“bc”,“cc”,..]。
这个示例需要26次转换。我认为您可以构建需要26n-1转换的最坏情况输入。
但这取决于字典里的单词。所以最坏的情况是n
,即。字典里的词都用上了。
存在多少种不同的序列?
每次你在顺序中寻找下一个单词时,都有可能找到26个不同的下一个步骤。但只适用于最短序列的前半部分,因为如果切换开始和结束词,这也适用。因此,最多可以有O(26N/2)
不同的序列,只要最短序列的最坏情况是O(N)
。
O(n log n)
查找序列中的下一个转换。O(N)
每个序列的转换O(26N/2)
不同序列。总共得到O(26N/2N log N)
。
我希望这能有所帮助
注:∈/ 意思是不在,我不能在代码中输入。 这个问题可能与一些帖子重复。 理解Dijkstra算法的时间复杂度计算 Dijkstra算法的复杂性 Dijkstras算法的复杂性 我读过它们,甚至读过Quora上的一些帖子,但仍然无法理解。我在伪代码中添加了一些注释,并试图解决它。我真搞不懂为什么它是O(E log V)
我有一个算法可以检查是否可以解决游戏行。游戏行是一个正整数数组,其中最后一个元素为 0。游戏标记从索引 0 开始,沿着数组移动它所在的整数指示的步数。 例如,[1,1,0]返回true,而[1,2,0]返回false。标记也可以向左或向右移动以解决游戏。也就是说,[3,3,2,2,0]是可解的。 我尝试了一些游戏行示例,并计算了最坏情况下的时间复杂度: 其他情况下给我的数字,我找不到与输入大小的关
查找p的伪码算法为: 假设我有一个int值的数组H[1到m],其中“p”是峰值元素,如果: 基本上,如果H【p】大于或等于其相邻元素,则H【p】为峰值。 假设数组H在开始和结束时都大于1个元素,数组为H[0到m 1],其中H[0]=H[m 1]=无穷大。因此,H[0]和H[m 1]是哨兵。然后是元素p,其中1≤ p≤ n、 是一个峰值,如果H【p-1】≤ H【p】≥ H【p 1】。 我认为渐近时间
问题内容: 我写了以下课程: 然后,在我的方法中,我创建了一个,向其中添加了一些具有“ X”和“ angle”字段的对象。 然后,我使用: 这种排序方法的复杂性是什么? 问题答案: 您可能已经阅读了有关Collections排序的文档,但是这里适合您: 排序算法是一种修改的mergesort(如果低子列表中的最高元素小于高子列表中的最低元素,则忽略合并)。该算法提供了有保证的n log(n)性能。
问题内容: 我当时在看这个pycon演讲,时间是34:30,发言人说,可以在中完成获取元素列表中最大的元素的操作。 那怎么可能?我的理解是,创建堆将是,但是其本身的复杂性是还是(以及(实际的算法是什么))? 问题答案: 扬声器在这种情况下是错误的。实际费用为。仅在可迭代的第一个元素上调用堆化。就是那个,但如果小于,则微不足道。然后,将所有剩余的元素一次通过添加到此“小堆”中。每次调用需要花费时间。
算法的时间与空间复杂度 看到群里们小伙伴在讨论算法复杂度问题,之前在极客时间看了王争的《数据结构与算法之美》,看的我也晕呼呼的,跟上学时在学校老师的讲的有点不一样了,网上搜了下各种各样的,结合参考作一篇简单易懂的总结。 什么是算法 算法是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作。 如何评价一个算法的好坏 一般我们会从以下维度来评估算法的优劣 正确性