首先祝大家兔年快乐!今年工作一切顺利
6296. Alternating Digit Sum
给你一个正整数 n 。n 中的每一位数字都会按下述规则分配一个符号:
- 最高有效位 上的数字分配到 正 号。
- 剩余每位上数字的符号都与其相邻数字相反。
返回所有数字及其对应符号的和。测试样例
输入:n = 521
输出:4
解释:
(+5) + (-2) + (+1) = 4
解答:按照题意编码计算即可
class Solution {
public int alternateDigitSum(int n) {
String num = String.valueOf(n);
int res = 0;
for (int i = 0; i < num.length(); ++i) {
int tmp = num.charAt(i) - '0';
if (i % 2 == 0) {
res += tmp;
} else {
res -= tmp;
}
}
return res;
}
}
6297. Sort the Students by Their Kth Score
班里有 m 位学生,共计划组织 n 场考试。给你一个下标从 0 开始、大小为 m x n 的整数矩阵 score ,其中每一行对应一位学生,而 score[i][j] 表示第 i 位学生在第 j 场考试取得的分数。矩阵 score 包含的整数 互不相同 。
另给你一个整数 k 。请你按第 k 场考试分数从高到低完成对这些学生(矩阵中的行)的排序。
返回排序后的矩阵。
测试样例:
输入:score = [[10,6,9,1],[7,5,11,2],[4,8,3,15]], k = 2
输出:[[7,5,11,2],[10,6,9,1],[4,8,3,15]]
解答: 经典排序题。Java可以偷懒使用Arrays.sort
class Solution {
public int[][] sortTheStudents(int[][] score, int k) {
Arrays.sort(score, (a, b) -> (b[k] - a[k]));
return score;
}
}
6298. Apply Bitwise Operations to Make Strings Equal
给你两个下标从 0 开始的 二元 字符串 s 和 target ,两个字符串的长度均为 n 。你可以对 s 执行下述操作 任意 次:
- 选择两个 不同 的下标 i 和 j ,其中 0 <= i, j < n 。
- 同时,将 s[i] 替换为 (s[i] OR s[j]) ,s[j] 替换为 (s[i] XOR s[j]) 。
例如,如果 s = "0110" ,你可以选择 i = 0 和 j = 2,然后同时将 s[0] 替换为 (s[0] OR s[2] = 0 OR 1 = 1),并将 s[2] 替换为 (s[0] XOR s[2] = 0 XOR 1 = 1),最终得到 s = "1110" 。如果可以使 s 等于 target ,返回 true ,否则,返回 false 。
测试样例
输入:s = "1010", target = "0110"
输出:true
解答:这题需要一点思考。对于s和target,每一位的可能只有4种,即
- s[i] = 0, t[i] = 0
- s[i] = 1, t[i] = 1
- s[i] = 1, t[i] = 0
- s[i] = 0, t[i] = 1
根据位运算的性质。如果第2种情况出现,则任意位都能按照要求形成一致数组。如果第3或者第四种情况同时出现。则通过一次计算,能使得第2种情况出现(大家可以自己用XOR和OR的位运算计算一下,为什么这样是可以计算的)。如果所有位都是第1和第2种情况,则s和t已经相同。
class Solution {
public boolean makeStringsEqual(String s, String target) {
int[] count = new int[4];
int len = s.length();
for (int i = 0; i < len; ++i) {
int n = (s.charAt(i) - '0') * 2 + (target.charAt(i) - '0');
count[n] += 1;
}
if (count[0] + count[3] == len) {
return true;
} else if (count[3] != 0) {
return true;
} else if (count[1] > 0 && count[2] > 0) {
return true;
}
return false;
}
}
6299. Minimum Cost to Split an Array
给你一个整数数组 nums 和一个整数 k 。
将数组拆分成一些非空子数组。拆分的 代价 是每个子数组中的 重要性 之和。
令 trimmed(subarray) 作为子数组的一个特征,其中所有仅出现一次的数字将会被移除。
- 例如,trimmed([3,1,2,4,3,4]) = [3,4,3,4] 。
子数组的 重要性 定义为 k + trimmed(subarray).length 。
- 例如,如果一个子数组是 [1,2,3,3,3,4,4] ,trimmed([1,2,3,3,3,4,4]) = [3,3,3,4,4] 。这个子数组的重要性就是 k + 5 。
找出并返回拆分 nums 的所有可行方案中的最小代价。子数组 是数组的一个连续 非空 元素序列。
测试样例
输入:nums = [1,2,1,2,1,3,3], k = 2
输出:8
解答:这题很明显的存在无后效应。如果在某一个位置截断,则之前的截断方案不会影响之后的阶段最小值。所以可以利用动态规划计算。
class Solution {
private Integer[] dp;
private int[] nums;
private int k;
public int minCost(int[] _nums, int _k) {
dp = new Integer[_nums.length];
nums = _nums;
k = _k;
return helper(0);
}
private int helper(int pos) {
if (pos >= nums.length) {
return 0;
}
if (dp[pos] == null) {
dp[pos] = Integer.MAX_VALUE;
HashMap<Integer, Integer> map = new HashMap<>();
int len = 0;
for (int i = pos; i < nums.length; ++i) {
int n = nums[i];
int o = map.getOrDefault(n, 0);
if (o == 1) {
len += 2;
} else if (o > 1) {
len += 1;
}
map.put(n, o + 1);
dp[pos] = Math.min(dp[pos], helper(i + 1) + k + len);
}
}
return dp[pos];
}
}