Shortest substring containing three short strings
来源:互联网 发布:2017怎么申请开淘宝店 编辑:程序博客网 时间:2024/06/03 12:28
@(leetcode)[字符串, Google]
Problem
Given a long string s and short strings t1, t2, t3
(which can have different length) find the shortest substring of s which contains t1
, t2
and t3
.
Example: s = "abcdefghijklmnopqrst", t1 = "abc", t2 = "cde", t3 = "klmn"
, return "abcdefghijklmn"
;
Solution
我们可以得到一个时间负责O(N),空间复杂度为O(1)的算法,因为题目中告知t1, t2, t3是short strings.具体的算法流程如下:1.初始化,len为t的长度,len1-3分别为s1-3的长度,min_len=min(len1,len2,len3), max_len=max(len1, len2, len3),以及扫描的起始位置idx,s1-3找到匹配时候的索引idx1-3 2.从idx开始,查看是否找到s1的匹配,如果找到更新idx1的位置,并且判断idx1,idx2,idx3是否都大于0,如果是,则可以根据这三个位置以及他们各自的长度求出当前包含它们的最小子字符串。并更新结果。3.同理,依次检查s2, s3是否找到匹配,如果找到就进行与步骤2一样的处理。4.做一点小的优化,如果在某次循环中得出的子字符串长度已经等于max_len,那么就没有比较继续搜索,此时的子字符串就是结果。
Code
#include <iostream>#include <string>#include <utility>#include <cstring>#include <algorithm>#include <cassert>using namespace std;typedef pair<int, int> sub_string;int cal_end_idx(sub_string const &str) { return str.first + str.second;}//计算此时包含三个字符串的最小子字符串void cal_shortest_sub_str(int idx1, int idx2, int idx3, size_t len1, size_t len2, size_t len3, sub_string& res) { if(idx1 < 0 || idx2 < 0 || idx3 < 0) { return; } size_t start_idx = min(min(idx1, idx2), idx3); size_t end_idx = max(max(idx1 + len1, idx2 + len2), idx3 + len3); int tmp_sub_len = (end_idx - start_idx); if(tmp_sub_len < res.second) { res.first = start_idx; res.second = tmp_sub_len; }}string find_shortest_sub_string(const string &s, const string &s1, const string &s2, const string &s3) { if(s.empty() || s1.empty() || s2.empty() || s3.empty()) { return ""; } size_t len = s.size(), len1 = s1.size(), len2 = s2.size(), len3 = s3.size(); size_t max_len = max(max(len1, len2), len3); size_t min_len = min(min(len1, len2), len3); const char* s_str = s.c_str(), *s1_str = s1.c_str(), *s2_str = s2.c_str(), *s3_str = s3.c_str(); int idx1 = -1, idx2 = -1, idx3 = -1; sub_string result = make_pair(0, len); for(int idx = 0; (idx + min_len) < len; ++idx) { if(0 == strncmp(s_str + idx, s1_str, len1)) { idx1 = idx; cal_shortest_sub_str(idx1, idx2, idx3, len1, len2, len3, result); } if(0 == strncmp(s_str + idx, s2_str, len2)) { idx2 = idx; cal_shortest_sub_str(idx1, idx2, idx3, len1, len2, len3, result); } if(0 == strncmp(s_str + idx, s3_str, len3)) { idx3 = idx; cal_shortest_sub_str(idx1, idx2, idx3, len1, len2, len3, result); } //如果此时子字符串的长度已经是max_len,已经找到结果,直接跳出循环 if(result.second == max_len) { break; } } if(idx1 < 0 || idx2 < 0 || idx3 < 0) { return ""; } return s.substr(result.first, result.second);}void Test(){ { const std::string input("abc0123456789aksdfjasd"); const std::string s1("0123"); const std::string s2("3456"); const std::string s3(""); std::string result = find_shortest_sub_string(input, s1, s2, s3); cout << "cal : " << result << " answer : " << "empty" << endl; assert(result.empty() == true); } { const std::string input("abc0123456789aksdfjasd"); const std::string s1("0123456"); const std::string s2("3456"); const std::string s3("1234"); std::string result = find_shortest_sub_string(input, s1, s2, s3); cout << "cal : " << result << " answer : " << "0123456" << endl; assert(result == std::string("0123456")); } { const std::string input("abc0123456789aksdfjasd"); const std::string s1("0123"); const std::string s2("3456"); const std::string s3("6789"); std::string result = find_shortest_sub_string(input, s1, s2, s3); cout << "cal : " << result << " answer : " << "0123456789" << endl; assert(result == std::string("0123456789")); } { const std::string input("sdfa01234ad23456dfad6789abc0123456789aksdfjasd"); const std::string s1("0123"); const std::string s2("3456"); const std::string s3("6789"); std::string result = find_shortest_sub_string(input, s1, s2, s3); cout << "cal : " << result << " answer : " << "0123456789" << endl; assert(result == std::string("0123456789")); } { const std::string input( "sdfa01234ad23456dfad6789abc0123456789aksdfjasd0123skd3456kjsd6789jhs"); const std::string s1("0123"); const std::string s2("3456"); const std::string s3("6789"); std::string result = find_shortest_sub_string(input, s1, s2, s3); cout << "cal : " << result << " answer : " << "0123456789" << endl; assert(result == std::string("0123456789")); }}int main() { Test();}
0 0
- Shortest substring containing three short strings
- 包含所有指定字符的最小子串(shortest substring containing all given characters)
- [Codeforces452E]Three strings(后缀自动机)
- Merge Intervals & *Longest Palindromic Substring & Multiply Strings
- codeforces 452E Three strings 后缀数组+并查集
- Codeforces 452E Three strings 后缀数组 + 并查集
- Three ways to solve the "Longest Palindromic Substring" problem
- Containing Block
- Containing Floats
- Three
- three
- three
- three
- leetcode 214. Shortest Palindrome leetcode 5. Longest Palindromic Substring回文串相关
- Strings
- Strings
- strings
- Strings
- 文件的分割
- Android中日期选择器与时间选择器的实现
- C语言再学习 -- printf、scanf占位符
- angularjs 单选按钮 默认选中
- POJ2689——Prime Distance(大区间素数筛)
- Shortest substring containing three short strings
- 【机房收费】概况总结
- ZooKeeper实战应用之【统一配置管理】
- Lancome5_order
- WPF的binding
- fail-fast机制
- 监控mysql主从状态邮件报警脚本
- Activity
- For oracle databases, if the top showing the oracle database, then oracle process is using the top c