2055. 蜡烛之间的盘子
给你一个长桌子,桌子上盘子和蜡烛排成一列。给你一个下标从 0 开始的字符串 s ,它只包含字符 '' 和 '|' ,其中 '' 表示一个 盘子 ,'|' 表示一支 蜡烛 。
同时给你一个下标从 0 开始的二维整数数组 queries ,其中 queries[i] = [lefti, righti] 表示 子字符串 s[lefti...righti] (包含左右端点的字符)。对于每个查询,你需要找到 子字符串中 在 两支蜡烛之间 的盘子的 数目 。如果一个盘子在 子字符串中 左边和右边 都 至少有一支蜡烛,那么这个盘子满足在 两支蜡烛之间 。
比方说,s = "|||||" ,查询 [3, 8] ,表示的是子字符串 "||**|" 。子字符串中在两支蜡烛之间的盘子数目为 2 ,子字符串中右边两个盘子在它们左边和右边 都 至少有一支蜡烛。
请你返回一个整数数组 answer ,其中 answer[i] 是第 i 个查询的答案。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/plates-between-candles
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二分
class Solution {
private int getRegionSum(int[] num, int left, int right) {
if (left > right) {
return 0;
}
return left == 0 ? num[right] : num[right] - num[left - 1];
}
private int getMostLeft(int[] num, int target) {
int left = 0, right = num.length - 1;
int ans = left;
while (left <= right) {
int mid = (left + right) >> 1;
if (num[mid] >= target) {
ans = mid;
right = mid - 1;
} else {
left = mid + 1;
}
}
return ans;
}
public int[] platesBetweenCandles(String s, int[][] queries) {
if (queries == null || queries.length == 0) {
return new int[0];
}
int[] ans = new int[queries.length];
int[] cnt1 = new int[s.length()];
int[] cnt2 = new int[s.length()];
cnt1[0] = s.charAt(0) == '*' ? 1 : 0;
cnt2[0] = s.charAt(0) == '|' ? 1 : 0;
for (int i = 1; i < s.length(); ++i) {
cnt1[i] = cnt1[i - 1] + (s.charAt(i) == '*' ? 1 : 0);
cnt2[i] = cnt2[i - 1] + (s.charAt(i) == '|' ? 1 : 0);
}
for (int i = 0; i < queries.length; ++i) {
int num1 = getRegionSum(cnt2, 0, queries[i][0]);
int num2 = getRegionSum(cnt2, 0, queries[i][1]);
if (num1 != num2) {
int left = s.charAt(queries[i][0]) == '|' ? queries[i][0] : getMostLeft(cnt2, num1 + 1);
int right = s.charAt(queries[i][1]) == '|' ? queries[i][1] : getMostLeft(cnt2, num2);
ans[i] = getRegionSum(cnt1, left, right);
}
}
return ans;
}
}
预处理
class Solution {
private int getRegionSum(int[] num, int left, int right) {
if (left > right) {
return 0;
}
return left == 0 ? num[right] : num[right] - num[left - 1];
}
private int getMostLeft(int[] num, int target) {
int left = 0, right = num.length - 1;
int ans = left;
while (left <= right) {
int mid = (left + right) >> 1;
if (num[mid] >= target) {
ans = mid;
right = mid - 1;
} else {
left = mid + 1;
}
}
return ans;
}
public int[] platesBetweenCandles(String s, int[][] queries) {
if (queries == null || queries.length == 0) {
return new int[0];
}
int[] ans = new int[queries.length];
int[] left = new int[s.length()];
int[] right = new int[s.length()];
left[0] = s.charAt(0) == '|' ? 1 : -1;
right[s.length() - 1] = s.charAt(s.length() - 1) == '|' ? s.length() - 1 : s.length();
for (int i = 1; i < s.length(); ++i) {
left[i] = s.charAt(i) == '|' ? i : left[i - 1];
}
for (int i = s.length() - 2; i >= 0; --i) {
right[i] = s.charAt(i) == '|' ? i : right[i + 1];
}
int[] cnt = new int[s.length()];
cnt[0] = s.charAt(0) == '*' ? 1 : 0;
for (int i = 1; i < s.length(); ++i) {
cnt[i] = cnt[i - 1] + (s.charAt(i) == '*' ? 1 : 0);
}
for (int i = 0; i < queries.length; ++i) {
ans[i] = getRegionSum(cnt, right[queries[i][0]], left[queries[i][1]]);
}
return ans;
}
}
心之所向,素履以往 生如逆旅,一苇以航
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理