-4

I wish to write code for this problem:

Given a string, remove duplicates from it in O(n) time and O(1) space.

Now, I have written a code to remove duplicates from a string.

public class RemoveDuplicates
{
    public static void main(String args[])
    {
        String input = "aabbccc";
        char[] inputArray = input.toCharArray();
        for(int i=0;i<inputArray.length;i++)
        {
            for(int j=i+1;j<inputArray.length;j++)
            {
                if(inputArray[i] == inputArray[j])
                    inputArray[j] = ' ';
            }
        }
        input = new String(inputArray);
        input = input.replaceAll("\\s+","");
        System.out.println("The String after removing duplicates is : "+input);
    }
}

Actually, I am taking a character and comparing with the rest, if they are found equal, replace the found character with a space. Finally, remove all the spaces in the string.

I have a basic understanding that it must be O(n^2) implementation (with respect to time) because of using two for loops. How do modify my code for O(n) time and O(1) space complexity?

Or in other words what does O(1) space requirement signify? And should I use a single for loop instead of two for the time requirements?

subham soni
  • 274
  • 1
  • 5
  • 17
  • If you want to remove duplicates that are "not necessarily consecutive", I can't see how it's possible in O(n) time and O(1) space. – Abhishek Bansal Aug 30 '14 at 05:29
  • 2
    Assuming it's only letters and numbers, you can have 36 boolean variables set to false to begin with. Then when you encounter a certain character, set that boolean to true and then delete all subsequent duplicated characters. This is still O(1) because you predefine a limited number of booleans – shieldgenerator7 Aug 30 '14 at 05:41
  • 1
    This question appears to be off-topic because it is about big O notation, not a specific programming problem. – bjb568 Aug 30 '14 at 17:38

2 Answers2

5

O(n) means no nested for loop and O(1) means constant storage needed for your input.

If your input string is constrained to be all ASCII then this problem is really simple.

`
    boolean[] counter = new boolean[256];
    StringBuilder sb = new StringBuilder(input);
    for (int i = 0; i < sb.length(); i++) {
        if (counter[(int) input.charAt(i)]) {
            sb.setCharAt(i, ' ');
        }
        counter[(int) input.charAt(i)] = true;
    }
`

However if the input isn't in ASCII but in Unicode, then it cannot be solved in O(1) space.

Alex Suo
  • 2,977
  • 1
  • 14
  • 22
  • What is constant storage? And can you please explain your code – subham soni Aug 30 '14 at 05:46
  • Constant storage means storage doesn't vary according to the problem size, in this case, the length of the string. – Alex Suo Aug 30 '14 at 05:48
  • Since you have only 256 characters in ASCII, it basically detects if any of them are readily encountered - if yes remove the current character; else set the counter corresponding to the character to be true means it's encountered already. I assume you must know that char can be casted into int. – Alex Suo Aug 30 '14 at 05:58
  • Can you come for a personal chat? – subham soni Aug 30 '14 at 06:03
0

If you string is always sorted you can do it with O(n) , and O(1) space .

    public String removeDuplicates(String input){

    if(input.length() <= 1){
        return input;
    }
    char[] inputArray = input.toCharArray();

    int count = 0;

    for(int i = 1; i < input.length(); ++i){

        if(inputArray[i] != inputArray[count]) {
            inputArray[++count] = inputArray[i];
        }
    }


    return String.valueOf(inputArray, 0, count + 1);
}

but if it's not sorted you have to sort it. which takes O(n lg(n))

or use hash but it's not for O(1) space.

at last you can take a look here