Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length. Do not allocate extra space for another array, you must do this in place with constant memory.
For example, given input array A = [1,1,2], your function should return length = 2, and A is now [1,2].
Analysis
The problem is pretty straightforward. It returns the length of the array with unique elements, but the original array need to be changed also. This problem is similar to Remove Duplicates from Sorted Array II.
Java Solution
public static int removeDuplicates(int[] A) { if (A.length < 2) return A.length; int j = 0; int i = 1; while (i < A.length) { if (A[i] != A[j]) { j++; A[j] = A[i]; } i++; } return j + 1; } |
Note that we only care about the first unique part of the original array. So it is ok if input array is {1, 2, 2, 3, 3}, the array is changed to {1, 2, 3, 3, 3}.
#include
#include
using namespace std;
#define ll long long
#define mod 1000000007
#define wt int t; cin>>t; while(t–){ solve(); cout<>n;
ll a[n];
mapm;
for(ll i=0;i>a[i];
m[a[i]]++;
}
for(ll i=0;i=1)
{
cout<< i<<" ";
}
}
}
int main(){
ios_base::sync_with_stdio(0);
cin.tie(NULL);
wt;
// wot;
}
This is general solution for sorted or unsorted array with test cases #Aditya Vajpayee
I think it’s easier to understand with a for loop and the notion of `last`.
int removeDuplicates(int[] nums)
{
if (num == null || num.length == 0) return 0;
int last = 0;
for (int i = 1 ; i < nums.length ; ++i)
{
if (nums[last] < nums[i])
{
last++;
nums[last] = nums[i];
}
}
return last + 1;
}
class Solution {
public:
int removeDuplicates(vector& nums) {
int lastIndex = 0;
for(int i = 1; i 0 ? lastIndex + 1 : 0;
}
};
public int removeDuplicates(int[] nums) {
int i=0; int j= 1; int localRepeat = 1;
while(j<nums.length){
if(nums[i] == nums[j]){
if(localRepeat<2){
localRepeat++;
i++;
nums[i]=nums[j];
}else {
j++;
localRepeat++;
}
}else {
i++;
nums[i]=nums[j];
j++;
localRepeat=1;
}
}
return i+1;
}
The time of arraycopy() is O(n). So time complexity is n square.
https://uploads.disquscdn.com/images/157e46ab84dcf67daeefce97b92dbab65e24a985749e01446235f4205b65d7be.png
public class RemoveDuplicatesFromSortedArray {
public static int[] removeDuplicates(int[] a) {
int i = 1;
while (i < a.length) {
if (a[i] == a[i – 1]) {
System.arraycopy(a, i + 1, a, i, a.length – i – 1);
a = Arrays.copyOf(a, a.length – 1);
} else {
i++;
}
}
return a;
}
public static void main(String[] args) {
int[] a = removeDuplicates(new int[] { 1, 1, 2, 2, 2, 3, 4, 5, 5, 6 });
for (int num : a) {
System.out.println(num);
}
}
}
public int[] removeDuplicates(int[] A) {
List list=Arrays.stream(A).boxed().collect(Collectors.toList());
for(int i=0;ii;j--){
if(list.get(i)==list.get(j)){
list.remove(j);
}}}
int[] array =new int[list.size()];
for(int i=0;i<list.size();i++){
array[i]=(int)list.get(i);
}
return array;
}
public int[] removeDuplicates(int[] A) {
List list=Arrays.stream(A).boxed().collect(Collectors.toList());
for(int i=0;ii;j–){
if(list.get(i)==list.get(j)){
list.remove(j);
}}}
int[] array =new int[list.size()];
for(int i=0;i<list.size();i++){
array[i]=(int)list.get(i);
}
return array;
}
https://uploads.disquscdn.com/images/b40d00a1d19bae2face7bcb76cdd391e0b60502a51bf8d68842d338e68b457b4.png
Use LinkedHashSet, so that only unique elements can be entered and the insertion order preserved.
For in place replacement what we can do is just start from the end of array and keep comparing i with the i -1. And if we see duplicate then just put the ith index value at then end of array. And keep a counter which we increase on every such incident.
Return length – counter.
public class Solution {
public int removeDuplicates(int[] nums) {
int length = nums.length;
int count = 0;
if(length >= 2){
for(int i = length -1 ;i>=0; i--){
if((i -1) >=0){
if(nums[i] == nums[i-1]){
shiftHelper(nums,i);
count++;
}
}
}
}
return length - count;
}
private void shiftHelper(int[] arr,int pos){
for(int i = pos; i< arr.length; i++){
if((i+1) < arr.length){
arr[i] = arr[i+1];
}
}
}
}
This also works.
#include
using namespace std;
class Solution
{
public:
int removeDuplicates(vector& nums)
{
if (nums.size() == 0) return 0;
int i = 0;
for (int j = 1; j < nums.size(); j++)
{
if (nums[i] != nums[j])
{
i++;
nums[i] = nums[j];
}
}
nums.resize(i + 1);
return nums.size();
}
};
Here is an option to remove duplicates for sorted or unsorted array using Java 8 stream API.
public static int[] removeDuplicates(int[] array) {
return IntStream.of(array).distinct().toArray();
}
public static int removeDuplicates(int[] nums) {
int size=0;
if(nums.length==1) return 1;
if(nums.length==0) return 0;
for(int i=0; i<nums.length-1; i++){
if(nums[i]!=nums[i+1]){
nums[++size]=nums[i+1];
}
}
return ++size;
}
Will this also work ?
public static int removeMyDups(int[] arr){
if(arr.length<1)
return 0;
int count=1;
for(int i=0;i <(arr.length)-1;i++){
if(arr[i] != arr[i+1]){
count++;
}
}
return count;
}
Another alternative to find unique size of array (Solution 3).
public static int countUnique(int[] A) {
LinkedHashSet output = new LinkedHashSet();
for(int i =0; i<= A.length – 1 ; i++)
{
output.add(A[i]);
}
return output.size();
}
it does not handle the case when your input is like :
int arr [] = {1,2,2,3,3,4,4,5,5,5,3,2,1,4,8,8,1};
it returns you B array :
[1, 2, 3, 4, 5, 3, 2, 1, 4, 8, 1]
I tried to solve it on LeetCode using a HashSet. My solution was accepted, but probably it ain’t that optimal.
public class Solution {
public int removeDuplicates(int[] A) {
HashSet mySet = new HashSet();
for (int i=0; i<A.length;i++) mySet.add(A[i]) ;
int j = 0 ;
for(int i : mySet) {
A[j] = i;
j++;
}
for(int i=j; i<A.length;i++) A[i] = Integer.MAX_VALUE;
Arrays.sort(A) ;
return mySet.size();
}
}
It seems like Solution 1 is the only solution that addresses the original problem – Solution 2 allocates a new array and Solution 3 only counts the number of duplicates. Also, solution 1 is labeled “naive”, but it seems to have the best possible runtime – O(n).
this as simle you can think just paste on notepad ..than understand the code ..
package arrays;
import java.io.*;
import java.util.Arrays;
public class DuplicateRemove {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println(“enter how many number do you want to sort”);
String str=br.readLine();
int n=Integer.parseInt(str);
int num[]=new int[n];
System.out.println(“enter your numbers”);
for(int i=0;i<n;i++)
{
num[i]=Integer.parseInt(br.readLine());
}
for(int i=0;i<n;i++)
{
System.out.println(num[i]);
}
Arrays.sort(num);
for(int i=1;i<num.length;i++)
{
if(num[i]!=num[i-1])
{
System.out.println("duplicate"+num[i]);
}
}
}
}
I don’t see why Solution 2 is listed here since it seems to be in direct contradiction of the original requirements (do NOT allocate a new array, constant memory use). Listing it here only confuses the reader.
But your solution won’t work in this case:
a=(3,3,4,5,5), as the index of 4 is 2 != 4 and you make the decision to ignore the duplicates in the upper half (5 and 5).
If the sorted array has 5 elements and the middle element is 4 and the first two elements are duplicates, the array looks like (3,3,4,5,6). The index of the middle element is ‘2’ which is not equal to 4. So the duplicate element is in the lower half of the array.
This doesn’t work. What if the middle element is 4 but the first two elements are duplicates…
How we can write amethod to return an array after adding elements to the array
We can use the XOR operator too I guess.
The following should work:
import java.util.Arrays;
public class HelloWorld{
public int[] removeDuplicates(int a[]) {
int previousElement = a[0];
int pos = 0;
for(int i=1; i < a.length; i++) {
int currentElement = a[i];
if((currentElement ^ previousElement) == 0) {
// Same Element again
}
else {
previousElement = currentElement;
pos++;
a[pos] = currentElement;
}
}
return Arrays.copyOf(a, pos+1);
}
public static void main(String []args){
int a[] = {1,2,2,2,3,3,3,4,4,5};
int b[] = new HelloWorld().removeDuplicates(a);
for(int cur: b) {
System.out.println(cur);
}
}
}
Find the middle element of the input array and compare it with its index.
If they are same, the duplicate element(s) will be at the upper half of the array.
Otherwise, it will be at the lower half of the array.
Time complexity = O(nlogn). You can find the code in http://www.algoqueue.com/algoqueue/default/view/3604480/remove-duplicates-in-a-sorted-integer-array-
Good solution. Mine was wrong, I have corrected it. Thanks!
Sorry about that– it should be formatted now. Let me know what you think. Seems simpler to me.
I want to see your solution. Can you put your code inside <pre> <code> tags?
This solution also works:
public static int removeDups(int[] arr){
int count=0;
for(int i=0;i<arr.length-1;i++){
if(arr[i] == arr[i+1]){
count++;
}
}
return (arr.length-count);
}