前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >程序员面试金典 - 面试题 17.17. 多次搜索(Trie树)

程序员面试金典 - 面试题 17.17. 多次搜索(Trie树)

作者头像
Michael阿明
发布2020-07-13 15:39:38
3610
发布2020-07-13 15:39:38
举报

1. 题目

给定一个较长字符串big和一个包含较短字符串的数组smalls,设计一个方法,根据smalls中的每一个较短字符串,对big进行搜索。 输出smalls中的字符串在big里出现的所有位置positions,其中 positions[i] 为 smalls[i] 出现的所有位置。

代码语言:javascript
复制
示例:
输入:
big = "mississippi"
smalls = ["is","ppi","hi","sis","i","ssippi"]
输出: [[1,4],[8],[],[3],[1,4,7,10],[5]]

提示:
0 <= len(big) <= 1000
0 <= len(smalls[i]) <= 1000
smalls的总字符数不会超过 100000。
你可以认为smalls中没有重复字符串。
所有出现的字符均为英文小写字母。

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/multi-search-lcci 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题

2.1 暴力超时

超时例子

代码语言:javascript
复制
class Solution {
public:
    vector<vector<int>> multiSearch(string big, vector<string>& smalls) {
    	unordered_map<char,vector<int>> m;
    	int i, j, n = smalls.size();
    	bool found;
    	vector<vector<int>> ans(n);
    	for(i = 0; i < big.size(); ++i)
    		m[big[i]].push_back(i);//每个字符开始的位置
    	for(i = 0; i < n; ++i)
    	{
    		if(smalls[i].empty())
    			continue;
    		for(auto idx : m[smalls[i][0]])//每个small单词开始的字符在big里的位置
    		{
    			found = true;
    			if(big.size()-idx < smalls[i].size())
    				break;
    			for(j = 0; j < smalls[i].size(); ++j)
    			{	//对big中每个开始的位置开始向后查找small
    				if(big[idx+j] != smalls[i][j])
    				{
    					found = false;
    					break;
    				}
    			}
    			if(found)
    				ans[i].push_back(idx);
    		}
    	}
    	return ans;
    }
};

2.2 Trie树

  • 将 small 全部插入 trie 树
  • 遍历 big 的每个位置,并从 big 该位置开始在 trie 中查找
代码语言:javascript
复制
class trie
{
public:
	bool isEnd = false;
	trie* next[26] = {NULL};
	void insert(string& s)
	{
		trie *cur = this;
		for(int i = 0; i < s.size(); ++i)
		{
			if(!cur->next[s[i]-'a'])
				cur->next[s[i]-'a'] = new trie();
			cur = cur->next[s[i]-'a'];
		}
		cur->isEnd = true;
	}
};
class Solution {
public:
    vector<vector<int>> multiSearch(string big, vector<string>& smalls) {
    	trie* t = new trie();
    	unordered_map<string,int> m;
    	int i, j, n = smalls.size();
    	bool found;
    	vector<vector<int>> ans(n);
    	for(i = 0; i < n; ++i)
    		m[smalls[i]] = i;
    	for(i = 0; i < n; ++i)
    		t->insert(smalls[i]);
    	string s;
    	trie* cur;
    	for(i = 0; i < big.size(); ++i)
    	{
    		s = "";
    		cur = t;
    		for(j = i; j < big.size(); ++j)
    		{
    			if(!cur->next[big[j]-'a'])
    				break;
    			s += big[j];
    			cur = cur->next[big[j]-'a'];
    			if(cur->isEnd)
    				ans[m[s]].push_back(i);
    		}
    	}
    	return ans;
    }
};

336 ms 108.7 MB

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/04/11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 题目
  • 2. 解题
    • 2.1 暴力超时
      • 2.2 Trie树
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档