1. Descrição e requisitos do tópico
80. Remova duplicatas na matriz classificada II - LeetCode
descrição do tópico
Dada uma matriz ordenada nums , exclua os elementos repetidos no local , de modo que os elementos que aparecem mais de duas vezes apareçam apenas duas vezes e retorne o novo comprimento da matriz excluída.
Não use espaço extra na matriz , você deve modificar a matriz de entrada no local e fazer isso com O(1) espaço extra.
exemplo
Exemplo 1:
输入:nums = [1,1,1,2,2,3]
输出:5, nums = [1,1,2,2,3]
解释:函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。 不需要考虑数组中超出新长度后面的元素。
Exemplo 2:
输入:nums = [0,0,1,1,1,1,2,3,3]
输出:7, nums = [0,0,1,1,2,3,3]
解释:函数应返回新长度 length = 7, 并且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3 。 不需要考虑数组中超出新长度后面的元素。
dica
1 <= nums.length <= 3 * 104
-104 <= nums[i] <= 104
nums
ordenado ascendente
2. Ideias para resolução de problemas
Ideia geral:
Primeiro, analise o tópico. O tópico diz que, dado um array ordenado, somos obrigados a excluir elementos que aparecem mais de duas vezes no array e só podemos modificar o array original e não podemos emprestar arrays adicionais. Finalmente, somos obrigados a retornar o novo comprimento da matriz.
Primeiramente queremos deletar os elementos que aparecem mais de duas vezes no array, então devemos percorrer todo o array, mas como descobrir os elementos que aparecem mais de duas vezes e excluí-los? A ideia mais simples é comparar cada elemento com os elementos a seguir, contar o número de vezes e modificá-lo se o número de ocorrências for maior que 2 durante a comparação, mas esse método de implementação precisa usar loops aninhados e o a complexidade do espaço é relativamente alta, alta e mais complicada de implementar. Portanto, podemos pensar no método "double pointer", ou seja, usar dois ponteiros para percorrer e atualizar os elementos do array. Portanto, podemos definir duas variáveis, uma é usada para percorrer o array e a outra é usada para registrar o comprimento do array atualizado e atualizar o array.
Então vamos analisar a situação do array.Para o número de elementos do array menor ou igual a 2, o comprimento do array pode ser retornado diretamente. Como precisamos garantir que cada elemento apareça apenas duas vezes, devemos comparar o primeiro elemento com o terceiro elemento (porque o título diz que é uma matriz ordenada) e, se forem iguais, significa o número de ocorrências do elemento atual É maior que 2, portanto, o ponteiro de passagem será movido para trás, encontre o elemento que não é igual ao elemento anterior, atribua-o e atualize o comprimento da matriz modificada (ou seja, o ponteiro de atualização se move um bit para trás) . Portanto, o valor inicial dos dois ponteiros é 2, e cada comparação é feita comparando o elemento apontado pelo ponteiro de passagem com o segundo elemento na frente do elemento apontado pelo ponteiro de atualização (o segundo da direita para a esquerda) .
[O seguinte é um exemplo para analisar as mudanças de dois ponteiros]
Etapas específicas:
① Determine se o comprimento da matriz é maior que 2
② Inicialize dois ponteiros
③Atravesse o array e atualize-o
④ Retorne o comprimento do array atualizado
3. Código específico [linguagem C]
int removeDuplicates(int* nums, int numsSize){
if(numsSize<=2) return numsSize;
int left = 2, right = 2;//有序数组,每个元素只出现两次,因此right从下标2开始遍历
//while的执行条件为right<numsSize,即未遍历完数组
while (right < numsSize) {
//比较当前位置的元素与自己前面第二个元素是否相等
//如果相等则需要继续向后面找新的元素替代掉当前位置的元素
//如果不相等则将此时right所指向的元素赋值给left所指向的元素
//left就是修改后的数组长度,而right是用来遍历访问整个数组的
if (nums[left - 2] != nums[right]) {
nums[left] = nums[right];
++left;
}
++right;
}
return left;
}