双向广搜
- 用途一:小优化
- BFS 的剪枝策略,分两侧展开分支,哪侧数量少就从哪侧展开
- 用途二:
- 特征:全量样本不允许递归完全展开,但是半量样本可以完全展开。(完全展开的过程中有可能能够进行分组,进行常数级优化)
- 过程:把数据分成两部分,每部分各自展开计算结果,然后设计两部分结果的整合逻辑
| #include <iostream> |
| #include <vector> |
| #include <queue> |
| #include <unordered_set> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| int ladderLength(string beginWord, string endWord, vector<string> &wordList) { |
| |
| unordered_set<string> dict; |
| for (const auto &item: wordList) |
| dict.emplace(item); |
| if (dict.find(endWord) == dict.end()) return 0; |
| |
| |
| unordered_set<string> smallLevel; |
| |
| unordered_set<string> bigLevel; |
| |
| unordered_set<string> nextLevel; |
| |
| smallLevel.emplace(beginWord); |
| bigLevel.emplace(endWord); |
| |
| int len = 2; |
| while (!smallLevel.empty()) { |
| |
| for (string word: smallLevel) { |
| string nw = word; |
| |
| for (int i = 0; i < nw.length(); ++i) { |
| char oldCh = nw[i]; |
| for (char ch = 'a'; ch <= 'z'; ch++) { |
| |
| if (ch == oldCh) continue; |
| nw[i] = ch; |
| |
| if (bigLevel.find(nw) != bigLevel.end()) return len; |
| |
| if (dict.find(nw) != dict.end()) { |
| nextLevel.emplace(nw); |
| |
| dict.erase(nw); |
| } |
| } |
| |
| nw[i] = oldCh; |
| } |
| } |
| if (nextLevel.size() > bigLevel.size()) { |
| |
| auto newSmall = bigLevel; |
| auto newBig = nextLevel; |
| smallLevel = newSmall; |
| bigLevel = newBig; |
| } else { |
| auto newSmall = nextLevel; |
| smallLevel = newSmall; |
| } |
| nextLevel.clear(); |
| len++; |
| } |
| |
| return 0; |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| #include <queue> |
| #include <unordered_set> |
| #include <algorithm> |
| |
| using namespace std; |
| |
| long N, M; |
| vector<long> prices; |
| |
| |
| void generate(int left, int right, long tempSum, vector<long> &sums) { |
| if (tempSum > M) return; |
| if (left > right) { |
| sums.emplace_back(tempSum); |
| return; |
| }; |
| |
| generate(left + 1, right, tempSum, sums); |
| |
| generate(left + 1, right, tempSum + prices[left], sums); |
| } |
| |
| int main() { |
| cin >> N >> M; |
| prices.resize(N); |
| for (int i = 0; i < N; ++i) |
| cin >> prices[i]; |
| |
| |
| vector<long> leftSum; |
| vector<long> rightSum; |
| |
| long mid = N >> 1; |
| generate(0, mid - 1, 0, leftSum); |
| generate(mid, N - 1, 0, rightSum); |
| |
| |
| sort(leftSum.begin(), leftSum.end()); |
| sort(rightSum.begin(), rightSum.end()); |
| |
| |
| long res = 0; |
| long lSize = leftSum.size(); |
| long rSize = rightSum.size(); |
| long left = 0; |
| long right = rSize - 1; |
| |
| while (left < lSize) { |
| while (right >= 0 && leftSum[left] + rightSum[right] > M) |
| right--; |
| res += right + 1; |
| left++; |
| } |
| |
| cout << res; |
| } |
| #include <iostream> |
| #include <vector> |
| #include <algorithm> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| void generate(vector<int> &nums, int left, int right, long sum, vector<long> &sums) { |
| if (left == right + 1) { |
| sums.emplace_back(sum); |
| return; |
| } |
| |
| generate(nums, left + 1, right, sum, sums); |
| |
| generate(nums, left + 1, right, sum + nums[left], sums); |
| } |
| |
| int minAbsDifference(vector<int> &nums, int goal) { |
| vector<long> leftSums; |
| vector<long> rightSums; |
| int mid = nums.size() >> 1; |
| |
| generate(nums, 0, mid - 1, 0, leftSums); |
| generate(nums, mid, nums.size() - 1, 0, rightSums); |
| |
| sort(begin(leftSums), end(leftSums)); |
| sort(begin(rightSums), end(rightSums)); |
| |
| long lSize = leftSums.size(); |
| long rSize = rightSums.size(); |
| long left = 0; |
| long right = rSize - 1; |
| long res = LONG_MAX; |
| |
| |
| |
| |
| |
| while (left < lSize && right >= 0) { |
| int t = leftSums[left] + rightSums[right]; |
| if (t == goal) { |
| return 0; |
| } else if (t < goal) { |
| if (goal - t < res) res = goal - t; |
| left++; |
| } else if (t > goal) { |
| if (t - goal < res) res = t - goal; |
| right--; |
| } |
| } |
| |
| return res; |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| #include <algorithm> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| |
| void generate(vector<int> &nums, int left, int right, long sum, vector<long> &sums) { |
| if (left == right + 1) { |
| sums.emplace_back(sum); |
| return; |
| } |
| |
| |
| int cur = left; |
| while (cur + 1 <= right && nums[cur + 1] == nums[cur]) |
| cur++; |
| |
| int len = cur - left + 1; |
| |
| for (int i = 0; i <= len; ++i) |
| generate(nums, cur + 1, right, sum + i * nums[left], sums); |
| } |
| |
| int minAbsDifference(vector<int> &nums, int goal) { |
| |
| |
| long negativeSum = 0; |
| |
| long positiveSum = 0; |
| for (int i = 0; i < nums.size(); ++i) { |
| if (nums[i] > 0) positiveSum += nums[i]; |
| if (nums[i] < 0) negativeSum += nums[i]; |
| } |
| if (negativeSum > goal) return negativeSum - goal; |
| if (positiveSum < goal) return goal - positiveSum; |
| |
| |
| |
| sort(nums.begin(), nums.end()); |
| |
| vector<long> leftSums; |
| vector<long> rightSums; |
| int mid = nums.size() >> 1; |
| |
| generate(nums, 0, mid - 1, 0, leftSums); |
| generate(nums, mid, nums.size() - 1, 0, rightSums); |
| |
| sort(begin(leftSums), end(leftSums)); |
| sort(begin(rightSums), end(rightSums)); |
| |
| long lSize = leftSums.size(); |
| long rSize = rightSums.size(); |
| long left = 0; |
| long right = rSize - 1; |
| long res = LONG_MAX; |
| |
| |
| |
| |
| |
| while (left < lSize && right >= 0) { |
| int t = leftSums[left] + rightSums[right]; |
| if (t == goal) { |
| return 0; |
| } else if (t < goal) { |
| if (goal - t < res) res = goal - t; |
| left++; |
| } else if (t > goal) { |
| if (t - goal < res) res = t - goal; |
| right--; |
| } |
| } |
| |
| return res; |
| } |
| }; |
本文作者:n1ce2cv
本文链接:https://www.cnblogs.com/sprinining/p/18416554
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
2021-09-16 监听器
2021-09-16 浅拷贝深拷贝1