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;
    }
}
posted @   Tianyiya  阅读(39)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示