力扣周赛292之相乘取模被坑

217 阅读1分钟

统计打字方案数 - 力扣 (LeetCode) 竞赛 (leetcode-cn.com)

思路不是很难,就是把相同的字符串的所有可能情况相乘计算出来就行,比如22233。

222有4种情况,33有2种情况。所以就是4 * 2 = 8。

但是这里比较麻烦的点是取模,取模的运算性质可参考。

image-20220508121744423.png

我们可以用打表的方法提前计算出来每个长度对应的可能状况。最后再相乘起来得到结果。

被坑的一点是尽管已经取模了,但是相乘后还是有可能溢出,所以相乘的结果要用long来记

 // 巨坑  result 声明为long就行了   181997601 * 10609 就是个负数了
    long result = 1;
    for (int i = 0; i < list.size(); i++) {
        result *= (list.get(i) % mod);
        result = result % mod;
    }

通过代码:

private int mod = 1000000007;

public int countTexts(String pressedKeys) {
    int[] mod3 = new int[100002];
    mod3[0] = 1;
    for (int i = 1; i <= 100001; i++) {
        for (int j = 3; j >= 1; j--) {
            if (i - j >= 0) {
                mod3[i] += (mod3[i - j] % mod);
                mod3[i] = (mod3[i] % mod);
            }
        }
        mod3[i] = (mod3[i] % mod);
    }


    int[] mod4 = new int[100002];
    mod4[0] = 1;
    for (int i = 1; i <= 100001; i++) {
        for (int j = 4; j >= 1; j--) {
            if (i - j >= 0) {
                mod4[i] += (mod4[i - j] % mod);
                mod4[i] = (mod4[i] % mod);
            }
        }
        mod4[i] = (mod4[i] % mod);
    }

    int len = pressedKeys.length();

    List<Integer> list = new ArrayList<>();
    for (int i = 0; i < len; i++) {
        int j = i;
        char c = pressedKeys.charAt(j);
        int tmpCnt = 1;
        while (j < len - 1 && pressedKeys.charAt(j) == pressedKeys.charAt(j + 1)) {
            tmpCnt++;
            j++;
        }
        if (c == '7' || c == '9') {
            list.add(mod4[tmpCnt]);
        } else {
            list.add(mod3[tmpCnt]);
        }
        i = j;
    }

    // 巨坑  result 声明为long就行了   181997601 * 10609 就是个负数了
    long result = 1;
    for (int i = 0; i < list.size(); i++) {
        result *= (list.get(i) % mod);
        result = result % mod;
    }
    
    return (int)result % mod;
}