1. Introdução do tópico
Fornece uma matriz de números inteiros e um inteiro k.
Se houver exatamente k números ímpares em uma submatriz contínua, consideramos esta submatriz como uma "bela submatriz".
Por favor, retorne o número de "belas submatrizes" nesta matriz.
Exemplo 1:
Entrada: nums = [1,1,2,1,1], k = 3
Saída: 2
Explicação: As submatrizes contendo 3 números ímpares são [1,1,2,1] e [1,2,1,1 ]
Exemplo 2:
Entrada: nums = [2,4,6], k = 1
Saída: 0
Explicação: A seqüência numérica não contém nenhum número ímpar, portanto, não há submatriz elegante.
Exemplo 3:
Entrada: nums = [2,2,2,1,2,2,1,2,2,2], k = 2
Saída: 16
pronto:
1 <= nums.length <= 50000
1 <= nums [i] <= 10 ^ 5
1 <= k <= nums.length
Fonte: LeetCode
Link: https://leetcode-cn.com/problems/count-number-of-nice-subarrays Os
direitos autorais são propriedade da LeetCode . Para reimpressões comerciais, favor contatar a autorização oficial Para reimpressões não comerciais, favor indicar a fonte
Dois, ideias para solução de problemas
- Percorra a matriz para registrar o i-ésimo número ímpar e armazene-o em vOdd na posição do subscrito na matriz.
- Usando a ideia de janela deslizante, mantenha uma "janela" com k números ímpares, ou seja, k números ímpares entre vOdd [i] e vOdd [i + k-1].
- Suponha que o ponteiro esquerdo na janela acima seja le o ponteiro direito seja r, o intervalo de valores de l é (vOdd [i-1], vOdd [i]]; o intervalo de valores de r é [vOdd [i + k-1 ], vOdd [i + k]). A submatriz entre os subscritos correspondentes a [l, r] é a submatriz elegante. esquerda = vOdd [i] -vOdd [i-1] representa o número de números pares do i-1º número ímpar ao i-ésimo número ímpar, da mesma forma direita = vOdd [i + k] -vOdd [i + k-1 ] Representa o número de números pares entre o número ímpar i + k-1 e o número ímpar i + k. Pode-se calcular que o número de submatrizes contendo esses k números ímpares está à esquerda * à direita.
- Percorra vOdd, calcule a soma cumulativa de k números ímpares começando do i-ésimo número ímpar e obtenha a bela submatriz.
- Preste atenção ao tratamento de casos de fronteira, consulte o código para obter detalhes.
Três, código de solução de problemas
class Solution {
public:
int numberOfSubarrays(vector<int>& nums, int k) {
int n = nums.size();
int cnt = 0;
vector<int> vOdd(n+2, -1);
for(int i = 0; i < n; ++i)
{
if((nums[i] & 1))
vOdd[++cnt] = i; //记录第几个奇数所对应的下标位置
}
vOdd[++cnt] = n;// 为了统计最后一个奇数到数组结尾之间偶数的个数
int res = 0;
for(int i = 1; i + k <= cnt; ++i)
{
res += (vOdd[i] - vOdd[i-1])*(vOdd[i+k] - vOdd[i+k-1]);
}
return res;
}
};