字符串拼接路径——bfs+剪枝
原题在这里:
概述题意,给定一个字符串数组和一个target字符串,问能否用使用字符串数组中字符串最少次数拼接出target字符串,如果不能则-1。
analyse:
很基础的想法:
桶存遍历target,再遍历一边字符串数组,先验证是否能拼凑出同时,存入字符串数组中每一个字符串的桶存字符,以便在bfs中遍历使用桶存数组进行处理。
code:
class Solution { vector<int> vis, num; vector<vector<int>> mp; bool gets, out; vector<int> get(vector<int> x, vector<int> y) { bool pd = true; for (int i = 0; i < 30; ++i) { if (x[i] > 0 && y[i] > 0) //有效处理 gets = true; x[i] -= y[i]; if (x[i] > 0) pd = false; } if (gets && pd) out = true; return x; } public: int minStickers(vector<string> &stickers, string target) { vis = num = vector<int>(30, 0); set<vector<int>> st; int n = stickers.size(); mp = vector<vector<int>>(n, vector<int>(30, 0)); for (char i : target) { vis[i - 'a'] = 1; ++num[i - 'a']; } for (int i = 0; i < stickers.size(); ++i) for (char j : stickers[i]) vis[j - 'a'] = 0, ++mp[i][j - 'a']; for (int i = 0; i < 30; ++i) if (vis[i]) return -1; queue<vector<int>> q; q.push(num); st.insert(num); int ans = 0; out = false; while (q.size()) { int m = q.size(); while (m--) { vector<int> now = q.front(); q.pop(); for (int i = 0; i < n; ++i) { gets = false; vector<int> res = get(now, mp[i]); if (gets == false) continue; if (st.count(res) == 0) { q.push(res); st.insert(res); } } } ++ans; if (out) return ans; } return -1; } };
进阶想法:
1.数据范围合适,那么在判断是否能拼凑出选择使用位运算来判断。
2.预处理字符串数组中字符串,只选择有效字符。
3.广搜选用字符串,而不是数组。
4.基本set去重。
code:
class Solution { public: int minStickers(vector<string> &stickers_, string target) { string start(26, 1), end(26, 1); unordered_set<string> st; int x = 0, y = 0; // 初始化初始状态 h for (char c : target) start[c - 'a']++, x |= (1 << (c - 'a')); vector<string> stickers; // 优化贴纸集合空间 for (string s : stickers_) { string fs = ""; for (auto &c : s) { if (x >> (c - 'a') & 1) fs += c, y |= (1 << (c - 'a')); } if (!fs.empty()) stickers.push_back(fs); } if ((x & y) < x) return -1; // 不可能完成时 int res = 0; queue<string> q; q.push(start); st.insert(start); // 广搜过程 while (!q.empty()) { int len = q.size(); res++; while (len--) { string now = q.front(); q.pop(); for (string s : stickers) { auto temp = now; for (auto &c : s) if (temp[c - 'a'] > 1) temp[c - 'a']--; if (temp == end) return res; if (!st.count(temp)) { st.insert(temp); q.push(temp); } } } } return -1; } };
【Over】

浙公网安备 33010602011771号