283. Moviendo el cero
283. Mover ceros https://leetcode.cn/problems/move-zeroes/
tema:
Dada una matriz nums
, escriba una función para 0
mover todo al final de la matriz manteniendo el orden relativo de los elementos distintos de cero.
Tenga en cuenta que las matrices deben manipularse in situ sin copiarlas.
Ideas para resolver problemas:
Podemos usar dos punteros (dest y cur) para dividir esta matriz en tres áreas
Podemos inicializar dest a -1 y cur a 0
Hay dos situaciones que encuentra cur al caminar a través de la matriz:
- la posición actual es 0
- La posición de cur no es 0.
Cuando la posición de cur es 0, cur++;
Cuando cur no es 0, simplemente cámbielo, dest++;
Código de resolución de problemas:
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int dest=-1;
int cur=0;
int size=nums.size();
while(cur<size)
{
if(nums[cur]!=0)
{
swap(nums[dest+1],nums[cur]);
++dest;
}
++cur;
}
}
};
1089. Sobrescribir cero
1089. Ceros duplicados https://leetcode.cn/problems/duplicate-zeros/
tema:
Dada una matriz de números enteros de longitud fija arr
, sobrescriba cada aparición de cero en la matriz y desplace los elementos restantes hacia la derecha.
Nota: No escriba elementos más allá de la longitud de la matriz. Realice la modificación anterior in situ en la matriz de entrada y no devuelva nada de la función.
Ideas para resolver problemas:
Esta pregunta requiere que la modifiquemos en su lugar y no podemos usar matrices adicionales. Pensemos en ello primero con matrices adicionales.
Encontramos que el resultado es este.
Usemos el método de doble puntero usando una matriz adicional para experimentar localmente. Descubrimos que dest = -1 y cur = 0, no es posible resolver el problema hacia adelante y los elementos se sobrescribirán y se perderán.
Intentemos operar al revés, dest = tamaño-1 (apuntando al último elemento), entonces, ¿cómo determinamos la posición de cur?
Podemos usar el método del doble puntero nuevamente para confirmar la posición de cur. Al principio, cur = 0, dest = -1
Recorra la matriz, cuando cur encuentre 0, dest+=2; cuando cur encuentre un valor distinto de cero, cur++;
Aquí habrá un caso límite que debemos considerar:
Ejemplo: 1 0 2 3 0
Cuando determinamos cur mediante el método anterior, ocurrirá la siguiente situación:
Habrá una situación en la que el destino está fuera de los límites. Estableceremos la posición de tamaño-1 en 0 y luego cur--, dest-=2 resolverá el problema.
Luego, cuando encuentre 0 de atrás hacia adelante, establecerá 0 dos veces y, si encuentra un valor distinto de cero, lo copiará. Este paso es simple
Código de resolución de problemas:
class Solution {
public:
void duplicateZeros(vector<int>& arr) {
int dest=-1;
int cur=0;
int size=arr.size();
//确认cur的位置
while(cur<size)
{
if(arr[cur]==0)dest+=2;
else dest++;
if(dest>=size-1)break;
cur++;
}
//边界情况,示例:1 0 2 3 0,当dest的位置越界了
if(dest==size)
{
arr[size-1]=0;
dest-=2;
cur--;
}
while(cur>=0)
{
if(arr[cur]!=0)
{
arr[dest--]=arr[cur--];
}
else
{
arr[dest--]=0;
arr[dest--]=0;
cur--;
}
}
}
};