目录
100230. 修改矩阵
题目链接
题目描述
接口描述
思路分析
代码详解
100186. 匹配模式数组的子数组数目 I
题目链接
题目描述
接口描述
思路分析
代码详解
100219. 回文字符串的最大数量
题目链接
题目描述
接口描述
思路分析
代码详解
100198. 匹配模式数组的子数组数目 II
题目链接
题目描述
接口描述
思路分析
代码详解
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
给你一个下标从 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. 回文字符串的最大数量
给你一个下标从 0 开始的字符串数组
words
,数组的长度为n
,且包含下标从 0 开始的若干字符串。你可以执行以下操作 任意 次数(包括零次):
- 选择整数
i
、j
、x
和y
,满足0 <= i, j < n
,0 <= x < words[i].length
,0 <= 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
给你一个下标从 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;
}
};