【CODE】Unique Paths & Word Search (DFS && dp && 字典树)

目录

62. Unique Paths

63. Unique Paths II

980. Unique Paths III

79. Word Search

212. Word Search II

字典树

720. Longest Word in Dictionary

1023. Camelcase Matching

648. Replace Words


62. Unique Paths

Medium

2435175Add to ListShare

A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).

The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).

How many possible unique paths are there?


Above is a 7 x 3 grid. How many possible unique paths are there?

Note: m and n will be at most 100.

Example 1:

Input: m = 3, n = 2
Output: 3
Explanation:
From the top-left corner, there are a total of 3 ways to reach the bottom-right corner:
1. Right -> Right -> Down
2. Right -> Down -> Right
3. Down -> Right -> Right

Example 2:

Input: m = 7, n = 3
Output: 28
#include"pch.h"
#include<iostream>
#include<stack>
#include<string>
#include<vector>
#include<algorithm>
#include<unordered_map>
using namespace std;
/*62. Unique Paths
DP:状态方程应该是 dp[i][j]=dp[i-1][j]+dp[i][j-1]
Runtime: 0 ms, faster than 100.00% of C++ online submissions for Unique Paths.
Memory Usage: 8 MB, less than 100.00% of C++ online submissions for Unique Paths.*/
int uniquePaths1(int m, int n) {
	vector<vector<int> > dp(m + 1, vector<int>(n + 1));
	for (int i = 1; i <= m; i++) dp[i][1] = 1;
	for (int i = 1; i <= n; i++) dp[1][i] = 1;
	for (int j = 2; j <= n; j++) {
		for (int i = 2; i <=m; i++) {
			for(int k=i;k>=1;k--)
				dp[i][j] += dp[k][j - 1];
		}
	}
	return dp[m][n];
}
int main() {
	cout << uniquePaths1(7,3);
	return 0;
}

63. Unique Paths II

Medium

1298212Add to ListShare

A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).

The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).

Now consider if some obstacles are added to the grids. How many unique paths would there be?

An obstacle and empty space is marked as 1 and 0 respectively in the grid.

Note: m and n will be at most 100.

Example 1:

Input:
[
  [0,0,0],
  [0,1,0],
  [0,0,0]
]
Output: 2
Explanation:
There is one obstacle in the middle of the 3x3 grid above.
There are two ways to reach the bottom-right corner:
1. Right -> Right -> Down -> Down
2. Down -> Down -> Right -> Right
#include"pch.h"
#include<iostream>
#include<stack>
#include<string>
#include<vector>
#include<algorithm>
#include<unordered_map>
using namespace std;
/*63. Unique Paths II
1.DFS:超时*/
void DFS(vector<vector<int> > & obstacleGrid, int &res,int i,int j) {
	int n = obstacleGrid.size();
	int m = obstacleGrid[0].size();
	if (i == n - 1 && j == m - 1 && obstacleGrid[i][j]!=1) {
		res++;
		return;
	}
	if (i < n - 1 && obstacleGrid[i][j] != 1 && obstacleGrid[i + 1][j] != 1) DFS(obstacleGrid, res, i + 1, j);
	if (j < m - 1 && obstacleGrid[i][j] != 1 && obstacleGrid[i][j + 1] != 1) DFS(obstacleGrid, res, i, j + 1);
	return;
}
int uniquePathsWithObstacles1(vector<vector<int>>& obstacleGrid) {
	int res=0;
	DFS(obstacleGrid, res, 0, 0);
	return res;
}
/*2.DP:状态方程 dp[i][j]=dp[i-1][j]+dp[i][j-1]
Runtime: 0 ms, faster than 100.00% of C++ online submissions for Unique Paths II.
Memory Usage: 8.2 MB, less than 100.00% of C++ online submissions for Unique Paths II.*/
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
	int n = obstacleGrid.size();
	int m = obstacleGrid[0].size();
	vector<vector<int> > dp(n , vector<int>(m));
	if (obstacleGrid[0][0] == 1 || obstacleGrid[n-1][m-1] == 1) return 0;
	for (int i = 0; i < n; i++) {
		if (obstacleGrid[i][0] == 1) {
			for (int j = i; j < n; j++) dp[j][0] = 0;
			break;
		}
		else dp[i][0] = 1;
	}
	for (int j = 0; j < m; j++) {
		if (obstacleGrid[0][j] == 1) {
			for (int i = j; i < m; i++) dp[0][i] = 0;
			break;
		}
		else dp[0][j] = 1;
	}
	for (int j = 1; j < m; j++) {
		for (int i = 1; i < n; i++) {
			if (obstacleGrid[i][j] == 1) dp[i][j] = 0;
			else {
				dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
			}
		}
	}
	return dp[n-1][m-1];
}
int main() {
	vector<vector<int> > nums = { {0,0},{1,1 },{0,0} };
	cout << uniquePathsWithObstacles(nums);
	return 0;
}
 

980. Unique Paths III

Hard

40149Add to ListShare

On a 2-dimensional grid, there are 4 types of squares:

  • 1 represents the starting square.  There is exactly one starting square.
  • 2 represents the ending square.  There is exactly one ending square.
  • 0 represents empty squares we can walk over.
  • -1 represents obstacles that we cannot walk over.

Return the number of 4-directional walks from the starting square to the ending square, that walk over every non-obstacle square exactly once.

Example 1:

Input: [[1,0,0,0],[0,0,0,0],[0,0,2,-1]]
Output: 2
Explanation: We have the following two paths: 
1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2)
2. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2)

Example 2:

Input: [[1,0,0,0],[0,0,0,0],[0,0,0,2]]
Output: 4
Explanation: We have the following four paths: 
1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2),(2,3)
2. (0,0),(0,1),(1,1),(1,0),(2,0),(2,1),(2,2),(1,2),(0,2),(0,3),(1,3),(2,3)
3. (0,0),(1,0),(2,0),(2,1),(2,2),(1,2),(1,1),(0,1),(0,2),(0,3),(1,3),(2,3)
4. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2),(2,3)

Example 3:

Input: [[0,1],[2,0]]
Output: 0
Explanation: 
There is no path that walks over every empty square exactly once.
Note that the starting and ending square can be anywhere in the grid.

Note:

  1. 1 <= grid.length * grid[0].length <= 20
#include"pch.h"
#include<iostream>
#include<stack>
#include<string>
#include<vector>
#include<algorithm>
#include<unordered_map>
using namespace std;
/*980. Unique Paths III
DFS:
Runtime: 148 ms, faster than 9.99% of C++ online submissions for Unique Paths III.
Memory Usage: 70 MB, less than 100.00% of C++ online submissions for Unique Paths III.*/
void DFS(vector<vector<int> > &grid, vector<vector<int> > vis, int num, int &res,int target,int a, int b) {
	if (a >= grid.size() || b >= grid[0].size() || a<0 || b<0) return;
	if (grid[a][b] == 2 && num == target) {
		res++;
		return;
	}
	else if (grid[a][b] == 2) return;
	else if (grid[a][b] == -1) return;
	else if( vis[a][b] == 0){
		vis[a][b] = 1;
		DFS(grid, vis, num + 1, res, target, a + 1, b);
		DFS(grid, vis, num + 1, res, target, a - 1, b);
		DFS(grid, vis, num + 1, res, target, a , b + 1);
		DFS(grid, vis, num + 1, res, target, a , b - 1);
		vis[a][b] = 0;
	}
	return;
}
int uniquePathsIII(vector<vector<int>>& grid) {
	vector<vector<int> > vis(grid.size(), vector<int>(grid[0].size()));
	int target = 0;
	int a = 0, b = 0;
	for (int i = 0; i < grid.size(); i++) {
		for (int j = 0; j < grid[0].size(); j++) {
			if (grid[i][j] == 1) { a = i; b = j; }
			else if (grid[i][j] == 0) target++;
		}
	}
	int res = 0;
	DFS(grid, vis, 0, res, target+1, a, b);
	return res;
}
int main() {
	vector<vector<int> > nums = { {0,1},{2,0} };
	cout << uniquePathsIII(nums);
	return 0;
}
 

79. Word Search

Medium

2822144Add to ListShare

Given a 2D board and a word, find if the word exists in the grid.

The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.

Example:

board =
[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]

Given word = "ABCCED", return true.
Given word = "SEE", return true.
Given word = "ABCB", return false.
#include"pch.h"
#include<iostream>
#include<vector>
using namespace std;
/*79. Word Search
DFS:
Runtime: 48 ms, faster than 58.95% of C++ online submissions for Word Search.
Memory Usage: 19.5 MB, less than 50.00% of C++ online submissions for Word Search.*/
void DFS(vector<vector<char> > &board, vector<vector<int> > &vis,int a, int b, string word, int &flag) {
	if (a >= board.size() || b >= board[0].size() || a < 0 || b < 0) {
		flag = 0;
		return;
	}
	else if (word.size() == 1 && vis[a][b]==0 && word[0] == board[a][b]) {
		flag = 1;
		return;
	}
	else if (word[0] != board[a][b]) {
		flag = 0;
		return;
	}
	else {
		if (vis[a][b] == 0) {
			vis[a][b] = 1;
			DFS(board, vis, a + 1, b, word.substr(1), flag);
			if (flag == 1) return;
			DFS(board, vis, a - 1, b, word.substr(1), flag);
			if (flag == 1) return;
			DFS(board, vis, a, b + 1, word.substr(1), flag);
			if (flag == 1) return;
			DFS(board, vis, a, b - 1, word.substr(1), flag);
			if (flag == 1) return;
			vis[a][b] = 0;
		}
	}
	return;
}
bool exist(vector<vector<char>>& board, string word) {
	vector<vector<int> > vis(board.size(), vector<int>(board[0].size()));
	int a = 0, b = 0, flag = 0;
	for (int i = 0; i < board.size(); i++) {
		for (int j = 0; j < board[0].size(); j++) {
			if (board[i][j] == word[0]) {
				a = i; b = j; 
				DFS(board, vis, a, b, word, flag);
				if (flag == 1) return true;
			}
		}
	}
	return flag;
}
int main() {
	vector<vector<char>> board = { {'A','B','C','E'}, {'S','F','C','S'}, {'A','D','E','E'} };
	string word = "ABCB";
	cout << exist(board,word);
	return 0;
}
 

212. Word Search II

Hard

181189Add to ListShare

Given a 2D board and a list of words from the dictionary, find all words in the board.

Each word must be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once in a word.

Example:Input:
board = [
['o','a','a','n'],
['e','t','a','e'],
['i','h','k','r'],
['i','f','l','v']
]
words = ["oath","pea","eat","rain"]
Output: ["eat","oath"]

#include"pch.h"
#include<iostream>
#include<vector>
#include<string>
using namespace std;
/*212. Word Search II
使用构造函数定义结构体,Trie+DFS
Runtime: 352 ms, faster than 23.11% of C++ online submissions for Word Search II.
Memory Usage: 97.9 MB, less than 8.33% of C++ online submissions for Word Search II.*/
typedef struct Trie {
	Trie *next[26];
	string str;
	Trie() :str("") {
		for (int i = 0; i < 26; i++) next[i] = NULL;
	}
}Trie;
void Insert_str(Trie *root, string str) {
	Trie *p = root;
	for (int i = 0; i < str.size(); i++) {
		if (p->next[str[i] - 'a'] == NULL) {
			Trie *tmp = new Trie();
			p->next[str[i] - 'a'] = tmp;
			p = tmp;
		}
		else p = p->next[str[i] - 'a'];
	}
	p->str = str;
	return;
}
void Search_str(Trie *root, int i, int j, vector<vector<char> >&board, vector<vector<int> > &vis,vector<string> &res) {
	if (root->str.size() != 0) {
		res.push_back(root->str);
		root->str.clear();
	}
	vector<vector<int> > dir = { {1,0},{-1,0},{0,1},{0,-1} };
	for (int m = 0; m < 4; m++) {
		int nx = i + dir[m][0], ny = j + dir[m][1];
		if (nx >= 0 && ny >= 0 && nx < board.size() && ny < board[0].size() && vis[nx][ny] == 0 && root->next[board[nx][ny] - 'a'] != NULL){
			vis[nx][ny] = 1;
			Search_str(root->next[board[nx][ny]-'a'], nx, ny, board, vis, res);
			vis[nx][ny] = 0;
		}
	}
	return;
}
vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
	Trie *root = new Trie();
	for (int i = 0; i < words.size(); i++) {
		Insert_str(root, words[i]);
	}
	vector<vector<int> > vis(board.size(), vector<int>(board[0].size()));
	vector<string> res;
	for (int i = 0; i < board.size(); i++) {
		for (int j = 0; j < board[0].size(); j++) {
			if (root->next[board[i][j] - 'a'] != NULL && vis[i][j]==0) {
				vis[i][j] = 1;
				Search_str(root->next[board[i][j] - 'a'], i, j, board, vis, res);
				vis[i][j] = 0;
			}
		}
	}
	return res;
}
int main() {
	vector<vector<char> > board = { {'a','a'} };
	vector<string> words = { "aaa" };
	vector<string> res = findWords(board, words);
	for (int i = 0; i < res.size(); i++) {
		cout << res[i] << endl;
	}
	return 0;
}

字典树

/*字典树,字符串的公共前缀,节省存储空间
(1)根节点不包含字符,
(2)从根节点到某一结点,路径上经过的字符连接起来,为该节点对应的字符串
(3)每个节点的所有子节点包含的字符都不相同
Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,
如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树。
他的核心思想是空间换时间,空间消耗大但是插入和查询有着很优秀的时间复杂度。*/
#include"pch.h"
#include<iostream>
#include<string>
using namespace std;
/*以一个例子为例:给你100000个长度不超过10的单词。
对于每一个单词,我们要判断他出没出现过。
假设我要查询的单词是abcd,那么在他前面的单词中,
以b,c,d,f之类开头的我显然不必考虑。
而只要找以a开头的中是否存在abcd就可以了。
同样的,在以a开头中的单词中,我们只要考虑以b作为第二个字母的*/
typedef struct Trie {
	int num;//表示存储的孩子节点的个数
	struct Trie* next[26];//指向各个子树的指针
}Trie;
/*创建一个新节点,初始化26个字数指针,初始化子树个数为0*/
Trie *createNew() {
	Trie *p = new Trie;
	for (int i = 0; i < 26; i++) {
		p->next[i] = NULL;
	}
	p->num = 0;
	return p;
}
/*插入字符串到树中*/
void Insert_str(string add,Trie *root) {
	Trie *t, *p = root;
	for (int i = 0; i < add.size(); i++) {
		int c = add[i] - 'a';
		if (p->next[c] == NULL) {
			t = createNew();
			p->next[c] = t;
			p->num++;
			p=p->next[c];
		}
		else p = p->next[c];
	}
}
int Search_str(string str, Trie *root) {
	Trie *p = root;
	int count = 0;
	for (int i = 0; i < str.size(); i++) {
		int c = str[i] - 'a';
		if (p->next[c] == NULL) {
			cout << "不存在该字符串" << endl;
			count = 0;
			return 0;
		}
		else {
			p = p->next[c];
			count = p->num;//子树个数
			cout << str[i] << " " << count << endl;
		}
	}
	return count;
}
int main() {
	Trie *root = createNew();
	string s = "";
	while (cin >> s && s!="quit") {
		Insert_str(s, root);
	}
	int c = Search_str("abc", root);
	cout << c << endl;
	return 0;
}

720. Longest Word in Dictionary

Easy

492608Add to ListShare

Given a list of strings words representing an English Dictionary, find the longest word in words that can be built one character at a time by other words in words. If there is more than one possible answer, return the longest word with the smallest lexicographical order.

If there is no answer, return the empty string.

Example 1:

Input: 
words = ["w","wo","wor","worl", "world"]
Output: "world"
Explanation: 
The word "world" can be built one character at a time by "w", "wo", "wor", and "worl".

Example 2:

Input: 
words = ["a", "banana", "app", "appl", "ap", "apply", "apple"]
Output: "apple"
Explanation: 
Both "apply" and "apple" can be built from other words in the dictionary. However, "apple" is lexicographically smaller than "apply".

Note:

  • All the strings in the input will only contain lowercase letters.
  • The length of words will be in the range [1, 1000].
  • The length of words[i] will be in the range [1, 30].
#include"pch.h"
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
/*720. Longest Word in Dictionary
字典树:先将原数组按字符串长度、字母序排序,
从头遍历该数组,判断当前字符串是否除尾字符,都在字典树中,
如果是,将长度与当前最大长度比较,如果大于当前最大长度,更新结果
Runtime: 160 ms, faster than 11.13% of C++ online submissions for Longest Word in Dictionary.
Memory Usage: 47.2 MB, less than 10.00% of C++ online submissions for Longest Word in Dictionary.*/
typedef struct Trie {
	Trie *next[26];
	int num;//子树个数
};
Trie *createTrie() {
	Trie *root = (Trie*)malloc(sizeof(Trie));
	for (int i = 0; i < 26; i++) {
		root->next[i] = NULL;
	}
	root->num = 0;
	return root;
}
void Insert_str(Trie *root, string str) {
	Trie *p = root;
	for (int i = 0; i < str.size(); i++) {
		if (p->next[str[i] - 'a'] == NULL) {
			Trie *tmp = createTrie();
			p->next[str[i] - 'a'] = tmp;
			p->num++;
		}
		else p = p->next[str[i] - 'a'];
	}
	return;
}
int Search_str(Trie *root, string str) {
	Trie *p = root;
	int res = 0, i = 0;
	for (i = 0; i < str.size(); i++) {
		if (p->next[str[i] - 'a'] == NULL) {
			res = i; break;
		}
		else p = p->next[str[i] - 'a'];
	}
	if (i == str.size()) {//说明str在字典树中
		return i;
	}
	//str不在树中
	//str只有一个字母不在树中,可以符合条件
	if (res == str.size() - 1) {
		Insert_str(root, str);
		return str.size();
	}
	//str不止一个不在树中,不符合条件
	else {
		return -1;
	}
}
static bool cmp(string a,string b){
	if(a.size()!=b.size()) return a.size() < b.size();
	else return a < b;
}
string longestWord(vector<string>& words) {
	int max = 0;
	Trie *root = createTrie();
	sort(words.begin(), words.end(), cmp);
	string res = "";
	for (int i = 0; i < words.size(); i++) {
		int tmp = Search_str(root, words[i]);
		if (tmp > max) {
			max = tmp;
			res = words[i];
		}
	}
	return res;
}
int main() {
	vector<string> words = { {"ts","e","x","pbhj","opto","xhigy","erikz","pbh","opt","erikzb","eri","erik","xlye","xhig","optoj","optoje","xly","pb","xhi","x","o"} };
	cout << longestWord(words) << endl;
	return 0;
}
#include"pch.h"
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<unordered_map>
using namespace std;
/*720. Longest Word in Dictionary
将words按照字符串长度、字符大小排序,存入unordered_map中。
注意关联容器不能使用sort来进行排序,set和map内部采用红黑树对key进行了排序,但不能对value进行排序,需要排序只能将map放入线性容器中。
Runtime: 224 ms, faster than 6.88% of C++ online submissions for Longest Word in Dictionary.
Memory Usage: 68.7 MB, less than 10.00% of C++ online submissions for Longest Word in Dictionary.*/
static bool cmp1(string a,string b){
	if(a.size()!=b.size()) return a.size() < b.size();
	else return a < b;
}
static bool cmp2(pair<string,int> a,pair<string,int> b) {
	if (a.second != b.second) return a.second > b.second;
	else return a.first < b.first;
}
string longestWord(vector<string>& words) {
	unordered_map<string, int> mp;
	sort(words.begin(), words.end(), cmp1);
	for (int i = 0; i < words.size(); i++) {
		if (words[i].size() != 1) {
			string tmp = words[i].substr(0,words[i].size()-1);
			if (mp.find(tmp) != mp.end()) {//查找除尾字符的该字符串前面是否出现过
				//mp.erase(tmp);//如果出现过,将该较短的字符串移除,存入含尾字符的
				mp[words[i]] = words[i].size();
			}
		}
		else mp[words[i]] = 1;
	}
	unordered_map<string, int>::iterator it;
	vector<pair<string, int> > vec;
	for (it = mp.begin(); it != mp.end(); it++) {
		vec.push_back(make_pair(it->first, it->second));
	}
	sort(vec.begin(), vec.end(), cmp2);
	if(vec.size()>0) return vec[0].first;
	return "";
}
int main() {
	vector<string> words = { "rac","rs","ra","on","r","otif","o","onpdu","rsf","rs","ot","oti","racy","onpd" };
	cout << longestWord(words) << endl;
	return 0;
}
#include"pch.h"
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<unordered_set>
using namespace std;
/*720. Longest Word in Dictionary
使用unordered_set,每次一个新的words[i],对比与res的大小关系,从而实时更新
Runtime: 132 ms, faster than 14.27% of C++ online submissions for Longest Word in Dictionary.
Memory Usage: 41.9 MB, less than 10.00% of C++ online submissions for Longest Word in Dictionary.*/
static bool cmp(string a, string b) {
	if (a.size() != b.size()) return a.size() < b.size();
	return a < b;
}
string longestWord(vector<string>& words) {
	sort(words.begin(), words.end(), cmp);
	unordered_set<string> st;
	string res = "";
	for (int i = 0; i < words.size(); i++) {
		if (words[i].size() == 1) {
			st.insert(words[i]);
			if (res.size() < words[i].size()) res = words[i];
		}
		else {
			string tmp = words[i].substr(0,words[i].size()-1);
			if (st.find(tmp) != st.end()) {
				st.insert(words[i]);
				if (res.size() < words[i].size()) res = words[i];
			}
		}
	}
	return res;
}
int main() {
	vector<string> words = { "rac","rs","ra","on","r","otif","o","onpdu","rsf","rs","ot","oti","racy","onpd" };
	cout << longestWord(words) << endl;
	return 0;
}

1023. Camelcase Matching

Medium

130109Add to ListShare

A query word matches a given pattern if we can insert lowercase letters to the pattern word so that it equals the query. (We may insert each character at any position, and may insert 0 characters.)

Given a list of queries, and a pattern, return an answer list of booleans, where answer[i] is true if and only if queries[i] matches the pattern.

Example 1:

Input: queries = ["FooBar","FooBarTest","FootBall","FrameBuffer","ForceFeedBack"], pattern = "FB"
Output: [true,false,true,true,false]
Explanation: 
"FooBar" can be generated like this "F" + "oo" + "B" + "ar".
"FootBall" can be generated like this "F" + "oot" + "B" + "all".
"FrameBuffer" can be generated like this "F" + "rame" + "B" + "uffer".

Example 2:

Input: queries = ["FooBar","FooBarTest","FootBall","FrameBuffer","ForceFeedBack"], pattern = "FoBa"
Output: [true,false,true,false,false]
Explanation: 
"FooBar" can be generated like this "Fo" + "o" + "Ba" + "r".
"FootBall" can be generated like this "Fo" + "ot" + "Ba" + "ll".

Example 3:

Input: queries = ["FooBar","FooBarTest","FootBall","FrameBuffer","ForceFeedBack"], pattern = "FoBaT"
Output: [false,true,false,false,false]
Explanation: 
"FooBarTest" can be generated like this "Fo" + "o" + "Ba" + "r" + "T" + "est".

Note:

  1. 1 <= queries.length <= 100
  2. 1 <= queries[i].length <= 100
  3. 1 <= pattern.length <= 100
  4. All strings consists only of lower and upper case English letters.
#include"pch.h"
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<unordered_set>
using namespace std;
/*1023. Camelcase Matching
对于queries中的每个字符串,去pattern中匹配:
如果遍历到的与pattern当前的相同,pattern移到下一个字符
如果遍历到的与pattern当前的不同:
如果遍历到大写,false
遍历结束后,查看pattern是否到末尾,即是否全都被匹配到
如果没有,false,否则,true
Runtime: 0 ms, faster than 100.00% of C++ online submissions for Camelcase Matching.
Memory Usage: 7.9 MB, less than 100.00% of C++ online submissions for Camelcase Matching.*/
vector<bool> camelMatch(vector<string>& queries, string pattern) {
	int n = pattern.size();
	vector<bool> res;
	for (int i = 0; i < queries.size(); i++) {
		string tmp = queries[i];
		int k=0,flag=0;
		for (int j = 0; j < tmp.size(); j++) {
			if (k<n && tmp[j] == pattern[k]) k++;
			else if (tmp[j] >= 'A' && tmp[j] <= 'Z') {
				flag = 1;
				break;
			}
		}
		if (k==n && flag == 0) res.push_back(true);
		else res.push_back(false);
	}
	return res;
}
int main() {
	vector<string> q = { "FooBar","FooBarTest","FootBall","FrameBuffer","ForceFeedBack" };
	string pattern = "FoBaT";
	vector<bool> res = camelMatch(q,pattern);
	for (int i = 0; i < res.size(); i++) cout << res[i] << endl;
	return 0;
}

648. Replace Words

Medium

578122Add to ListShare

In English, we have a concept called root, which can be followed by some other words to form another longer word - let's call this word successor. For example, the root an, followed by other, which can form another word another.

Now, given a dictionary consisting of many roots and a sentence. You need to replace all the successor in the sentence with the root forming it. If a successor has many roots can form it, replace it with the root with the shortest length.

You need to output the sentence after the replacement.

Example 1:

Input: dict = ["cat", "bat", "rat"]
sentence = "the cattle was rattled by the battery"
Output: "the cat was rat by the bat"

Note:

  1. The input will only have lower-case letters.
  2. 1 <= dict words number <= 1000
  3. 1 <= sentence words number <= 1000
  4. 1 <= root length <= 100
  5. 1 <= sentence words length <= 1000
#include"pch.h"
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<unordered_set>
using namespace std;
/*648. Replace Words
字典树:
Runtime: 64 ms, faster than 70.99% of C++ online submissions for Replace Words.
Memory Usage: 53.4 MB, less than 28.57% of C++ online submissions for Replace Words.*/
typedef struct Trie {
	Trie *next[26];
	int num;
};

Trie *createTrie() {
	Trie *root = (Trie*)malloc(sizeof(Trie));
	for (int i = 0; i < 26; i++) {
		root->next[i] = NULL;
	}
	root->num = 0;
	return root;
}
void Insert_str(Trie *root, string str) {
	Trie *p = root;
	for (int i = 0; i < str.size(); i++) {
		if (p->next[str[i] - 'a'] != NULL && p->next[str[i]-'a']->num==0) return;
		else if (p->next[str[i] - 'a'] != NULL) {
			p = p->next[str[i] - 'a'];
		}
		else {
			Trie *tmp = createTrie();
			p->next[str[i] - 'a'] = tmp;
			p->num++;
			p = tmp;
		}
	}
	return;
}
int Search_str(Trie *root, string str) {
	Trie *p = root;
	int res = 0;
	for (int i = 0; i < str.size(); i++) {
		if (p->next[str[i] - 'a'] != NULL) {
			p = p->next[str[i] - 'a'];
			res++;
		}
		else if(p->num==0) return i;
		else break;
	}
	if(p->num!=0) return str.size();
	return res;
}
string replaceWords(vector<string>& dict, string sentence) {
	Trie *root = createTrie();
	for (int i = 0; i < dict.size(); i++) {
		Insert_str(root, dict[i]);
	}
	vector<string> res;
	string ress = "";
	string tmp = "";
	for(int i = 0; i < sentence.size(); i++) {
		if (sentence[i] != ' ')  tmp += sentence[i];
		else {
			res.push_back(tmp);
			tmp = "";
		}
	}
	res.push_back(tmp);
	for (int i = 0; i < res.size(); i++) {
		tmp = res[i];
		int num = Search_str(root, tmp);
		if (num != 0) {
			tmp = tmp.substr(0, num);
			if (i != 0) ress += " ";
			ress += tmp;
		}
		else {
			if (i != 0) ress += " ";
			ress += tmp;
		}
	}
	return ress;
}
static bool cmp(string a, string b) {
	if (a.size() != b.size()) return a.size() < b.size();
	return a < b;
}
int main() {
	vector<string> q = { "cat", "bat", "rat" };
	string s = "the cattle was rattled by the battery";
	sort(q.begin(), q.end(),cmp);
	cout << replaceWords(q, s);
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值