Difficulty: Easy Asked in: Google, Facebook, Microsoft, Amazon, Morgan Stanley
Key takeaway: This problem is an excellent way to learn optimization using fast and slow pointers. We have discussed two in-place solutions that take O(n) time.
We are given a sorted array and need to write a program to remove duplicate elements so that there is a single occurrence of each element in the array. Note: After removing duplicates, we need to return the length of the array containing unique elements. It doesn't matter what we leave beyond the new length.
Input: X[] = [2, 2, 2, 2, 2, 3, 3, 3], Output: 2, X[] = [2, 3]
Explanation: Our function should return length = 2, with the first two elements of X[] being 2 and 3, respectively. It doesn't matter what we leave beyond the returned length.
Input: X[] = [1, 2, 2, 3, 4, 4, 4, 5, 5], Output: 5, X[] = [1, 2, 3, 4, 5]
Explanation: Our function should return length = 5, with the first five elements of X[] being 1, 2, 3, 4, and 5, respectively.
One idea would be to store unique elements in extra memory and copy them back to the original array. By the end of this process, we will return the new length of the input array.
int removeDuplicatesArray(int X[], int n)
{
if (n == 0 || n == 1)
return n;
int unique[n];
int count = 0;
for (int i = 0; i < n - 1; i = i + 1)
{
if (X[i] != X[i + 1])
{
unique[count] = X[i];
count = count + 1;
}
}
unique[count] = X[n - 1];
count = count + 1;
for (int i = 0; i < count; i = i + 1)
X[i] = unique[i];
return count;
}
def removeDuplicatesArray(X, n):
if n == 0 or n == 1:
return n
unique = [0] * n
count = 0
for i in range(n - 1):
if X[i] != X[i + 1]:
unique[count] = X[i]
count = count + 1
unique[count] = X[n - 1]
count = count + 1
for i in range(count):
X[i] = unique[i]
return count
We are linearly traversing the array twice, so the time complexity is Traversing the array to store unique elements + Traversing the array to copy unique elements = O(n) + O(count) = O(n). The value of count is equal to n in the worst case. Space complexity = O(n) for the extra array unique[n].
Can we use the sorted array property to solve this problem in place? Let's think.
In a sorted array, all duplicate elements will be placed adjacent to each other. So, we can easily track unique elements and place them into the front positions of the array. For this purpose, we use one fast pointer to scan the array and a slow pointer to track the position of unique elements.
int removeDuplicatesArray(int X[], int n)
{
if (n == 0)
return 0;
int slow = 0;
int fast = 1;
while (fast < n)
{
if (X[fast] != X[slow])
{
slow = slow + 1;
X[slow] = X[fast];
}
fast = fast + 1;
}
return slow + 1;
}
def removeDuplicatesArray(X, n):
if n == 0:
return 0
slow = 0
fast = 1
while fast < n:
if X[fast] != X[slow]:
slow = slow + 1
X[slow] = X[fast]
fast = fast + 1
return slow + 1
We are doing a single scan of the array, so the time complexity is O(n). We are just using two extra variables, so the space complexity is O(1).
Here is another idea to solve the problem by counting duplicates in the array:
int removeDuplicatesArray(int X[], int n)
{
int duplicateCount = 0;
for (int i = 1; i < n; i = i + 1)
{
if (X[i] == X[i - 1])
duplicateCount = duplicateCount + 1;
else
X[i - duplicateCount] = X[i];
}
return n - duplicateCount;
}
def removeDuplicatesArray(X, n):
duplicateCount = 0
for i in range(1, n):
if X[i] == X[i - 1]:
duplicateCount = duplicateCount + 1
else:
X[i - duplicateCount] = X[i]
return n - duplicateCount
We are doing a single scan of the array, so the time complexity is O(n). The space complexity is O(1), and we are just using one extra variable.
If you have any queries/doubts/feedback, please write us at contact@enjoyalgorithms.com. Enjoy learning, Enjoy algorithms!