LeetCode 第384场周赛个人题解

目录

100230. 修改矩阵

题目链接

题目描述

接口描述

思路分析

代码详解

100186. 匹配模式数组的子数组数目 I

题目链接

题目描述

接口描述

思路分析

代码详解

100219. 回文字符串的最大数量

题目链接

题目描述

接口描述

思路分析

代码详解

100198. 匹配模式数组的子数组数目 II

题目链接

题目描述

接口描述

思路分析

代码详解


100230. 修改矩阵

题目链接

100230. 修改矩阵 - 力扣(LeetCode)

题目描述

给你一个下标从 0 开始、大小为 m x n 的整数矩阵 matrix ,新建一个下标从 0 开始、名为 answer 的矩阵。使 answer 与 matrix 相等,接着将其中每个值为 -1 的元素替换为所在列的 最大 元素。

返回矩阵 answer 。

接口描述

class Solution {
public:
    vector> modifiedMatrix(vector>& matrix) {
        
    }
};

思路分析

代码详解

class Solution
{
public:
    vector> modifiedMatrix(vector> &matrix)
    {
        vector> ret(matrix);
        int m = matrix.size(), n = matrix[0].size();
        for (int i = 0; i < m; i++)
        {
            for (int j = 0; j < n; j++)
            {
                if (ret[i][j] == -1)
                {
                    for (int k = 0; k < m; k++)
                        ret[i][j] = max(ret[i][j], matrix[k][j]);
                }
            }
        }
        return ret;
    }
};

100186. 匹配模式数组的子数组数目 I

题目链接

100186. 匹配模式数组的子数组数目 I

题目描述

给你一个下标从 0 开始长度为 n 的整数数组 nums ,和一个下标从 0 开始长度为 m 的整数数组 pattern ,pattern 数组只包含整数 -1 ,0 和 1 。

大小为 m + 1 的

子数组

  nums[i..j] 如果对于每个元素  pattern[k] 都满足以下条件,那么我们说这个子数组匹配模式数组  pattern :
  • 如果 pattern[k] == 1 ,那么 nums[i + k + 1] > nums[i + k]
  • 如果 pattern[k] == 0 ,那么 nums[i + k + 1] == nums[i + k]
  • 如果 pattern[k] == -1 ,那么 nums[i + k + 1] < nums[i + k]

请你返回匹配 pattern 的 nums 子数组的 数目 。

接口描述

class Solution {
public:
    int countMatchingSubarrays(vector& nums, vector& pattern) {
        
    }
};

思路分析

其实就是字符串匹配板子题

把nums两两配对按照递增递减相等分配字符,可以得到长度为n - 1的字符串a,把pattern转化为字符串b,题目就是让找a中b的数目

转化完跑KMP即可

关于KMP见:KMP算法详解 [c++]

时间复杂度O(n+m)

代码详解

class Solution
{
public:
    void get_nextval(const string &src, vector &nextval)
    {
        int j = 0, k = -1;
        nextval[0] = -1;
        while (j < (int)src.size() - 1)
        {
            if (k == -1 || src[j] == src[k])
            {
                j++;
                k++;
                nextval[j] = k;
            }
            else
            {
                k = nextval[k];
            }
        }
    }
    int countMatchingSubarrays(vector &nums, vector &pattern)
    {
        int n = nums.size(), m = pattern.size(), ret = 0;
        string a, b;
        for (int i = 0; i < n - 1; i ++)
            a.push_back(nums[i] == nums[i + 1] ? '0' : (nums[i] < nums[i + 1] ? '1' : '2'));
        for (auto x : pattern)
            b.push_back((~x) ? (x ^ 48) : '2');
        vector next(m);
        get_nextval(b, next);
        for (int i = 0, j = 0; i < n - 1;)
        {
            if (j == -1 || a[i] == b[j])
                i++, j++;
            else
                j = next[j];
            if (j == m)
                i--, ret++, j = next[m - 1];
        }
        return ret;
    }
};

100219. 回文字符串的最大数量

题目链接

100219. 回文字符串的最大数量

题目描述

给你一个下标从 0 开始的字符串数组 words ,数组的长度为 n ,且包含下标从 0 开始的若干字符串。

你可以执行以下操作 任意 次数(包括零次):

  • 选择整数ijxy,满足0 <= i, j < n0 <= x < words[i].length0 <= y < words[j].length交换 字符 words[i][x] 和 words[j][y] 。

返回一个整数,表示在执行一些操作后,words 中可以包含的回文字符串的 最大 数量。

注意:在操作过程中,i 和 j 可以相等。

接口描述

class Solution {
public:
    int maxPalindromesAfterOperations(vector& words) {
        
    }
};

思路分析

贪心

抛开题目,给一个字符集U,让构造k个字符串(长度固定)如何尽可能多的构造回文串?

先构造短的,并且分配若干个字符对(字符对就是两个相同的字符)+单/零个字符

那么对于本题而言,我们只需要先统计所有字符数目,然后计算有多少个字符对。然后把字符串数组按照长度升序排序,然后贪心分配字符即可

时间复杂度:O(nlogn)

代码详解

class Solution {
public:
    int maxPalindromesAfterOperations(vector& words) {
        int cnt[26]{0}, s = 0 ,res = 0, n = words.size(), ret = 0;
        for(auto& x : words)
            for(auto ch : x) cnt[ch - 'a']++;
        for(auto x : cnt) s += x / 2;
        sort(words.begin(), words.end(), [](string& x, string& y){return x.size() < y.size();});
        for(auto& x : words)
            if(s >= x.size() / 2) s -= x.size() / 2, ret++;
            else break;
        return ret;
    }
};

100198. 匹配模式数组的子数组数目 II

题目链接

100198. 匹配模式数组的子数组数目 II

题目描述

给你一个下标从 0 开始长度为 n 的整数数组 nums ,和一个下标从 0 开始长度为 m 的整数数组 pattern ,pattern 数组只包含整数 -1 ,0 和 1 。

大小为 m + 1 的

子数组

  nums[i..j] 如果对于每个元素  pattern[k] 都满足以下条件,那么我们说这个子数组匹配模式数组  pattern :
  • 如果 pattern[k] == 1 ,那么 nums[i + k + 1] > nums[i + k]
  • 如果 pattern[k] == 0 ,那么 nums[i + k + 1] == nums[i + k]
  • 如果 pattern[k] == -1 ,那么 nums[i + k + 1] < nums[i + k]

请你返回匹配 pattern 的 nums 子数组的 数目 。

接口描述

class Solution {
public:
    int countMatchingSubarrays(vector& nums, vector& pattern) {
        
    }
};

思路分析

和第一道方法一样

代码详解

class Solution
{
public:
    void get_nextval(const string &src, vector &nextval)
    {
        int j = 0, k = -1;
        nextval[0] = -1;
        while (j < (int)src.size() - 1)
        {
            if (k == -1 || src[j] == src[k])
            {
                j++;
                k++;
                nextval[j] = k;
            }
            else
            {
                k = nextval[k];
            }
        }
    }
    int countMatchingSubarrays(vector &nums, vector &pattern)
    {
        int n = nums.size(), m = pattern.size(), ret = 0;
        string a, b;
        for (int i = 0; i < n - 1; i ++)
            a.push_back(nums[i] == nums[i + 1] ? '0' : (nums[i] < nums[i + 1] ? '1' : '2'));
        for (auto x : pattern)
            b.push_back((~x) ? (x ^ 48) : '2');
        vector next(m);
        get_nextval(b, next);
        for (int i = 0, j = 0; i < n - 1;)
        {
            if (j == -1 || a[i] == b[j])
                i++, j++;
            else
                j = next[j];
            if (j == m)
                i--, ret++, j = next[m - 1];
        }
        return ret;
    }
};

你可能感兴趣的:(Leetcode周赛,leetcode,算法,职场和发展,c++,数据结构)