[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;
}
}