上岸算法 I LeetCode Weekly Contest 225解题报告

本文解析了四道编程题目,包括替换隐藏数字得到最晚时间、满足特定条件需改变的最少字符数、找出第K大的异或坐标值及放置盒子问题。通过具体的代码示例,展示了如何使用字符串操作、数组处理等技术解决问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

No.1 替换隐藏数字得到的最晚时间

解题思路

从左到右依次处理每个位置的 ? 即可 —— 替换为可能的最大值。

代码展示

class Solution {
    public String maximumTime(String time) {
        char[] chars = time.toCharArray();
        if (chars[0] == '?') {
            chars[0] = chars[1] != '?' && chars[1] > '3' ? '1' : '2';
        }
        if (chars[1] == '?') {
            chars[1] = chars[0] == '2' ? '3' : '9';
        }
        if (chars[3] == '?') {
            chars[3] = '5';
        }
        if (chars[4] == '?') {
            chars[4] = '9';
        }
        return new String(chars);
    }
}

No.2 满足三条件之一需改变的最少字符数

解题思路

3 种条件、26 个分界点,枚举这 3 x 26 种情况即可。

代码展示

class Solution {
    public int minCharacters(String a, String b) {
        int[] cntA = count(a); // cntA[c - 'a'] 表示 a 中 c 出现的次数
        int[] cntB = count(b);
        int res = Integer.MAX_VALUE;for (char c = 'a'; c <= 'z'; c++) {
            // a, b 都为字符 c
            res = Math.min(res, a.length() + b.length() - cntA[c - 'a'] - cntB[c - 'a']);
            if (cntB[25] == 0) {
                // a > b 且 b 中所有字符不大于 c
                res = Math.min(res, calc(cntA, cntB, c));
            }
            if (cntA[25] == 0) { 
                // a < b 且 a 中所有字符不大于 c
                res = Math.min(res, calc(cntB, cntA, c));
            }
        }

        return res;
    }

    private int calc(int[] cntA, int[] cntB, char c) {
        int res = 0;
        for (char c2 = 'a'; c2 <= c; c2++) {
            res += cntA[c2 - 'a'];
        }
        for (char c2 = (char) (c + 1); c2 <= 'z'; c2++) {
            res += cntB[c2 - 'a'];
        }
        return res;
    }

    private int[] count(String s) {
        int[] cnt = new int[26];
        for (char c : s.toCharArray()) {
            cnt[c - 'a']++;
        }
        return cnt;
    }
}

No.3 找出第K大的异或坐标值

解题思路

前缀和。计算出每个坐标的异或值,然后取第 K 大即可。

代码展示

class Solution {
    public int kthLargestValue(int[][] matrix, int k) {
        int n = matrix.length;
        int m = matrix[0].length;
        int[][] rowPrefix = new int[n][m]; // 每一行的前缀异或和
        for (int i = 0; i < n; i++) {
            rowPrefix[i][0] = matrix[i][0];
            for (int j = 1; j < m; j++) {
                rowPrefix[i][j] = rowPrefix[i][j - 1] ^ matrix[i][j];
            }
        }

        List<Integer> list = new ArrayList<>();
        // 利用 rowPrefix 计算出每个坐标的值
        for (int j = 0; j < m; j++) {
            int xor = rowPrefix[0][j];
            list.add(xor);
            for (int i = 1; i < n; i++) {
                xor ^= rowPrefix[i][j];
                list.add(xor);
            }
        }
        Collections.sort(list);
        return list.get(list.size() - k);
    }
}

No.4 放置盒子

解题思路

最优策略就是尽可能利用墙角,然后堆得尽可能高。按照如下顺序放置方块即可:

放 1 个 (0, 0, 0) 高 1,底 1,总 1 (样例一)
放 1 个 (1, 0, 0)底 2,总 2
放 2 个 (0, 1, 0)(0, 0, 1) 高 2,底 3,总 4 (样例二)
放 1 个 (2, 0, 0)底 4,总 5
放 2 个 (2, 1, 0)(2, 0, 1)底 5,总 7
放 3 个 (2, 2, 0)(2, 1, 1)(2, 0, 0)底 6,总 10 (样例三)

从 0 开始,底部每增加一个,放置的方块总数就会增加 1, 1, 1, 2, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4, 5 … 个。

代码展示

class Solution {
    public int minimumBoxes(int n) {
        int sum = 1;
        int level = 1;
        int bottom = 1;
        while (sum < n) {
            for (int i = 0; i <= level && sum < n; i++) {
                bottom++;
                sum += i + 1;
            }
            level += 1;
        }
        return bottom;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值