2022/11 LeetCode练习
🔰🔰🔰:困难
🔰🔰:中等
🔰:简单
💤:待补题
🔰
1662.检查两个字符串数组是否相等🔰🔰
2453.摧毁一系列目标🔰
1620.网络信号最好的坐标🔰
1668.最大重复子字符串🔰🔰
754.到达终点数字🔰🔰🔰
1106.解析布尔表达式🔰🔰
6230.长度为 K 子数组中的最大和🔰🔰
816.模糊坐标🔰🔰
(动态规划)764.最大加号标志🔰🔰
(动态规划)790.多米诺和托米诺平铺🔰🔰
6234.最小公倍数为 K 的子数组数目🔰🔰🔰
(状态压缩 + 常规bfs)864.获取所有钥匙的最短路径🔰🔰
791.自定义字符串排序- 💤
🔰🔰
647.回文子串 - 💤
🔰🔰🔰
6236.不重叠回文子字符串的最大数目 🔰🔰🔰
805.数组的均值分割🔰
1710.卡车上的最大单元数🔰🔰
792. 匹配子序列的单词数🔰🔰🔰
891.子序列宽度之和🔰🔰
799.香槟塔🔰🔰
6242.二叉搜索树最近节点查询
🔰
1662.检查两个字符串数组是否相等
https://leetcode.cn/problems/check-if-two-string-arrays-are-equivalent/
简单的双指针操作
class Solution {
public:
bool arrayStringsAreEqual(vector<string>& word1, vector<string>& word2) {
int a = 0, b = 0;
int i = 0, j = 0;
int n = word1.size(), m = word2.size();
while(i < n && j < m)
{
if(word1[i][a++] != word2[j][b++]) return false;
if(a == word1[i].size()){
a = 0;
++i;
}
if(b == word2[j].size()){
b = 0;
++j;
}
}
return i == n && j == m;
}
};
🔰🔰
2453.摧毁一系列目标
https://leetcode.cn/problems/destroy-sequential-targets/
暴力, 超时
- 先用map记录了每个位置上目标的数量, 以及最远的位置maxnum
- 在区间[nums[i], nums[i]+space*j] (
nums[i]+space*j <= maxnum
)中累加符合条件的位置上的目标数量, 并更新最大值
class Solution {
public:
int destroyTargets(vector<int>& nums, int space) {
int n = nums.size();
map<int, int> mp;
int maxnum = -1;
for(int i = 0; i < n; ++i){
mp[nums[i]] ++;
maxnum = nums[i]>maxnum ? nums[i]:maxnum;
}
int res = 1e9, resnum = -1;
for(int i = 0; i < n; ++i){
int t = 0;
int k = ((maxnum-nums[i])/space)+1;
for(int j = 0; j <= k; ++j){
t += mp[nums[i]+space*j];
}
if(t >= resnum){
resnum = t;
res = res < nums[i] ? res : nums[i];
}
}
return res;
}
};
转化思路:
- 要找到尽可能多的数x满足
nums[i]+c*space
👉 找到尽可能多的数k = x%space =nums[i]%space
- 在摧毁数目最多的前提下,nums[i]的最小值 👉 从小到大遍历num[],找满足最多的那个k
class Solution {
public:
int destroyTargets(vector<int>& nums, int space) {
unordered_map<int, int> cnt;
sort(nums.begin(), nums.end());
for(auto& x:nums) ++cnt[x%space];
int res = 0, t = 0;
for(auto& x:nums){
if(t < cnt[x%space]){
t = cnt[x%space];
res = x;
}
}
return res;
}
};
🔰
1620.网络信号最好的坐标
https://leetcode.cn/problems/coordinate-with-maximum-network-quality/
纯枚举
class Solution {
public:
vector<int> bestCoordinate(vector<vector<int>>& towers, int radius) {
int n = towers.size();
int resx, resy, _max = -1;
for(int i = 0; i <= 50; ++i) {
for(int j = 0; j <= 50; ++j) {
int t = 0;
for(auto& e:towers){
double d = sqrt((i-e[0])*(i-e[0])+(j-e[1])*(j-e[1]));
if(d <= radius) t += (int)(e[2]/(1+d));
}
if(t > _max) {
resx = i, resy = j;
_max = t;
}
}
}
return {resx, resy};
}
};
✨蓝桥杯H: 扫雷
💣
小明最近迷上了一款名为《扫雷》的游戏。
其中有一个关卡的任务如下:
在一个二维平面上放置着 n 个炸雷,第 i 个炸雷 (xi,yi,ri) 表示在坐标 (xi,yi) 处存在一个炸雷,它的爆炸范围是以半径为 ri 的一个圆。
为了顺利通过这片土地,需要玩家进行排雷。
玩家可以发射 m 个排雷火箭,小明已经规划好了每个排雷火箭的发射方向,第 j 个排雷火箭 (xj,yj,rj) 表示这个排雷火箭将会在 (xj,yj) 处爆炸,它的爆炸范围是以半径为 rj 的一个圆,在其爆炸范围内的炸雷会被引爆。
同时,当炸雷被引爆时,在其爆炸范围内的炸雷也会被引爆。
现在小明想知道他这次共引爆了几颗炸雷?
你可以把炸雷和排雷火箭都视为平面上的一个点。
一个点处可以存在多个炸雷和排雷火箭。
当炸雷位于爆炸范围的边界上时也会被引爆。
输入格式
输入的第一行包含两个整数 n、m。
接下来的 n 行,每行三个整数 xi,yi,ri,表示一个炸雷的信息。
再接下来的 m 行,每行三个整数 xj,yj,rj,表示一个排雷火箭的信息。
输出格式
输出一个整数表示答案。
数据范围
对于 40% 的评测用例:0 ≤ x, y ≤ 10^9, 0 ≤ n, m ≤ 10^3, 1 ≤ r ≤ 10,
对于 100% 的评测用例:0 ≤ x, y ≤ 10^9, 0 ≤ n, m ≤ 5×10^4, 1 ≤ r ≤ 10。
输入样例:
2 1
2 2 4
4 4 2
0 0 5
输出样例:
2
样例解释
示例图如下,排雷火箭 1 覆盖了炸雷 1,所以炸雷 1 被排除;炸雷 1 又覆盖了炸雷 2,所以炸雷 2 也被排除。
图遍历 + 手动哈希
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long LL;
const int N = 5e4+10, M = 1e6+7;
struct Circle{
int x, y, r;
}cir[N];
LL h[M];
int st[M];
int id[M];
bool check(int x, int y, int i, int j, int r) {
return (x-i)*(x-i)+(y-j)*(y-j) <= r*r;
}
//(x, y) => LL
LL get_key(int x, int y) {
return x*1000000001ll + y;
}
//(x, y) => hashcode
int find(int x, int y) {
LL key = get_key(x, y);
int t = (key % M + M) % M;
while(h[t] != -1 && h[t] != key)
if(++t == M)
t = 0;
return t;
}
void dfs(int x, int y, int r) {
st[find(x, y)] = true;
for (int i = x-r; i <= x+r; ++i){
for(int j = y-r; j <= y+r; ++j){
if(check(x, y, i, j, r)){
int t = find(i, j);
if(id[t] && !st[t]) dfs(i, j, cir[id[t]].r);
}
}
}
}
int main()
{
memset(h, -1, sizeof(h));
int n, m;
scanf("%d%d", &n, &m);
int x, y, r;
for(int i = 1; i <= n; ++i){
scanf("%d%d%d", &x, &y, &r);
cir[i] = {x, y, r};
int t = find(x, y);
if(h[t] == -1) h[t] = get_key(x, y);
if(!id[t] || cir[id[t]].r < r) id[t] = i;
}
while(m --)
{
scanf("%d%d%d", &x, &y, &r);
for (int i = x-r; i <= x+r; ++i){
for(int j = y-r; j <= y+r; ++j){
if(check(x, y, i, j, r)){
int t = find(i, j);
if(id[t] && !st[t]) dfs(i, j, cir[id[t]].r);
}
}
}
}
int res = 0;
for(int i = 1; i <= n; ++i)
if(st[find(cir[i].x, cir[i].y)])
++res;
printf("%d", res);
return 0;
}
🔰
1668.最大重复子字符串
https://leetcode.cn/problems/maximum-repeating-substring/
注意审题
class Solution {
public:
int maxRepeating(string sequence, string word) {
int res = 0;
string k_rep = word;
while(sequence.find(k_rep) != -1)
{
res ++;
k_rep += word;
}
return res;
}
};
🔰🔰
754.到达终点数字
https://leetcode.cn/problems/reach-a-number/
参考题解: 灵茶山艾府
class Solution {
public:
int reachNumber(int target) {
target = target < 0 ? -target : target;
int num = 0;
while(target > 0)
{
++num;
target -= num;
}
return target&1 ? num+1+num%2 : num;
}
};
优化
上面的while循环目的是寻找满足 的最小值num,
即
class Solution {
public:
int reachNumber(int target) {
target = target < 0 ? -target : target;
int num =ceil((sqrt(1+8L*target)-1)/2);
return (num*(num+1)/2-target)&1 ? num+1+num%2 : num;
}
};
🔰🔰🔰
1106.解析布尔表达式
https://leetcode.cn/problems/parsing-a-boolean-expression/
栈的运用
class Solution {
public:
bool parseBoolExpr(string expression) {
stack<char> stk;
for(auto e : expression) {
if(e == '(' || e == ',') continue;
if(e == 't' || e == 'f') stk.push(e);
else if(e == '|' || e == '&' || e == '!') stk.push(e);
else {
int tnum = 0, fnum = 0;
while(stk.top() == 't' || stk.top() == 'f'){
if(stk.top() == 't') ++tnum;
else ++fnum;
stk.pop();
}
char op = stk.top();
stk.pop();
stk.push(calculate(tnum, fnum, op));
}
}
return stk.top() == 't';
}
char calculate(int tnum, int fnum, char op){
if(op == '!') return tnum ? 'f' : 't';
if(op == '|') return tnum ? 't' : 'f';
if(op == '&') return fnum ? 'f' : 't';
return 't';
}
};
🔰🔰
6230.长度为 K 子数组中的最大和
https://leetcode.cn/problems/maximum-sum-of-distinct-subarrays-with-length-k/
滑动窗口
维护一个长度为k的窗口, 以及一个哈希表(用来记录滑动窗口内数字的是否存在)
class Solution {
public:
long long maximumSubarraySum(vector<int>& nums, int k) {
int st[100010];
memset(st, 0, sizeof(st));
int n = nums.size();
long long sum = 0, res = 0;
for(int l = 0, r = 0; r < n; r++) {
st[nums[r]] ++;
sum += nums[r];
while(st[nums[r]] > 1 || r+1-l > k) {
sum -= nums[l];
st[nums[l]] --;
l ++;
}
if(r+1-l == k){
res = max(res, sum);
}
}
return res;
}
};
🔰🔰
816.模糊坐标
https://leetcode.cn/problems/ambiguous-coordinates/
.
的添加与否
对于一个数字字符串s
s == "0" || s[0] != "0"
直接加入左/右的items序列,并returns[0] != "0"
,直接加入左/右的items序列- 最后一位为0, 则return (该字符串s无法添加小数点, 否则会有多余的0,不合题意)
- 最后一位不为0,
- 首位为0(此时只能是
0.k
/0.00k
[k=1...9]的形式), 将该小数字符串返回 - 首位不为0, 则在任意两字符间添加小数点均可
- 首位为0(此时只能是
class Solution {
public:
vector<string> getItems(string s) {
vector<string> items;
if(s == "0") {
items.push_back(s);
return items;
}
if (s[0] != '0') items.push_back(s);
int len = s.size();
if(s[len-1] == '0') return items;
if(s[0] == '0') items.push_back("0."+s.substr(1));
else{
for (int p = 1; p < len; ++p)
items.push_back(s.substr(0, p) + "." + s.substr(p));
}
return items;
}
vector<string> ambiguousCoordinates(string s) {
int n = s.size();
s = s.substr(1, n-2);
vector<string> res;
for (int i = 1; i < n-2; ++i) {
vector<string> l_items = getItems(s.substr(0, i));
if(!l_items.size()) continue;
vector<string> r_items = getItems(s.substr(i, n-2));
if(!r_items.size()) continue;
for(auto& a : l_items)
for(auto& b : r_items) {
res.push_back("("+ a + ", " + b + ")");
}
}
return res;
}
};
🔰🔰
(动态规划)764.最大加号标志
https://leetcode.cn/problems/largest-plus-sign/
class Solution {
public:
int orderOfLargestPlusSign(int n, vector<vector<int>>& mines) {
int res = 0;
vector<vector<int>> g(n, vector<int>(n, n));
for(auto t : mines) g[t[0]][t[1]] = 0;
for(int i = 0; i < n; ++i){
int d[4] = {0};
// dir[0,1,2,3]: 从左/右/上/下开始数到当前位置连续的"1"的数量
for(int j = 0, k = n-1; j < n; ++j,--k){
d[0] = g[i][j] ? d[0]+1 : 0;
d[1] = g[i][k] ? d[1]+1 : 0;
d[2] = g[j][i] ? d[2]+1 : 0;
d[3] = g[k][i] ? d[3]+1 : 0;
g[i][j] = g[i][j] < d[0] ? g[i][j] : d[0];
g[i][k] = g[i][k] < d[1] ? g[i][k] : d[1];
g[j][i] = g[j][i] < d[2] ? g[j][i] : d[2];
g[k][i] = g[k][i] < d[3] ? g[k][i] : d[3];
}
}
for(auto t : g) {
res = max(res, *max_element(t.begin(), t.end()));
}
return res;
}
};
🔰🔰
(动态规划)790.多米诺和托米诺平铺
https://leetcode.cn/problems/domino-and-tromino-tiling/
>>题解
class Solution {
public:
int numTilings(int n) {
int f[1010];
int mod = 1e9+7;
memset(f, 0, sizeof(f));
f[1] = 1;
f[2] = 2;
f[3] = 5;
for(int i = 4; i <= n; ++i) {
f[i] = (2*f[i-1]%mod + f[i-3]%mod)%mod;
}
return f[n];
}
};
🔰🔰
6234.最小公倍数为 K 的子数组数目
https://leetcode.cn/problems/number-of-subarrays-with-lcm-equal-to-k/
class Solution {
public:
int gcd(int a,int b) {
return b ? gcd(b, a%b) : a;
}
int subarrayLCM(vector<int>& nums, int k) {
int n = nums.size();
int j;
int cnt = 0;
for(int i = 0; i < n; ++i) {
if(nums[i] == k) ++cnt;
j = i+1;
int tmp_num = nums[i];//当前最小公倍数
while(j < n){
int g = gcd(tmp_num, nums[j]);
tmp_num = (tmp_num/g) * nums[j];
if(tmp_num == k){
++cnt;
}else if(tmp_num > k){
break;
}
++j;
}
}
return cnt;
}
};
🔰🔰🔰
(状态压缩 + 常规bfs)864.获取所有钥匙的最短路径
https://leetcode.cn/problems/shortest-path-to-get-all-keys/
是我最喜欢的走迷宫(^-^)V, 写起来就爽就完了
一道常规的BFS, 不用记录是否访问,
需要不断更新到当前坐标时的某种状态的最短路程
,
使用k位二进制数(k是钥匙的数量)记录钥匙的状态
, 即有无
class Solution {
public:
int dist[31][31][1<<6];
struct Room{
int x, y, st;
};
int shortestPathAllKeys(vector<string>& grid) {
int n = grid.size(), m = grid[0].size();
int knum = 0;//钥匙数
memset(dist, 0x3f, sizeof(dist));
queue<Room> q;
for(int i = 0; i < n; ++i)
for(int j = 0; j < m; ++j) {
if(grid[i][j] == '@') {;
q.push({i, j, 0});
dist[i][j][0] = 0;
}else if(grid[i][j] >= 'a' && grid[i][j] <= 'f') {
++knum;
}
}
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
int onePiece = (1 << knum) - 1; //目标状态
while(q.size()) { //bfs
auto t = q.front();
q.pop();
int d = dist[t.x][t.y][t.st];
for(int i = 0; i < 4; ++i) {
int nx = t.x + dx[i], ny = t.y + dy[i], ns = t.st;
if(nx < 0 || nx >= n || ny < 0 || ny >= m || grid[nx][ny] == '#')
continue;
char ch = grid[nx][ny];
//钥匙
if(ch >= 'a' && ch <= 'f') {
ns |= 1 << (ch - 'a');
if(ns == onePiece) return d + 1; //集齐所有钥匙, 且路程最短
if(dist[nx][ny][ns] > d + 1) {
q.push({nx, ny, ns});
dist[nx][ny][ns] = d + 1;
}
}
//锁
else if(ch >= 'A' && ch <= 'F') {
if(ns & (1 << ch - 'A')) { //有当前锁的钥匙
if(dist[nx][ny][ns] > d + 1) {
q.push({nx, ny, ns});
dist[nx][ny][ns] = d + 1;
}
}
}
else {
if(dist[nx][ny][ns] > d + 1) {
q.push({nx, ny, ns});
dist[nx][ny][ns] = d + 1;
}
}
}
}
return -1;
}
};
即
class Solution {
public:
int dist[31][31][1<<6];
struct Room{
int x, y, st;
};
int shortestPathAllKeys(vector<string>& grid) {
int n = grid.size(), m = grid[0].size();
int knum = 0;//钥匙数
memset(dist, 0x3f, sizeof(dist));
queue<Room> q;
for(int i = 0; i < n; ++i)
for(int j = 0; j < m; ++j) {
if(grid[i][j] == '@') {;
q.push({i, j, 0});
dist[i][j][0] = 0;
}else if(grid[i][j] >= 'a' && grid[i][j] <= 'f') {
++knum;
}
}
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
int onePiece = (1 << knum) - 1; //目标状态
while(q.size()) { //bfs
auto t = q.front();
q.pop();
int d = dist[t.x][t.y][t.st];
for(int i = 0; i < 4; ++i) {
int nx = t.x + dx[i], ny = t.y + dy[i], ns = t.st;
if(nx < 0 || nx >= n || ny < 0 || ny >= m || grid[nx][ny] == '#')
continue;
char ch = grid[nx][ny];
//钥匙
if(ch >= 'a' && ch <= 'f') {
ns |= 1 << (ch - 'a');
if(ns == onePiece) return d + 1; //集齐所有钥匙, 且路程最短
}
//锁
else if(ch >= 'A' && ch <= 'F') {
if(!(ns & (1 << ch - 'A'))) continue;
}
if(dist[nx][ny][ns] > d + 1) {
q.push({nx, ny, ns});
dist[nx][ny][ns] = d + 1;
}
}
}
return -1;
}
};
🔰🔰
791.自定义字符串排序
https://leetcode.cn/problems/custom-sort-string/
typedef pair<int, char> PII;
class Solution {
public:
string customSortString(string order, string s) {
int n = order.size(), m = s.size();
vector<PII> vSite;
map<char, int> mp;
for(int i = 0; i < n; ++i){
mp[order[i]] = i;
}
string res;
for(int i = 0; i < m; ++i){
if(!mp[s[i]]) res += s[i];
else vSite.push_back({mp[s[i]], s[i]});
}
sort(vSite.begin(), vSite.end());
for(auto [a, b] : vSite) res += b;
return res;
}
};
💤🔰🔰
647.回文子串
https://leetcode.cn/problems/palindromic-substrings/
💤🔰🔰🔰
6236.不重叠回文子字符串的最大数目
https://leetcode.cn/problems/maximum-number-of-non-overlapping-palindrome-substrings/
🔰🔰🔰
805.数组的均值分割
https://leetcode.cn/problems/split-array-with-same-average/
枚举二进制状态, 超时
class Solution {
public:
bool splitArraySameAverage(vector<int>& nums) {
int n = nums.size();
int S = 0, r = (1 << n) - 1;
for(int i = 0; i < n; ++i) S += nums[i];
for(int i = 1; i < r; ++i) { //枚举状态
int n1 = 0, S1 = 0;
for(int j = 0; j < n; ++j) {
if((i >> j) & 1) {
++n1;
S1 += nums[j];
}
}
if(n1*S == n*S1) return true;
}
return false;
}
};
折半搜索 / 动态规划 进行优化
折半搜索
class Solution {
public:
bool splitArraySameAverage(vector<int>& nums) {
int n = nums.size();
if(n == 1) return false;
int sr = 0, s = 0, mid = n>>1;
for(int x : nums) s += x;
for(int &x : nums) x = x * n - s;
for(int i = mid; i < n; ++i) sr += nums[i];
unordered_set<int> left;
for(int i = 1; i < (1<<mid); ++i) { //枚举状态
int s1 = 0;
for(int j = 0; j < mid; ++j)
if((i >> j) & 1)
s1 += nums[j];
if(s1 == 0) return true;
left.emplace(s1);
}
for(int i = 1; i < (1<<(n-mid)); ++i) {
int s2 = 0;
for(int j = 0; j < n-mid; ++j)
if((i >> j) & 1)
s2 += nums[j+mid];
if(s2 == 0 || (s2 != sr && left.count(-s2)))
return true;
}
return false;
}
};
💤动态规划
STL accumulate使用说明
STL unorderedset emplace / find 的用法
🔰
1710.卡车上的最大单元数
https://leetcode.cn/problems/maximum-units-on-a-truck/
简单模拟
class Solution {
public:
int maximumUnits(vector<vector<int>>& boxTypes, int truckSize) {
int n = boxTypes.size();
sort(boxTypes.begin(), boxTypes.end(),
[&](const vector<int>& a, const vector<int>& b){
return a[1] > b[1];
});
int i = 0, s = 0;
while(i < n){
int _min = min(boxTypes[i][0], truckSize);
s += _min*boxTypes[i][1];
truckSize -= _min;
if(truckSize == 0) return s;
++i;
}
return s;
}
};
🔰🔰
792. 匹配子序列的单词数
https://leetcode.cn/problems/number-of-matching-subsequences/submissions/
class Solution {
public:
int numMatchingSubseq(string s, vector<string>& words) {
vector<queue<string>> str(26);
int n = s.size(), m = words.size();
for(int i = 0; i < m; ++i) str[words[i][0]-'a'].emplace(words[i]);
int ans = 0;
for(int i = 0; i < n; ++i) {
queue<string>& q = str[s[i]-'a'];
for(int j = q.size(); j; --j) {
string t = q.front();
q.pop();
if(t.size() == 1) ++ans;
else str[t[1]-'a'].emplace(t.substr(1));
}
}
return ans;
}
};
🔰🔰🔰
891.子序列宽度之和
https://leetcode.cn/problems/sum-of-subsequence-widths/
0x3f 的题解
class Solution {
public:
const int MOD = 1e9+7;
int sumSubseqWidths(vector<int>& nums) {
int n = nums.size();
long long res = 0L, a[n];
sort(nums.begin(), nums.end());
a[0] = 1;
for(int i = 1; i < n; ++i){
a[i] = (a[i-1]*2)%MOD;
}
for(int i = 0; i < n; ++i) {
res += (a[i] - a[n-1-i]) * nums[i] % MOD;
}
return (res%MOD+MOD)%MOD;
}
// long long pow(int x, int n){
// long long res = 1L;
// while(n)
// {
// if(n & 1) res = (res*x)%MOD;
// x = (x*x)%MOD;
// n >>= 1;
// }
// return res;
// }
};
🔰🔰
799.香槟塔
https://leetcode.cn/problems/champagne-tower/
class Solution {
public:
double champagneTower(int v, int n, int m) {
double h[110][110];
memset(h, 0, sizeof(h));
h[0][0] = v;
for(int i = 0; i <= n; ++i) {
for(int j = 0; j <= i; ++j) {
if(h[i][j] < 1) continue;
h[i+1][j] += (h[i][j] - 1)/2;
h[i+1][j+1] += (h[i][j] - 1)/2;
}
}
return h[n][m] < 1 ? h[n][m] : 1;
}
};
🔰🔰
6242.二叉搜索树最近节点查询
https://leetcode.cn/problems/closest-nodes-queries-in-a-binary-search-tree/
先得到中序遍历的序列, 再二分
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
void mid_build(TreeNode* root, vector<int>& a) {
if(!root) return ;
mid_build(root->left, a);
a.push_back(root->val);
mid_build(root->right, a);
}
// 大于等于当前数的最小值
int find_left(vector<int>& a, int l, int r, int x) {
int ll = l, rr = r;
while(ll < rr) {
int mid = (ll + rr) >> 1;
if(x <= a[mid]) rr = mid;
else ll = mid + 1;
}
return a[ll] >= x ? a[ll] : -1;
}
// 小于等于当前数的最大值
int find_right(vector<int>& a, int l, int r, int x) {
int ll = l, rr = r;
while(ll < rr) {
int mid = (ll + rr + 1) >> 1;
if(x < a[mid]) rr = mid - 1;
else ll = mid;
}
return a[rr] <= x ? a[rr] : -1;
}
vector<vector<int>> closestNodes(TreeNode* root, vector<int>& queries) {
vector<int> a;
mid_build(root, a);
vector<vector<int>> res;
for(auto x : queries) {
int l = find_left(a, 0, a.size()-1, x);
int r = find_right(a, 0, a.size()-1, x);
res.push_back({r, l});
}
return res;
}
};
本文来自博客园,作者:泥烟,CSDN同名, 转载请注明原文链接:https://www.cnblogs.com/Knight02/p/leetcode-2022-11.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET10 - 预览版1新功能体验(一)
2021-11-20 [OpenGL学习笔记] 初学图形渲染管线
2021-11-20 AcWing第26场周赛 4077. k显性字符
2021-11-20 [OpenGL学习笔记] 窗口的创建&简单响应, 双缓冲的机理
2021-11-20 [OpenGL学习笔记] 初识,环境配置
2020-11-20 【转载】关于int main( int argc, char* argv[] ) 中arg和argv参数的解析及调试
2020-11-20 枚举