山脉二分找中值|子集型回溯

++回溯枚举情况 出口处check++

lc1601

不选 选

++DFS枚举所有请求的选与不选,统计++满足所有节点进出人数平衡的请求组合,返回最大请求数量

class Solution {

public:

int maximumRequests(int n, vector<vector<int>>& requests) {

int ans = 0;

int l = requests.size();

vector<int> path(n,0);

//i表示当前遍历的元素,cnt是当前满足的请求

function<void(int,int)> dfs = [&](int i,int cnt)

{

if(i==l)

{

for(int k = 0;k < n;++k)

++if(path[k] != 0) return; //check
ans = max(ans,cnt);
++

return;

}

//不选

dfs(i+1,cnt);

//选

path[requests[i][0]]--;//出去

path[requests[i][1]]++;//进去

dfs(i+1,cnt+1);

//恢复现场

path[requests[i][0]]++;//出去

path[requests[i][1]]--;//进去

};

dfs(0,0);

return ans;

}

};

lc2044

之前是用for迭代写的

刷题单发现还可以回溯写(`・ω・´)

先计算数组所有元素的总按位或值

再通过DFS枚举子集,统计按位或等于该最大值的子集数量

trick:

if (subset_or == total_or)

ans += 1 << (n - i);

当子集按位或等于最大值时,剩++余 n-i 个元素选或不选都不影响结果++,直接用 2^(n-i) 快速统计这类子集的数量。

class Solution {

/*

输入:nums = [3,2,1,5]

输出:6

解释:子集按位或可能的最大值是 7 。有 6 个子集按位或可以得到 7 :

  • 3,5

  • 3,1,5

  • 3,2,5

  • 3,2,1,5

  • 2,5

  • 2,1,5

*/

public:

int countMaxOrSubsets(vector<int>& nums) {

int ++total_or = reduce(nums.begin(), nums.end(), 0, bit_or());++

int n = nums.size();

int ans = 0;

auto dfs = [&](this auto&& dfs, int i, int subset_or) {

++if (subset_or == total_or) {
ans += 1 << (n - i);
++

return; //cut

}

if (i == n)

return;

dfs(i + 1, subset_or); // 不选 nums[i]

dfs(i + 1, ++subset_or | nums[i]); // 选++

};

dfs(0, 0);

return ans;

}

};

lc1255

预处理: 统计字母库存后

DFS枚举单词选或不选的所有组合

验证字母是否充足并计算得分,最终返回最大得分

class Solution {

public:

int maxScoreWords(vector<string> &words, vector<char> &letters, vector<int> &score) {

int ans = 0, left[26]{};

for (char c : letters)

++left[c - 'a'];

function<void(int, int)> dfs = [&](int i, int total)

{

if (i < 0) { // 到头了

++ans = max(ans, total);++

return;

}

// 不选 words[i]

dfs(i - 1, total);

// 选 words[i]

bool ok = true;

for (char c : words[i]) {

++if (left[c - 'a']-- == 0)++

++ok = false; // 剩余字母不足++

++total += score[c - 'a']; // 累加得分++

}

if (ok)

++dfs(i - 1, total);++

// 恢复现场

++for (char c : words[i])++

++++left[c - 'a'];++

};

dfs(words.size() - 1, 0);

return ans;

}

};

lc1095

山脉数组 两次二分

先二分查找山脉数组的峰值位置

再在峰值左侧升序区间和右侧降序区间分别二分查找目标值

优先返回左侧找到的索引

/**

* // This is the MountainArray's API interface.

* // You should not implement it, or speculate about its implementation

* class MountainArray {

* public:

* int get(int index);

* int length();

* };

*/

class Solution

{

public:

int binary_search(MountainArray & mountainArr, int target, int L, int R, int sign)

{

target = sign * target;

while (L <= R)

{

int mid = (L + R) >> 1;

int cur = sign * mountainArr.get(mid);

if (cur == target)

return mid;

else if (cur < target)

L = mid + 1;

else

R = mid - 1;

}

return -1;

}

int findInMountainArray(int target, MountainArray &mountainArr)

{

int L = 0, R = mountainArr.length() - 1;

while (L <= R)

{

int mid = (L + R) >> 1;

if (mountainArr.get(mid) < mountainArr.get(mid + 1))

L = mid + 1;

else

R = mid-1;

}

int peak_idx = L;

int idx = binary_search(mountainArr, target, 0, peak_idx, 1 );

if (idx != -1)

return idx;

return binary_search(mountainArr, target, peak_idx + 1, mountainArr.length() - 1, -1 );

}

};

相关推荐
m0_629494732 小时前
LeetCode 热题 100-----26.环形链表 II
数据结构·算法·leetcode·链表
壹号用户2 小时前
用队列实现栈
数据结构·算法
做人求其滴2 小时前
面试经典 150 题 380 274
c++·算法·面试·职场和发展·力扣
daad7772 小时前
记一组无人机IMU传感器数据
算法
计算机安禾2 小时前
【c++面向对象编程】第42篇:模板特化与偏特化:为特定类型定制实现
开发语言·c++·算法
小O的算法实验室2 小时前
2026年KBS,流形感知强化学习差分进化算法+不规则3D无人机路径规划,深度解析+性能实测
算法·智能算法·智能算法改进
玖釉-3 小时前
C++ 中的循环语句详解:while、do...while、for、嵌套循环与循环控制
开发语言·c++·算法
不做无法实现的梦~3 小时前
运动控制系统复习一览-----常考题目总结版本
算法
小短腿的代码世界3 小时前
信号路由风暴:Qt算法交易系统的高频信号分发架构
qt·算法·架构
阿文的代码库3 小时前
一文读懂GROUP BY 1,2 VS GROUP BY column_1, column_2 的区别
算法