-1

What's the time complexity and auxiliary space for this method? Can anyone please tell and explain me the results?

public Set<T> findRepeatedValues(List<T> list){
    Set<T> set = new HashSet<>();
    Set<T> repeatedValues = new HashSet<>();
    for (T i: list) {
        if (!set.add(i)) {
            repeatedValues.add(i);
        }
    }
    return repeatedValues;
}

what happened if I Test my code like below?

@Test
public void findRepeatedStrings(){
    List<String> stringList = new ArrayList<String>(Arrays.asList("ali","mahdi","hadi","mahdi","mojtaba","mohammad","mojtaba"));
    RepeatedValues repeatedValues = new RepeatedValues();
    Set values = repeatedValues.findRepeatedValues(stringList);
    for (Object i :
            values) {
        System.out.println(i);
    }
}
Naman
  • 27,789
  • 26
  • 218
  • 353

2 Answers2

1

Time complexity

The time complexity of your code would be O(n) , where n is the number of elements in the list. Reason:

for (T i : list) { // iterates through all the 'n' elements
    if (!set.add(i)) {
        repeatedValues.add(i);
    }
}

Space complexity

On the other hand, since you're using a Set to temporarily store values, the space required in the worst case for your Set used would be:

Set<T> set = new HashSet<>(list.size()); // all elements are unique

Hence the space complexity of your solution would be O(n) as well. Of course, n is a value that as the size of the list. If the size of the list grows the space required grows as well.

Output

public void printRepeatedStrings(){
    List<String> stringList = Arrays.asList("ali","mahdi","hadi","mahdi","mojtaba","mohammad","mojtaba");
    RepeatedValues<String> repeatedValues = new RepeatedValues<>(); // type 'T' bound 
    repeatedValues.findRepeatedValues(stringList)
                  .forEach(System.out::println); // prints ["mahdi","mojtaba"]
}
Naman
  • 27,789
  • 26
  • 218
  • 353
0

Complexity

  • Time complexity is O(n)
  • Space complexity is O(n)

Explanation

public Set<T> findRepeatedValues(List<T> list){
    // both sets contains n elements: hence space complexity is O(n)
    Set<T> set = new HashSet<>();
    Set<T> repeatedValues = new HashSet<>();

    // iterate over list only once: hence time complexity is O(n)
    for (T i: list) {
        // HashSet add has O(1) time complexity
        if (!set.add(i)) {
            repeatedValues.add(i);
        }
    }

    return repeatedValues;
}

Test

Your test is incorrect. You have to check that returned Set contains required data. It cold be look like:

public static void findRepeatedStrings() {
    List<String> list = Arrays.asList("ali", "mahdi", "hadi", "mahdi", "mojtaba", "mohammad", "mojtaba");
    Set<String> values = new RepeatedValues<String>().findRepeatedValues(list);

    MatcherAssert.assertThat(values, IsCollectionWithSize.hasSize(2));
    MatcherAssert.assertThat(values, IsIterableContainingInOrder.contains("mahdi", "mojtaba"));
}
Oleg Cherednik
  • 17,377
  • 4
  • 21
  • 35
  • "PS" Such a predicate is not "a non-interfering, stateless predicate", as required by [`filter`](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#filter-java.util.function.Predicate-) (it's very similar to the canonical example of a stateful lambda). This would not be guaranteed to work. – Andy Turner Jan 06 '19 at 18:29