字符串拼接路径——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】
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!