lc472
只尝试 `len < n` 确保由"更短单词"拼成;等长词不会参与
// 思路(排序+逐词断词 DP,长度去重优化)
// - 按长度升序处理,只用"更短"的词去拼当前词。
// - 对每个词做 word-break:`dp[i]` 表示前 i 位可由更短词拼出;只尝试出现过的"长度集合",剪枝快。
// - 复杂度:总 O(∑L · |lenSet|);因每词长度 ≤ 30、lenSet ≤ 30,且总长度 ≤ 1e5,足够快。
class Solution {
public:
std::vector<std::string> findAllConcatenatedWordsInADict(std::vector<std::string>& w)
{
std::sort(w.begin(), w.end(), [](auto& a, auto& b){ return a.size() < b.size(); });
std::unordered_set<std::string> S;
std::unordered_set<int> seenLen;
std::vector<int> L; // 已出现的不同长度
std::vector<std::string> ans;
for (auto& s : w) {
int n = s.size();
if (!S.empty() && ok(s, S, L)) ans.push_back(s);
S.insert(s);
if (seenLen.insert(n).second) L.push_back(n);
}
return ans;
}
private:
static bool ok(const std::string& s, const std::unordered_set<std::string>& S, const std::vector<int>& L)
{
int n = s.size();
std::vector<char> dp(n + 1); dp[0] = 1;
for (int i = 0; i < n; ++i) if (dp[i]) {
for (int len : L) if (len < n && i + len <= n && S.count(s.substr(i, len)))
{
if ((dp[i + len] = 1) && dp[n]) return true;
}
}
return dp[n];
}
};
lc466
找出由n1个s1拼接成的字符串里,++最多能包含多少个完整的s2(再除以n2得最终结果)++
过程中用循环检测来避免重复计算,提升效率
class Solution
{
//s1*n1删除某些字符能得到s2*n2*m
public:
int getMaxRepetitions(std::string s1, int n1, std::string s2, int n2) {
using ll = long long;
// 不可匹配的快速判零
std::array<int,26> has{}; for(char c: s1) has[c-'a']=1;
for(char c: s2) if(!has[c-'a']) return 0;
int L2 = s2.size(), j = 0;
std::vector<int> first(L2, -1);
std::vector<ll> cnt(L2, 0);
ll c2 = 0; // 已匹配完整 s2 的次数
for (ll i = 0; i < n1; ++i) {
for (char c : s1) {
if (c == s2[j] && ++j == L2) j = 0, ++c2;
}
if (first[j] != -1) { // 发现循环
ll i0 = first[j], c20 = cnt[j];
ll perBlk = i - i0, perCnt = c2 - c20;
ll loops = (n1 - 1 - i) / perBlk;
c2 += loops * perCnt;
i += loops * perBlk;
} else {
first[j] = i; cnt[j] = c2;
}
}
return (int)(c2 / n2);
}
};
lc791
直接返回 true / false 确保"在order中的字符优先排前面"
class Solution {
public:
string customSortString(string order, string s)
{
unordered_map<char,int> hash;
for(int i=0;i<order.size();i++)
{
hash[order[i]]=i;
}
sort(s.begin(),s.end(),[&](char& a,char& b)
{
if(hash.count(a) && hash.count(b))
return hash[a]<hash[b];
else if(hash.count(a))
return true;
else if(hash.count(b))
return false;
else
return a<b;
});
return s;
}
};