字节跳动 暑期实习 广告系统后端开发 编辑距离
- HashMap
- 数据库
- 索引、优化、事务
- 聚簇索引和非聚簇索引
- 并发编程
- 网络编程,RPC
- 算法题:
- 编辑距离
算法题问了一道计算编辑距离(Levenshtein Distance)的问题。编辑距离的问题恰好我在之前度《图解算法》的时候有所涉及,用DP解决即可。但本题目稍微复杂度写,需要在很多字符串中,寻找距离最近的字符串。可以理解为"Fuzzy matching"。
题面大概为:
莱文斯坦距离,又称 Levenshtein 距离,是编辑距离的一种。指两个字串之间,由一个转成另一个所需的最少编辑操作次数。 允许的编辑操作包括: 插入一个字符 删除一个字符 将一个字符替换成另一个字符 需要你编写一个程序,实现以下功能: 给定一个字符串集合 S 以及一个模板串 P,从 S 中找出与 P 莱文斯坦距离最小的字符串 T,输出 T 以及其对应的编辑距离 D。如果 S 中出现多个满足条件的字符串,则取按字典序排列的第一个。
并没有想到很好的解法,暴力解法的话, 比较所有字符串和P的距离 时间复杂度为: O(P.size() * sum(S_i.size()).
后在网上搜索解法,并不难找到。利用Trie以避免不同字符串的DP重复的计算,时间复杂度为: O(P.size() * Trie的节点数). 虽然最坏时间复杂度没有变好,但是实实在在的优化。应该这就是面试官想要的解法了。
#include #include #include #include #include #include using namespace std; struct Node { array, 26> children; vector distance; Node() = delete; Node(int n) { distance.resize(n); } }; pair solve(const string& target, const vector& s) { const int k = target.size() + 1; auto root = make_shared(k); for (int i = 0; i distance.size(); ++i) { root->distance[i] = i; } int ans_distance = 0x3f3f3f3f, ans_index = -1; for (int j = 0; j < s.size(); ++j) { const string& str = s[j]; auto current = root; // cout << endl << "debug: " << str << endl; int distance_from_empty = 0; for (char c : str) { if (current->children[c - 'a'] == nullptr) { current->children[c - 'a'] = make_shared(k); auto next_current = current->children[c - 'a']; next_current->distance[0] = distance_from_empty; for (int i = 1; i < k; ++i) { if (c == target[i - 1]) { next_current->distance[i] = current->distance[i - 1]; } else { next_current->distance[i] = min({ current->distance[i - 1], current->distance[i], next_current->distance[i - 1] }) + 1; } // cout distance[i] << " "; } // cout << endl; } current = current->children[c - 'a']; ++distance_from_empty; } if (current->distance[k - 1] < ans_distance) { ans_distance = current->distance[k - 1]; ans_index = j; } else if (current->distance[k - 1] == ans_distance) { if (s[ans_index] > s[j]) ans_index = j; } } return {ans_distance, s[ans_index]}; } int main() { string P; cin >> P; int N; cin >> N; vector S(N); for (int i = 0; i < N; ++i) { cin >> S[i]; } auto ans = solve(P, S); cout << ans.first << endl; cout << ans.second << endl; return 0; }#字节跳动##实习##笔试题目#