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

++回溯枚举情况 出口处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 );

}

};

相关推荐
皓月斯语43 分钟前
B3842 [GESP202306 三级] 春游 题解
数据结构·c++·算法·题解
atunet1 小时前
树状结构在查询优化中的作用与实现细节7
算法
徐凤年_1 小时前
rog_map参数理解
算法
春日见1 小时前
算法与数据结构----哈希表
数据结构·人工智能·算法·机器学习·自动驾驶·哈希算法·散列表
叩码以求索2 小时前
统计按位或能得到最大值的子集数目(一)
数据结构·算法
tachibana22 小时前
hot100 数组中的第K个最大元素(215)
java·数据结构·算法·leetcode
txzrxz2 小时前
单调队列讲解
数据结构·c++·算法·单调队列
不会就选b3 小时前
算法日常・每日刷题--<快排>4
算法
Keven_113 小时前
算法札记:树状数组的用途
数据结构·算法
用户677437175813 小时前
C++函数参数传递方式详解:string、string&、const string、const string&该怎么选?
算法