[Leetcode Weekly Contest]288

链接:LeetCode

[Leetcode]2231. 按奇偶性交换后的最大数字

给你一个正整数 num 。你可以交换 num 中 奇偶性 相同的任意两位数字(即,都是奇数或者偶数)。
返回交换 任意 次之后 num 的 最大 可能值。

遍历即可。

class Solution {
    public int largestInteger(int num) {
        List<Character> even = new ArrayList<>();
        List<Character> odd = new ArrayList<>();
        char[] numChars = String.valueOf(num).toCharArray();
        for(var ch: numChars) {
            if(((int)(ch-'0') & 1) != 0)  odd.add(ch);
            else even.add(ch);
        }
        even.sort((a,b) -> b-a);
        odd.sort((a,b) -> b-a);
        int res = 0;
        int even_ind = 0, odd_ind = 0;
        for(var ch: numChars) {
            if(((int)(ch-'0') & 1) != 0) {
                res = res * 10 + (int)(odd.get(odd_ind)-'0');
                odd_ind ++;
            }
            else {
                res = res * 10 + (int)(even.get(even_ind)-'0');
                even_ind ++;
            }
        }
        return res;
    }
}

[Leetcode]2232. 向表达式添加括号后的最小结果

给你一个下标从 0 开始的字符串 expression ,格式为 \("<num1>+<num2>"\) ,其中 \(<num1>\)\(<num2>\) 表示正整数。

请你向 expression 中添加一对括号,使得在添加之后, expression 仍然是一个有效的数学表达式,并且计算后可以得到 最小 可能值。左括号 必须 添加在 '+' 的左侧,而右括号必须添加在 '+' 的右侧。
返回添加一对括号后形成的表达式 expression ,且满足 expression 计算得到 最小 可能值。如果存在多个答案都能产生相同结果,返回任意一个答案。
生成的输入满足:expression 的原始值和添加满足要求的任一对括号之后 expression 的值,都符合 32-bit 带符号整数范围。

遍历左括号和右括号的位置即可。

class Solution {
    public String minimizeResult(String expression) {
        int add_idx = -1;
        for(int i=0;i<expression.length();++i) {
            if(expression.charAt(i) == '+') add_idx =i;
        }
        String res = expression;
        int min_value = Integer.MAX_VALUE;
        for(int left = 0;left<add_idx; ++left){
            for(int right = add_idx+1; right<expression.length(); ++right) {
                if(getResult(expression, add_idx, left, right) <  min_value) {
                    min_value = getResult(expression, add_idx, left, right);
                    res = insertToString(expression, left, right);
                }
            }
        }
        return res;
    }

    public String insertToString(String expression, int left, int right) {
        StringBuilder sb = new StringBuilder();
        for(int i = 0;i<expression.length();++i) {
            if(i==left) sb.append('(');
            sb.append(expression.charAt(i));
            if(i == right) sb.append(')');
        }
        return sb.toString();
    }

    public int getResult(String expression, int add_idx, int left, int right) {
        int res = 0;
        int left_value = 1, right_value = 1;
        if(left!=0) left_value = getValue(expression, 0, left-1);
        int mid_value = getValue(expression, left, add_idx-1) + getValue(expression, add_idx+1, right);
        if(right!=expression.length()-1) right_value = getValue(expression, right+1, expression.length()-1);
        return left_value * mid_value * right_value;
    }

    public int getValue(String expression, int start, int end) {
        int res = 0;
        for(int ind = start;ind <= end; ind++) {
            res = res * 10 + (int)(expression.charAt(ind)-'0');
        }
        return res;
    }
}

[Leetcode]2233. K 次增加后的最大乘积

给你一个非负整数数组 nums 和一个整数 k 。每次操作,你可以选择 nums 中 任一 元素并将它 增加 1 。
请你返回 至多 k 次操作后,能得到的 nums的 最大乘积 。由于答案可能很大,请你将答案对 109 + 7 取余后返回。

class Solution {
    public int maximumProduct(int[] nums, int k) {
        Queue<Integer> queue=new PriorityQueue<>((o1,o2)->o1-o2);
        for(int num:nums){
            queue.add(num);
        }
        while(k>0){
            Integer peek = queue.poll();
            queue.add(peek+1);
            k --;
        }
        long ans=1;
        while(!queue.isEmpty()){
            Integer peek = queue.poll();
            ans=(ans*peek)%1000000007L;
        }
        return (int)ans;
    }
}

[Leetcode]2234. 花园的最大总美丽值

Alice 是 n 个花园的园丁,她想通过种花,最大化她所有花园的总美丽值。
给你一个下标从 0 开始大小为 n 的整数数组 flowers ,其中 flowers[i] 是第 i 个花园里已经种的花的数目。已经种了的花 不能 移走。同时给你 newFlowers ,表示 Alice 额外可以种花的 最大数目 。同时给你的还有整数 target ,full 和 partial 。
如果一个花园有 至少 target 朵花,那么这个花园称为 完善的 ,花园的 总美丽值 为以下分数之 和 :

  • 完善 花园数目乘以 full.
  • 剩余 不完善 花园里,花的 最少数目 乘以 partial 。如果没有不完善花园,那么这一部分的值为 0 。

请你返回 Alice 种最多 newFlowers 朵花以后,能得到的 最大 总美丽值。

容易想到, 我们可以枚举完善花园数目,来求最大总美丽值。
首先明确 , newFlowers 是不需要用完的 , 所以如果我们要对 x 个花坛进行完善 , 我们选择最多花朵的花坛进行完善一定是最优的 (此时消耗的 newFlowers 最少)。那么在剩下的 n - x 个 不完善 的花坛我们二分最后的 最小值 使其最大 即可。

难点在于,我们在 二分中需要用 前缀和 + 二分 再一步优化。

class Solution {
    public long maximumBeauty(int[] flowers, long newFlowers, int target, int full, int partial) {
        long res = 0;
        int n = flowers.length;
        List<Integer> UpperBounderflowers = new ArrayList<>();
        for(int flower: flowers) UpperBounderflowers.add(Math.min(flower, target));
        UpperBounderflowers.sort((o1,o2)->o2-o1);
        long[] perfixSum = new long[n];
        long cur = 0;
        int idx = 0;
        for(int flower: UpperBounderflowers) {
            cur += flower;
            perfixSum[idx] = cur;
            idx ++;
        }

        for(int perfect_count=0;perfect_count<=flowers.length;perfect_count++) {
            long perfect_garden_flowers_need = 0;
            if(perfect_count >0) perfect_garden_flowers_need = (long)target * perfect_count - perfixSum[perfect_count-1];
            if(perfect_count < flowers.length && UpperBounderflowers.get(perfect_count) >= target) continue;
            if(perfect_garden_flowers_need > newFlowers) break;
            if(perfect_count == flowers.length) {
                res = Math.max(res, (long)full * perfect_count);
                break;
            }
            long rest_flowers = newFlowers - perfect_garden_flowers_need;
            int min_partial_flowers = getPartialCount(UpperBounderflowers, perfect_count, rest_flowers, target, perfixSum);
            res = Math.max(res, (long)perfect_count * full + (long)min_partial_flowers * partial);
        }
        return res;
    }

    public int getPartialCount(List<Integer> UpperBounderflowers, int perfect_count, long rest_flowers, int target, long[] perfixSum) {
        int lo = 0, hi = target -1 ;
        while(lo <= hi) {
            int mid = lo + (hi-lo)/2;
            if(isValid(UpperBounderflowers, perfect_count, rest_flowers, mid, perfixSum)) {
                lo = mid + 1;
            }
            else hi = mid - 1;
        }
        return hi;
    }

    public boolean isValid(List<Integer> UpperBounderflowers, int perfect_count, long rest_flowers, int target, long[] perfixSum) {
        int idx = Math.max(getFirstSmallerIdx(UpperBounderflowers, target), perfect_count);
        long need = 0;
        if(idx == UpperBounderflowers.size()) return true;
        if(idx == 0) need = (long)target * UpperBounderflowers.size() - perfixSum[UpperBounderflowers.size()-1];
        else need = (long)target * (UpperBounderflowers.size()-idx) - (perfixSum[UpperBounderflowers.size()-1] - perfixSum[idx-1]);
        if(need > rest_flowers) return false;
        return true;
    }

    public int getFirstSmallerIdx(List<Integer> nums, int target) {
        int lo = 0, hi = nums.size()-1;
        while(lo<=hi) {
            int mid = lo+(hi-lo)/2;
            if(nums.get(mid) < target) hi = mid-1;
            else lo = mid+1;
        }
        return lo;
    }
}
posted @ 2022-05-31 20:33  Jamest  阅读(26)  评论(0编辑  收藏  举报