本文主要是介绍leetcode 2055.蜡烛之间的盘子(js),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目
给你一个长桌子,桌子上盘子和蜡烛排成一列。给你一个下标从 0 开始的字符串 s ,它只包含字符 ‘*’ 和 ‘|’ ,其中 ‘*’ 表示一个 盘子 ,’|’ 表示一支 蜡烛 。
同时给你一个下标从 0 开始的二维整数数组 queries ,其中 queries[i] = [lefti, righti] 表示子字符串 s[lefti…righti] (包含左右端点的字符)。对于每个查询,你需要找到 子字符串中 在 两支蜡烛之间 的盘子的 数目 。如果一个盘子在 子字符串中 左边和右边 都 至少有一支蜡烛,那么这个盘子满足在 两支蜡烛之间 。
比方说,s = “||*||*|*” ,查询 [3, 8] ,表示的是子字符串 “*||**|” 。子字符串中在两支蜡烛之间的盘子数目为 2 ,子字符串中右边两个盘子在它们左边和右边 都 至少有一支蜡烛。
请你返回一个整数数组 answer ,其中 answer[i] 是第 i 个查询的答案。
示例 1:
输入:s = "**|**|***|", queries = [[2,5],[5,9]]
输出:[2,3]
解释:queries[0] 有两个盘子在蜡烛之间。queries[1] 有三个盘子在蜡烛之间。
示例 2:
输入:s = "***|**|*****|**||**|*", queries = [[1,17],[4,5],[14,17],[5,11],[15,16]]
输出:[9,0,0,0,0]
解释:queries[0] 有 9 个盘子在蜡烛之间。另一个查询没有盘子在蜡烛之间。
提示:
3 <= s.length <= 105
s 只包含字符 '*' 和 '|' 。
1 <= queries.length <= 105
queries[i].length == 2
0 <= lefti <= righti < s.length
解题
1.博主垃圾代码(超时)
本来想的是两个循环,第一个循环queries数组,拿到要截取的那段字符,第二个循环再算盘子的数量。
第二个盘子循环的算法是:遇到了第一个蜡烛,开关就打开,然后开始记盘子数目,每次遇到 ‘|’ 并且前面一个是 ‘*’ 就赋值一次总数sum。
能完成题目要求,但是超时,改了很久看了答案才知道,原来只用一次循环就可以解决,下面是我的代码,双循环实现,但是超时。
var platesBetweenCandles = function (s, queries) {let ans = new Array(queries.length)for (let i = 0; i < queries.length; i++) {let plate = 0;let candle = 0;if (s[queries[i][0]] == '|') {candle = 1;}for (let j = queries[i][0]; j <= queries[i][1]; j++) {if (s[j] == '|' && s[j - 1] != '|') {candle = 1;sum = plate;} else if (candle && s[j] != '|') {plate++;}}ans[i] = sum;;}return ans;};
2.官方预处理前缀和方法
var platesBetweenCandles = function(s, queries) {const n = s.length;const preSum = new Array(n).fill(0);for (let i = 0, sum = 0; i < n; i++) {if (s[i] === '*') {sum++;}preSum[i] = sum;}const left = new Array(n).fill(0);;for (let i = 0, l = -1; i < n; i++) {if (s[i] === '|') {l = i;}left[i] = l;}const right = new Array(n).fill(0);;for (let i = n - 1, r = -1; i >= 0; i--) {if (s[i] === '|') {r = i;}right[i] = r;}const ans = new Array(queries.length).fill(0);for (let i = 0; i < queries.length; i++) {const query = queries[i];const x = right[query[0]], y = left[query[1]];ans[i] = x === -1 || y === -1 || x >= y ? 0 : preSum[y] - preSum[x];}return ans;
};
一共三个数组:
1.preSum 这个数组遍历了原字符串,数组中每个元素的值是之前所有索引的盘子数,例如preSum[10]就是第十个字符之前所有的盘子数。
2.left 这个数组的值是索引值向左数,最近的蜡烛的索引值。有点绕,相当于 || 一共10个字符,left[5]、left[7]…left[8]的值都是4 ,因为向左数第5个字符是最近的蜡烛。
3right 这个数组和left数组相似,得到索引值向右看,最近的蜡烛的索引值。
然后范围[x,y],y左边最近的蜡烛的索引值-x右边最近的蜡烛的索引值就是范围内所有蜡烛之间的盘子。
x === -1 || y === -1 || x >= y ? 0 : preSum[y] - preSum[x]
条件运算符中的判断分别为:范围内只有一个蜡烛和范围内没有蜡烛的情况。范围内没有蜡烛则x>y。
这篇关于leetcode 2055.蜡烛之间的盘子(js)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!