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

++回溯枚举情况 出口处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(pathk != 0) return; //check
ans = max(ans,cnt);
++

return;

}

//不选

dfs(i+1,cnt);

//选

pathrequests\[i0]--;//出去

pathrequests\[i1]++;//进去

dfs(i+1,cnt+1);

//恢复现场

pathrequests\[i0]++;//出去

pathrequests\[i1]--;//进去

};

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); // 不选 numsi

dfs(i + 1, ++subset_or | numsi); // 选++

};

dfs(0, 0);

return ans;

}

};

lc1255

预处理: 统计字母库存后

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

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

class Solution {

public:

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

int ans = 0, left26{};

for (char c : letters)

++leftc - 'a';

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

{

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

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

return;

}

// 不选 wordsi

dfs(i - 1, total);

// 选 wordsi

bool ok = true;

for (char c : wordsi) {

++if (leftc - 'a'-- == 0)++

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

++total += scorec - 'a'; // 累加得分++

}

if (ok)

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

// 恢复现场

++for (char c : wordsi)++

++++leftc - '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 );

}

};

相关推荐
BothSavage13 小时前
Trae远程开发中DeepSeek自定义模型4054错误的排查与修复
算法
小林ixn13 小时前
从暴力到KMP:一道题彻底搞懂字符串匹配的前世今生
算法
烬羽15 小时前
字符串算法入门:从反转字符串到回文判断,面试不再慌
算法·面试
先吃饱再说1 天前
判断回文字符串,从一行代码到双指针优化
算法
黄敬峰1 天前
深入理解算法核心:从递归思想、数组扁平化到快速排序
算法
得物技术1 天前
从狂野代码到按目标生产:得物推荐 AI Harness 的工程化实践|AICon 演讲整理
人工智能·算法·架构
AI小老六2 天前
SkillOpt 架构拆解:把 Skill 文本当参数,用执行轨迹训练 Agent
后端·算法·ai编程
胡萝卜术2 天前
从“分数打架”到“排名投票”:为什么你的ChatBI必须用RRF?
算法·设计模式·面试
Asize2 天前
初识DFS 与 BFS:递归、队列与图遍历
算法