LeetCode 第 154 场周赛 【“气球” 的最大数量】【一周中的第几天】【K 次串联后最大子数组之和】

5189. “气球” 的最大数量

给你一个字符串 text,你需要使用 text 中的字母来拼凑尽可能多的单词 “balloon”(气球)。

字符串 text 中的每个字母最多只能被使用一次。请你返回最多可以拼凑出多少个单词 “balloon”。

示例 1:

输入:text = "nlaebolko"
输出:1

示例 2:

输入:text = "loonbalxballpoon"
输出:2

示例 3:

输入:text = "leetcode"
输出:0

代码:

public int maxNumberOfBalloons(String text) {
        HashMap<Character, Integer> map = new HashMap<>();
        // balloon
        map.put('b', 0);
        map.put('a', 0);
        map.put('l', 0);
        map.put('o', 0);
        map.put('n', 0);
        for (int i = 0; i < text.length(); i++) {
            char key = text.charAt(i);
            if (map.containsKey(key)) {
                map.put(key, map.get(key) + 1);
            }
        }
        int max = Integer.MAX_VALUE;
        Iterator<Character> iterator = map.keySet().iterator();
        while (iterator.hasNext()) {
            char key = iterator.next();
            if (map.get(key) == 0) {
                max = 0;
                break;
            }
            if (key == 'l' || key == 'o') {
                if (map.get(key) == 1) {
                max = 0;
                break;
                }
                max = Math.min(max, map.get(key) / 2);
            } else {
                max = Math.min(max, map.get(key));
            }
        }
        return max;
    }

5190. 反转每对括号间的子串

给出一个字符串 s(仅含有小写英文字母和括号)。

请你按照从括号内到外的顺序,逐层反转每对匹配括号中的字符串,并返回最终的结果。

注意,您的结果中 不应 包含任何括号。

示例 1:

输入:s = "(abcd)"
输出:"dcba"

示例 2:

输入:s = "(u(love)i)"
输出:"iloveu"

示例 3:

输入:s = "(ed(et(oc))el)"
输出:"leetcode"

示例 4:

输入:s = "a(bcdefghijkl(mno)p)q"
输出:"apmnolkjihgfedcbq"

思路:使用栈,依次压栈,遇到右括号时,将栈里面的元素取出,直至遇到左括号,然后反转之后继续入栈。s = “((” + s + “))”:解决刚开始没在括号里面的字符,不需要反转,只用拼接,所以加了两对括号,让他反转两次,拼接。
代码:

public static String reverseParentheses(String s) {
        // 解决"a(bcdefghijkl(mno)p)q"这种情况,翻转两次仍然是原来的
        s = "((" + s + "))";
        Stack<String> stack = new Stack<>();
        for (char c : s.toCharArray()) {
            if (c == ')') {
                String now = "";
                while (!stack.isEmpty() && !stack.peek().equals("(")) {
                    String t = stack.pop();
                    now =  t + now;
                }
                stack.pop(); // 将"("弹出
                StringBuilder sb = new StringBuilder(now);
                System.out.println("now:" + now);
                stack.push(sb.reverse().toString());
            } else {
                stack.push(String.valueOf(c));
            }
        }
        return stack.peek();
    }

5191. K 次串联后最大子数组之和

给你一个整数数组 arr 和一个整数 k。

首先,我们要对该数组进行修改,即把原数组 arr 重复 k 次。

  • 举个例子,如果 arr = [1, 2] 且 k = 3,那么修改后的数组就是 [1, 2, 1, 2, 1, 2]。

然后,请你返回修改后的数组中的最大的子数组之和。

注意,子数组长度可以是 0,在这种情况下它的总和也是 0。

由于 结果可能会很大,所以需要 模(mod) 10^9 + 7 后再返回。
示例 1:

输入:arr = [1,2], k = 3
输出:9

示例 2:

输入:arr = [1,-2,1], k = 5
输出:2

示例 3:

输入:arr = [-1,-2], k = 7
输出:0

思路:尝试多种情况
代码:

	public static int MOD = (int) (1e9 + 7); // 1000000007
    public static int kConcatenationMaxSum(int[] arr, int k) {
        long sum = 0;
        int len = arr.length;
        for (int t : arr) {
            sum += t;
        }
        int leftMax = 0;
        int rightMax = 0;
        long ans = 0;
        // 统计固定左端点,从左往右最大和
        for (int i = 0, cur = 0; i < len; i++) {
            cur += arr[i];
            leftMax = Math.max(leftMax, cur);
        }
        // 统计固定右端点,从右往左最大和
        for (int i = len - 1, cur = 0; i >= 0; i--) {
            cur += arr[i];
            rightMax = Math.max(rightMax, cur);
        }
        // 最大的子数组
        for (int i = 0, cur = 0; i < len; i++) {
            cur += arr[i];
            if (cur < 0) {
                cur = 0;
            }
            ans = Math.max(ans, cur);
        }
        System.out.println("ans:" + ans + " leftMax:" + leftMax + " rightMax:" + rightMax + " sum:" + sum);
        if (k == 1) {
            return (int) ans % MOD;
        }
        // 1.取所有sum
        ans = Math.max(ans, sum * k);
        // 2.只拼接一边的最大和
        ans = Math.max(ans, Math.max(sum * (k - 1) + leftMax, sum * (k - 1) + rightMax));
        // 3.拼接左右最大和
        ans = Math.max(ans, sum * (k - 2) + leftMax + rightMax);
        // 4.sum<0
        ans = Math.max(ans, leftMax + rightMax);
        ans = ans % MOD;
        return (int) ans;
    }

你可能感兴趣的:(LeetCode周赛)