Manipulação de Arrays: Quadrados de um Array Ordenado, Subarray de Soma Mínima e Matriz Espiral

Este artigo aborda três problemas comuns em algoritmos de arrays: calcular os quadrados de elementos em um array ordenado, encontrar o subarray de soma mínima e gerar uma matriz em espiral.

Quadrados de um Array Ordenado (977. Squares of a Sorted Array)

O objetivo é receber um array de inteiros em ordem não decrescente, calcular o quadrado de cada elemento e, em seguida, retornar um novo array com os quadrados também em ordem não decrescente. Uma abordagem eficiente utiliza a técnica de dois ponteiros.

Inicializamos dois ponteiros, um no início (esquerda) e outro no final (direita) do array de entrada. Um ponteiro auxiliar (posicao) é usado para preencher o array de resultado a partir do final. Comparamos os quadrados dos elementos apontados por esquerda e direita. O maior quadrado é colocado na posição atual de posicao no array de resultado, e o ponteiro correspondente (esquerda ou direita) é movido, enquanto posicao é decrementado.


#include <vector>
#include <cmath>
#include <algorithm>

class Solution {
public:
    std::vector<int> sortedSquares(std::vector<int>& nums) {
        int esquerda = 0;
        int direita = nums.size() - 1;
        int posicao = direita;
        std::vector<int> resultado(nums.size());

        while (esquerda <= direita) {
            int quadradoEsquerda = nums[esquerda] * nums[esquerda];
            int quadradoDireita = nums[direita] * nums[direita];

            if (quadradoEsquerda > quadradoDireita) {
                resultado[posicao] = quadradoEsquerda;
                esquerda++;
            } else {
                resultado[posicao] = quadradoDireita;
                direita--;
            }
            posicao--;
        }
        return resultado;
    }
};
</int></int></int></algorithm></cmath></vector>

Subarray de Soma Mínima (209. Minimum Size Subarray Sum)

Este problema busca o menor subarray contínuo de um array de inteiros positivos cuja soma seja maior ou igual a um determinado target. A abordagem mais eficaz é a da "janela deslizante".

Utilizamos dois ponteiros, inicioJanela e fimJanela, para definir a janela deslizante. O ponteiro fimJanela avança, adicionando elementos à soma atual (somaAtual). Se somaAtual atingir ou exceder o target, registramos o comprimento da janela atual (fimJanela - inicioJanela + 1) e tentamos encolher a janela pelo lado esquerdo, subtraindo o elemento em inicioJanela e incrementando inicioJanela, até que somaAtual seja menor que target novamente. O menor comprimento registrado é a resposta.


#include <vector>
#include <limits>
#include <algorithm>

class Solution {
public:
    int minSubArrayLen(int target, std::vector<int>& nums) {
        int inicioJanela = 0;
        int fimJanela = 0;
        long long somaAtual = 0; // Usar long long para evitar overflow
        int comprimentoMinimo = std::numeric_limits<int>::max();

        while (fimJanela < nums.size()) {
            somaAtual += nums[fimJanela];

            while (somaAtual >= target) {
                comprimentoMinimo = std::min(comprimentoMinimo, fimJanela - inicioJanela + 1);
                somaAtual -= nums[inicioJanela];
                inicioJanela++;
            }
            fimJanela++;
        }

        return (comprimentoMinimo == std::numeric_limits<int>::max()) ? 0 : comprimentoMinimo;
    }
};
</int></int></int></algorithm></limits></vector>

Matriz Espiral II (59. Spiral Matrix II)

O desafio aqui é preencher uma matriz quadrada n x n com inteiros de 1 a n*n em um padrão espiral, começando do canto superior esquerdo e movendo-se no sentido horário.

A lógica central é simular o preenchimento da matriz em camadas concêntricas. Definimos limites para as bordas da camada atual (linhaInicio, linhaFim, colunaInicio, colunaFim). Iteramos preenchendo a borda superior, depois a direita, a inferior e, por fim, a esquerda. Após completar uma camada, ajustamos os limites para a próxima camada interna e repetimos o processo. Um contador (valorAtual) rastreia o próximo número a ser inserido na matriz.


#include <vector>

class Solution {
public:
    std::vector<:vector>> generateMatrix(int n) {
        std::vector<:vector>> matriz(n, std::vector<int>(n));
        int valorAtual = 1;
        int linhaInicio = 0, linhaFim = n - 1;
        int colunaInicio = 0, colunaFim = n - 1;

        while (linhaInicio <= linhaFim && colunaInicio <= colunaFim) {
            // Preencher linha superior
            for (int j = colunaInicio; j <= colunaFim; ++j) {
                matriz[linhaInicio][j] = valorAtual++;
            }
            linhaInicio++;

            // Preencher coluna direita
            for (int i = linhaInicio; i <= linhaFim; ++i) {
                matriz[i][colunaFim] = valorAtual++;
            }
            colunaFim--;

            // Preencher linha inferior (se ainda houver linha)
            if (linhaInicio <= linhaFim) {
                for (int j = colunaFim; j >= colunaInicio; --j) {
                    matriz[linhaFim][j] = valorAtual++;
                }
                linhaFim--;
            }

            // Preencher coluna esquerda (se ainda houver coluna)
            if (colunaInicio <= colunaFim) {
                for (int i = linhaFim; i >= linhaInicio; --i) {
                    matriz[i][colunaInicio] = valorAtual++;
                }
                colunaInicio++;
            }
        }
        return matriz;
    }
};
</int></:vector></:vector></vector>

Estes exemplos demonstram a aplicação de técnicas fundamentais em manipulação de arrays, como ponteiros duplos e janelas deslizantes, para resolver problemas de forma eficiente.

Tags: C++ Algoritmos Arrays ponteiros duplos janela deslizante

Publicado em 6-13 22:05 por Thomas