LeetCode 833. 字符串中的查找与替换

2235. 两整数相加

添加链接描述
给你两个整数 num1 和 num2,返回这两个整数的和。

示例 1:

输入:num1 = 12, num2 = 5
输出:17
解释:num1 是 12,num2 是 5 ,它们的和是 12 + 5 = 17 ,因此返回 17 。
示例 2:

输入:num1 = -10, num2 = 4
输出:-6
解释:num1 + num2 = -6 ,因此返回 -6 。

class Solution {
    // 不使用加法运算符
    public int sum(int num1, int num2) {
        while (num2 != 0) {
            int carry = (num1 & num2) << 1; // 进位
            num1 ^= num2; // 不进位的和
            num2 = carry;
        }
        return num1;
    }

    public int sum1(int num1, int num2) {
        return num1 + num2;   
    }
}

833. 字符串中的查找与替换

添加链接描述
你会得到一个字符串 s (索引从 0 开始),你必须对它执行 k 个替换操作。替换操作以三个长度均为 k 的并行数组给出:indices, sources, targets。

要完成第 i 个替换操作:

检查 子字符串 sources[i] 是否出现在 原字符串 s 的索引 indices[i] 处。
如果没有出现, 什么也不做 。
如果出现,则用 targets[i] 替换 该子字符串。
例如,如果 s = “abcd” , indices[i] = 0 , sources[i] = “ab”, targets[i] = “eee” ,那么替换的结果将是 “eeecd” 。

所有替换操作必须 同时 发生,这意味着替换操作不应该影响彼此的索引。测试用例保证元素间不会重叠 。

例如,一个 s = “abc” , indices = [0,1] , sources = [“ab”,“bc”] 的测试用例将不会生成,因为 “ab” 和 “bc” 替换重叠。
在对 s 执行所有替换操作后返回 结果字符串 。

子字符串 是字符串中连续的字符序列。

示例 1:

输入:s = “abcd”, indices = [0,2], sources = [“a”,“cd”], targets = [“eee”,“ffff”]
输出:“eeebffff”
解释:
“a” 从 s 中的索引 0 开始,所以它被替换为 “eee”。
“cd” 从 s 中的索引 2 开始,所以它被替换为 “ffff”。
示例 2:

输入:s = “abcd”, indices = [0,2], sources = [“ab”,“ec”], targets = [“eee”,“ffff”]
输出:“eeecd”
解释:
“ab” 从 s 中的索引 0 开始,所以它被替换为 “eee”。
“ec” 没有从原始的 S 中的索引 2 开始,所以它没有被替换。

class Solution {
    public String findReplaceString(String s, int[] indices, String[] sources, String[] targets) {
        int n = s.length();
        int[] replace = new int[n]; // 保存哪个位置需要替换
        Arrays.fill(replace, -1);
        for (int k = 0; k < indices.length; k++) {
            // startsWith 判断指定偏移量开头是否以指定字符串开头
            if (s.startsWith(sources[k], indices[k])) {
                replace[indices[k]] = k; // 记录需要替换的位置
            }
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < n;) {
            if (replace[i] >= 0) {
                stringBuilder.append(targets[replace[i]]); // 替换成 targets,位置是 replace[i]
                // i 替换成功,向后跳原来替换的字符串长度
                // a b c d e f
                // 替换 cd 为 ffff,a b ffff e f
                // 替换成功,i 下一个从 e 比较,而不是 d
                int index = replace[i];
                i += sources[index].length();
            } else {
                stringBuilder.append(s.charAt(i));
                i++;
            }
        }
        return stringBuilder.toString();
    }
}

1444. 切披萨的方案数

添加链接描述

给你一个 rows x cols 大小的矩形披萨和一个整数 k ,矩形包含两种字符: ‘A’ (表示苹果)和 ‘.’ (表示空白格子)。你需要切披萨 k-1 次,得到 k 块披萨并送给别人。

切披萨的每一刀,先要选择是向垂直还是水平方向切,再在矩形的边界上选一个切的位置,将披萨一分为二。如果垂直地切披萨,那么需要把左边的部分送给一个人,如果水平地切,那么需要把上面的部分送给一个人。在切完最后一刀后,需要把剩下来的一块送给最后一个人。

请你返回确保每一块披萨包含 至少 一个苹果的切披萨方案数。由于答案可能是个很大的数字,请你返回它对 10^9 + 7 取余的结果。

示例 1:

输入:pizza = [“A…”,“AAA”,“…”], k = 3
输出:3
解释:上图展示了三种切披萨的方案。注意每一块披萨都至少包含一个苹果。
示例 2:

输入:pizza = [“A…”,“AA.”,“…”], k = 3
输出:1
示例 3:

输入:pizza = [“A…”,“A…”,“…”], k = 1
输出:1

class Solution {
    public int ways(String[] pizza, int k) {
        int mod = 1_000_000_007;
        int rows = pizza.length;
        int cols = pizza[0].length();
        int[][] apples = new int[rows + 1][cols + 1];
        // 统计苹果分布数量
        for (int i = rows - 1; i >= 0; i--) {
            for (int j = cols - 1; j >= 0; j--) {
                apples[i][j] = apples[i][j + 1] + apples[i + 1][j] - apples[i + 1][j + 1] +
                        (pizza[i].charAt(j) == 'A' ? 1 : 0); // 容斥原理
            }
        }
        // 切披萨数
        // 从右下角开始
        // dp[i,j,k]的含义是披萨仅剩从坐标i,j开始的右下角部分,并且可以切k刀的方案数
        int[][][] dp = new int[rows + 1][cols + 1][k + 1];
        for (int kk = 1; kk <= k; kk++) {
            for (int i = 0; i < rows; i++) {
                for (int j = 0; j < cols; j++) {
                    if (kk == 1) {
                        if (apples[i][j] > 0) {
                            dp[i][j][kk] = 1;
                        }
                    } else {
                        // 水平方向切
                        for (int ii = i + 1; ii < rows; ii++) {
                            if (apples[i][j] > apples[ii][j]) { // 切出去上面的披萨的至少有一个苹果
                                dp[i][j][kk] = (dp[i][j][kk] + dp[ii][j][kk - 1]) % mod;
                            }
                        }
                        // 垂直方向切
                        for (int jj = j + 1; jj < cols; jj++) {
                            if (apples[i][j] > apples[i][jj]) {
                                dp[i][j][kk] = (dp[i][j][kk] + dp[i][jj][kk - 1]) % mod;
                            }
                        }
                    }
                }
            }
        }
        return dp[0][0][k];
    }
}

你可能感兴趣的:(LeetCode,leetcode,算法,java,动态规划,intellij-idea)