【unordered_map】在数组中找出包括某集合所有元素的最短子数组
2015-01-10 13:11
405 查看
题目:EPI
搜狗实习生面试中出现过一道题,“给出一个字符串,找出一个最短子串,该子串包括字符串出现过的所有字符”。
代码如下(还能进一步优化):
进阶一:流操作(即只能往后读取数据,不能回头读取已经读过的数据)
进阶二:最短的连续子序列需要按照原子集Q的先后顺序
搜狗实习生面试中出现过一道题,“给出一个字符串,找出一个最短子串,该子串包括字符串出现过的所有字符”。
代码如下(还能进一步优化):
string find_substring_contain_all(const string &str) { if (str.empty()) return ""; unordered_map<char, int> hmap; //第一次扫描str,记录有几种字符 for (int i = 0; i < str.size(); i++) hmap[str[i]]++; int size = hmap.size(); hmap.clear(); int left = 0, right = 0; //重新建立hmap,left==0时,正好包含所有种字符, while (hmap.size() != size) { hmap[str[right]]++; right++; } right--;//后退一位,这时[left,right]之间的字符串包含所有字符 int markleft = 0, markright = right, length = markright + 1; hmap[str[left]]--; if (hmap[str[left]] == 0) { hmap.erase(str[left]); } left++; while (true) { //包含所有字符时,左指针右移 if (hmap.size() == size) { //出现更短的子字符串,更新记录 if (right - left + 1 < length) { markleft = left; markright = right; length = markright - markleft + 1; } hmap[str[left]]--; //注意删除hmap记录为零的项 if (hmap[str[left]] == 0) { hmap.erase(str[left]); } left++; } else { right++; if (right >= str.size()) { right--; break; } hmap[str[right]]++; } } string res(str.begin() + markleft, str.begin() + markright+1); return res; }
进阶一:流操作(即只能往后读取数据,不能回头读取已经读过的数据)
//假设s是一种流,只能往后读取数据,不能回头读取已经读过的数据 pair<int, int> find_smallest_subarray(const vector<string> &s, const unordered_set<string> &Q) { pair<int, int> res(-1, -1); if (Q.empty()) return res; list<int> loc;//字符串最后出现的位置 unordered_map<string, list<int>::iterator> hmap; int index = 0; for (auto i = Q.begin(); i != Q.end(); i++) hmap[*i] = loc.end(); while (index < s.size()) { if (Q.find(s[index]) != Q.end()) { auto i = hmap[s[index]]; if (i != loc.end()) { loc.erase(i); } loc.push_back(index); hmap[s[index]] = --loc.end(); if (loc.size() == Q.size() && ((res.first == -1 && res.second == -1) || (index - loc.front() < res.second - res.first))) { res = make_pair(loc.front(), index); } } index++; } return res; }
进阶二:最短的连续子序列需要按照原子集Q的先后顺序
pair<int, int> find_smallest_sequentially_subset(const vector<string> &A, const vector<string> &Q) { pair<int, int> res(-1, A.size()); if (A.empty() || Q.empty()) return res; unordered_map<string, int> K; vector<int> L(Q.size(), -1), D(Q.size(), INT_MAX); //初始化K for (int i = 0; i < Q.size(); i++) K[Q[i]] = i; for (int i = 0; i < A.size(); i++) { auto iter = K.find(A[i]); if (iter != K.end()) { int index = iter->second; //更新L L[index] = i; //更新D if (index == 0) D[0] = 1; else if (D[index - 1] != INT_MAX) D[index] = i - L[index - 1] + D[index - 1]; //更新res if (index == Q.size() - 1 && D[index] < res.second - res.first + 1) { //注意,res.first = L[0]是错的!因为此时以L[0]开始的部分可能还没有形成整个Q。 res.first = i - D[index] + 1; res.second = i; } } } return res; }
相关文章推荐
- 面试题——找出数组中不相同的所有元素(是数组,不是集合)
- 找出一个整形数组的所有元素除了一个、两个、三个元素外,其余全是成对出现的,找出这些元素
- 找出MXN数组中所有不相邻元素,并求出它们的和(相邻的数:前一个数是偶数,后一个数是素数)
- 将一个字典内的内value转换为集合:返回一个数组,此数组中包含输入字典的键值对中的数组的所有元素(为NSArray添加category)
- leetcode-java.T015_3Sum---给定一个n个元素的数组,是否存在a,b,c三个元素,使用得a+b+c=0,找出所有符合这个条件的三元组
- 试题:找出数组中元素和为指定值的所有组合
- lastIndexOf() 找出指定元素出现的所有位置(返回的是下标数组)---lastIndexOf() 这个方法是倒叙查找,正序的是indexOf()
- 找出数组中所有降序尾部子数组的头元素
- [leetcode 46] Permutations------数组中元素的所有排列组合集合
- java找出2个集合或数组相同和不同的元素(以及去除List中的重复元素)
- 在给定的数组中找出两个元素和为给定值的所有元素对
- 百度面试题之 循环链表求出最短的包括所有元素的字串长度
- 使用jQuery匹配文档中所有的li元素,返回一个jQuery对象,然后通过数组下标的方式读取jQuery集合中第1个DOM元素,此时返回的是DOM对象,然后调用DOM属性innerHTML,读取该元素 包含的文本信息
- 有一个整数数组,请编写一个函数,找出索引m和n,只要将m和n之间的元素排好序,整个数组就是有序的。注意:n-m应该越小越好,也就是说,找出符合条件的最短序列。 给定一个int数组A和数组的大小n,请
- 给定数组Arr[n],O(n)时间内找出每个元素左侧所有元素中位置最靠近该元素且大于该元素的元素
- 给定数组Arr[n],O(n)时间内找出每个元素左侧所有元素中位置最靠近该元素且大于该元素的元素
- 【面试题】-数组A中任意两个相邻元素大小相差1,找出某个数在数组A中的位置。(所有位置 )
- 9.11排序与查找(三)——给定一个排序后的数组,包括n个整数,但这个数组已被旋转过多次,找出数组中的某个元素
- 找出一个字符数组(元素不重复)所有可能字符的组合
- java中获取map集合数组的元素的方法