LeetCode Una pregunta por día -2.15-485. El número máximo de unos consecutivos + 2.19-1004. El número máximo de unos consecutivos III

¡Papel lleno de advertencias absurdas!


485

Descripción del Título

Inserte la descripción de la imagen aquí

Ventana deslizante Idea

Esta pregunta en realidad no requiere ventanas deslizantes. Si encuentra 1, cnt ++, puede restablecer a 0 cuando encuentre 0cnt, pero un buscador de empleo dedicado debe practicar las ventanas deslizantes.

class Solution {
    
    
public:
    int findMaxConsecutiveOnes(vector<int>& nums) {
    
    
         int l = 0, r = 0;
        int len = nums.size();
        int ans = 0;
        while(r < len) {
    
    
            if(nums[r] == 1) {
    
    
                r++;
            } else {
    
    
                //r一定会会先遇到0,l会停在第一个1
                //这时候r-l就是1的长度
                ans = max(ans, r - l);
                r++;
                l = r;
            }
        }
        //eg:[0,1,1]  [1,1,1] 最后一个窗口到达时,r超出了数组长度,所以还要计算一次
        ans = max(ans, r - l);
        return ans;
    }
};

La idea del deslizamiento del código anterior:
si encuentra un 1, r ++, expanda la ventana y no realice otras operaciones; esto lleva a que si es 1 al final, debe calcularlo nuevamente.
Si encuentra un 0, calcule el resultado, porque aquí se retrasa, r = 0, lo que indica que el intervalo [L, R) es un intervalo correcto, y luego R ++, L = R, cruza este 0. En general, cuando te encuentras con RL, tienes que calcularlo una vez más.
Tiempo O (n)
Espacio O (1) Cuando
hago este problema, creo que es bastante natural, pero cuando hago el siguiente problema, creo que es extraño.

1004

Descripción del Título

Inserte la descripción de la imagen aquí

Ventana deslizante Idea

Para esta pregunta, no puede juzgar directamente 0 con un solo puntero y luego borrarlo, porque cada 0 puede ser un punto de partida.
Entonces todavía usa una ventana deslizante,

class Solution {
    
    
public:
    int longestOnes(vector<int>& A, int K) {
    
    
        int len = A.size();
        if(K == len) return len;
        int left = 0, right = 0;
        int ans = 0;
        int zeroSum = 0;
        while(right < len) {
    
    
            if(A[right] == 0) {
    
    
                zeroSum++;
            }
            while(zeroSum > K) {
    
    
                if(A[left] == 0) {
    
    
                    zeroSum--;
                }
                left++;
            }
            ans = max(ans, right - left + 1);
            right++;
        }
        return ans;
    }
};

La idea también es obvia. Cuando
encuentres un 0, primero cambia "se convierte en 1". Si el número de veces es suficiente, estará bien;
pero si encuentras que se usa más, debes seguir reduciendo la izquierda. límite hasta que se descarte un 0,
y luego calcule el tamaño del intervalo cada vez.

Oye, pensarlo de esta manera te hará sentir extraño. ¿Por qué la primera pregunta debe contarse una vez más al final? ¿La idea no es lo suficientemente buena? ¿Puedes usar el método de movimiento de insectos como la segunda pregunta?
ps: método de movimiento de insectos. El
límite derecho sigue retorciéndose, y el límite izquierdo sigue retorciéndose cuando se encuentra en un período especial. Es correcto cada vez que se detiene.
Entonces comenzó a procesar el código de la primera pregunta.
Esta es la primera versión

class Solution {
    
    
public:
    int findMaxConsecutiveOnes(vector<int>& nums) {
    
    
         int l = 0, r = 0;
        int len = nums.size();
        int ans = 0;
        while(r < len) {
    
    
            if(nums[r] == 0)
            {
    
    
                l = r;
                while(nums[r] == 0) {
    
    
                    l++;
                    r++;
                }
            }
            ans = max(ans, r - l + 1);
            r++;
        }
        //eg:[0,1,1]  [1,1,1] 最后一个窗口到达时,r超出了数组长度,所以还要计算一次
        return ans;
    }
};

La idea es ignorar al encontrar 1, expandir la ventana. Al
encontrar 0, busque un intervalo que no comience en 0,
y luego calcule el tamaño de la ventana cada vez.

Era extraño verlo, pero como se esperaba, el
caso [0] cruzó el límite, porque la r en el while cruzó el límite
y luego lo cambió de nuevo.

class Solution {
    
    
public:
    int findMaxConsecutiveOnes(vector<int>& nums) {
    
    
         int l = 0, r = 0;
        int len = nums.size();
        int ans = 0;
        while(r < len) {
    
    
            if(nums[r] == 0)
            {
    
    
                l = r;
                while(r < len && nums[r] == 0) {
    
    
                    l++;
                    r++;
                }
            } else {
    
    
                ans = max(ans, r - l + 1);
                r++;
            }
        }
        return ans;
    }
};

La condición aumentada, que mientras se determina el límite r no es
solo esto no es suficiente, si el caso de [0], el primer ans será igual a 1, es incorrecta,
por lo que el siguiente código en el else entra, es decir, solo los números [ r] Es igual a 1 para calcular el tamaño de la ventana.
Esto es correcto,
pero el código de 1004 no aparece [0], 0 será incorrecto, la razón es que su L se convertirá en 1, y luego el resultado del cálculo es, 0-1 + 1 = 0,
obviamente, K = 0 de 1004 es 485, así que volvemos a cambiar el código

class Solution {
    
    
public:
    int findMaxConsecutiveOnes(vector<int>& nums) {
    
    
         int l = 0, r = 0;
        int len = nums.size();
        int ans = 0;
        int zeroSum= 0;
        while(r < len) {
    
    
            if(nums[r] == 0) {
    
    
                zeroSum++;
            }
            while(zeroSum > 0) {
    
    
                if(nums[l] == 0) {
    
    
                    zeroSum--;
                }
                l++;
            }
            ans = max(ans, r - l + 1);
            r++;
        }
        //eg:[0,1,1]  [1,1,1] 最后一个窗口到达时,r超出了数组长度,所以还要计算一次
        return ans;
    }
};

Simplificación

class Solution {
    
    
public:
    int findMaxConsecutiveOnes(vector<int>& nums) {
    
    
         int l = 0, r = 0;
        int len = nums.size();
        int ans = 0;
        int zeroSum= 0;
        while(r < len) {
    
    
            if(nums[r] == 0) {
    
    
                while(nums[l] != 0) {
    
    
                    l++;
                }
                l++;
            }
            ans = max(ans, r - l + 1);
            r++;
        }
        return ans;
    }
};

Lo cambié durante mucho tiempo ... También fui a interpretar a Hollow Knight en medio del autismo. Por supuesto, descubrí que Hollow Knight era más autista, y luego regresé.
La dificultad es que L ++ debe usarse al final del ciclo while; es decir, se debe cruzar un 0 (sin importar qué k sea), por lo que el resultado debe ser correcto.
Dar algunos ejemplos

K = 0
1 1 0  
出循环时 L = 3 R = 2

K = 1
1 1 0 0 
出循环时 L = 4 R = 4

Es solo un artículo para que lo vea usted mismo. Mírelo y adivine lo que 233333 ha
dicho tanto. Lo principal es expresar aparentemente el mismo tema por analogía, pero no lo piense, a veces será un desastre si no prestas atención.

Supongo que te gusta

Origin blog.csdn.net/qq_42883222/article/details/113886972
Recomendado
Clasificación