『力扣周赛』第361场周赛、第112场双周赛

66 阅读2分钟

第361场周赛

2. 生成特殊数字的最少操作

要让整数被25整除,只要数以25的倍数为结尾即可,分别是25、50、75、00。从最后面开始遍历,依次找到这两位。n - 1 - i表示最后面的数,i - j - 1表示两位之间的数,这些数都要被删掉,加到操作数里。

如果没有找到符合要求的两位数,minOps就没更新,还是n,那么此时的目标是删掉所有数然后变成0。如果有0的话,可以少删一次。

num不含前导0,所以“00”是不行的。

var minimumOperations = function(num) {
    const n = num.length;
    let minOps = n;
    
    // 找25的倍数
    for (let i = n - 1; i >= 0; i--) {
        for (let j = i - 1; j >= 0; j--) {
            if ((num[i] === '5' && num[j] === '2') || (num[i] === '0' && num[j] === '5') || (num[i] === '5' && num[j] === '7') || (num[i] === '0' && num[j] === '0')) {
                const opsBetween = (n - 1 - i) + (i - j - 1);
                minOps = Math.min(minOps, opsBetween);
            }
        }
    }
    
    if (minOps === n) {
        const str = '' + num
        for (const item of str) {
            if (item === '0') return minOps - 1
        }
        return minOps
    }
    
    return minOps;

};

2845. 统计趣味子数组的数目

这道题关键在于优化时间复杂度,如果直接暴力,时间复杂度是O(n ^ 3)。

因为这道题目涉及区间,可以想到前缀和,但这题的前缀和不是传统的“和”,而是保存了数量,但是思想是相同的:想要求某个区间的“值”,就用“大的前缀和”减去“小的前缀和”。

prefix[i] 保存的是数组 nums 中前 i 个元素中满足条件 nums[j] % modulo == k 的元素的数量,prefix[r] - prefix[l-1] 就等于子数组 nums[l..r] 中满足条件的元素的数量。

count[i] 保存的是前缀和取 modulo 的余数等于 i 的前缀的数量。

var countInterestingSubarrays = function(nums, modulo, k) {
    const n = nums.length;
    let prefix = new Array(n + 1).fill(0);
    let count = {};
    count[0] = 1;
    let ans = 0;

    for (let i = 0; i < n; i++) {
        // 计算前缀和 
        prefix[i + 1] = prefix[i] + (nums[i] % modulo === k ? 1 : 0);
        // 目标是 (prefix[i + 1] - prefix[key]) % modulo === k
        // 找出有多少个符合条件的prefix[key],把数量加上
        // +modulo是防止产生负数
        let key = (prefix[i + 1] - k + modulo) % modulo;
        ans += count[key] ? count[key] : 0;
        // 更新count
        count[prefix[i + 1] % modulo] = (count[prefix[i + 1] % modulo] || 0) + 1;
    }

    return ans;
};

第112场双周赛

2. 判断通过操作能否让字符串相等 II

只需要看下标为偶数的字符个数是否都一样,下标为奇数的字符个数是否都一样。

这种题一般都不需要真的去完成操作(交换),属于脑筋急转弯问题。

var checkStrings = function(s1, s2) {
    const count1 = new Array(52).fill(0);
    const count2 = new Array(52).fill(0);
    const n = s1.length;
    for(let i = 0; i < n; i++) {
        count1[s1.charCodeAt(i) - 97 + (i % 2) * 26]++;
        count2[s2.charCodeAt(i) - 97 + (i % 2) * 26]++;
    }
    for(let i = 0; i < 52; i++) {
        if(count1[i] !== count2[i]) {
            return false;
        }
    }
    return true;
};