首先祝大家兔年快乐!今年工作一切顺利

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种,即

  1. s[i] = 0, t[i] = 0
  2. s[i] = 1, t[i] = 1
  3. s[i] = 1, t[i] = 0
  4. 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];
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *