Descripción
Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.
Find all the elements of [1, n] inclusive that do not appear in this array.
Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space.
pensamiento
Ancianos reciclado para volver a crear los primeros 6 días.
Esta pregunta y # 442 son el mismo tipo de problema, relativamente complicado, requiere complejidad del tiempo O(n)
, sin espacio adicional (suplemento sujeta la matriz para ser devuelto en el espacio extra no está ahí, por lo que puede abrir una serie de resultados del algoritmo de preservación)
Una de las dificultades de este problema es la manera de entender las preguntas correctamente, hay dos mensajes clave, uno es 所有数字在输入串中只能出现一次
, el otro es 1 ≤ a[i] ≤ n (n = size of array)
. Lo que significa que la información es: el valor de todos los elementos de la matriz 1
y size
entre.
Habría dos ciclos a la resolución de problemas, o la segunda capa en HashSet O(1)
~ O(n)
de búsqueda de inserción. Sin embargo, de acuerdo con estos dos datos fundamentales, podemos hacer que el bucle interno en un tiempo de "mapeo" constante, de modo que la complejidad del tiempo se reduce O(n)
. Método interior "Asignación de valores-clave" son: Guardar el elemento como un valor index
(Key), será nums[index]
cambiado a un signo menos para el marcado cifras han visitado el (valor).
La fundación puede hacer algunas de ellas:
- Después menos uno, un valor dentro de una gama de elementos de la matriz
0
ysize -1
entre, y exactamenteindex
igual. - Bien diseñado estrategias de mapeo / Hash, como el sitio básico aquí, desde
元素值的绝对值
el标记某个数字已被访问
mapa. nums
Valor se cambia al signo negativo no es un problema, todavía puedeabs()
expresar su valor original.
AC después del descubrimiento:
- Por esta repetitivos problemas numéricos, unoredered_set eficiencia de la consulta es pobre y no puede mantener la junta (1), porque demasiadas colisiones entre elementos idénticos. Por lo tanto, la estrategia de asignación nueva re-modifique hash a partir de la particularidad de la matriz.
- Hacer la operación de implantación baja diferencia entre los dos eficiencia conjunto C ++, y no hay ninguna operación durante un diferencia de conjuntos construidos unordered_set, y sorpresa, pitón de código C ++ es el código mucho más rápido.
CA primera edición del código, 340ms, situándose en el 5,5%:
class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums) {
vector<int> missing_num;
unordered_set<int> num_set;
for (int element : nums) {
num_set.insert(element);
}
for (int i = 1; i <= nums.size(); ++i) {
auto num_set_iter = num_set.find(i);
if (num_set_iter == num_set.end()) {
missing_num.push_back(i);
}
}
return missing_num;
}
};
códigos segunda edición, CA 712ms pitón, situándose en el 5,5%; 912ms CPP, ocupando el 5% ::
class Solution:
def findDisappearedNumbers(self, nums: List[int]) -> List[int]:
a = set([i for i in range(1, len(nums)+1)])
b = set(nums)
return list(a - b)
class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums) {
set<int> all_nums;
for (int i = 1; i <= nums.size(); ++i) {
all_nums.insert(i);
}
set<int> nums_set(nums.begin(), nums.end());
set<int> missing_num;
set_difference(all_nums.begin(), all_nums.end(),
nums_set.begin(), nums_set.end(),
inserter(missing_num, missing_num.begin()));
return vector<int>(missing_num.begin(), missing_num.end());
}
};
AC tercera edición del código, 116ms, ocupando el 64%:
class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums) {
if (nums.empty()) return nums;
vector<int> result;
for (auto element : nums) {
// element may be negative, don't use it directly as index
element = abs(element);
if (nums[element-1] > 0) {
nums[element-1] = -nums[element-1];
}
}
for (int i = 0; i < nums.size(); ++i) {
if (nums[i] > 0) {
result.push_back(i+1);
}
}
return result;
}
};