Monday, August 24, 2015

Leetcode: Two Sum III - Data structure design

Design and implement a TwoSum class. It should support the following operations: add and find.
add - Add the number to an internal data structure.
find - Find if there exists any pair of numbers which sum is equal to the value.
For example,
add(1); add(3); add(5);
find(4) -> true
find(7) -> false

Understand the problem:
The problem asks for designing a class TwoSum which supports two operations, add and find. There are two data structures / design decisions to think about. 
 1. Use two pointers. Requires the list to be sorted. 
       -- add: insert an element to a sorted array requires O(logn) + O(n) time. 
       -- find: use two pointers. Takes O(n) time. 

2. Use a hash map. 
       -- Add takes O(1) time. 
       -- Find takes O(n) time. 

Note that we have to use  the map instead of the set because we need to counter the number of duplicates for a number. e.g. add(0), add(0) and find(0). 

Code (Java):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class TwoSum {
    private Map<Integer, Integer> map = new HashMap<Integer, Integer>();
     
 public void add(int number) {
     if (map.containsKey(number)) {
         int val = map.get(number) + 1;
         map.put(number, val);
     } else {
         map.put(number, 1);
     }
 }
 
 public boolean find(int value) {
     if (map.isEmpty()) {
         return false;
     }
     Iterator it = map.entrySet().iterator();
 
     // Itearte over the set
     while (it.hasNext()) {
         Map.Entry pair = (Map.Entry) it.next();
         int firstKey =  (int) pair.getKey();
         int firstValue = (int) pair.getValue();
          
         int secondKey = value - firstKey;
          
         // 0 + 0 = 0
         if (firstKey == secondKey && firstValue >= 2) {
             return true;
         else if (firstKey != secondKey && map.containsKey(secondKey)) {
             return true;
         }
     }
     return false;
 }
}

Follow-up: 
What if you add a few, but search very heavily? You need to make sure search only takes O(1) time. Add(num), add num with all the previous added numbers 
search(target), only takes O(1) time. 

Code (Java)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class FasterSearchSum implements TwoSum {
    Set<Integer> set = new HashSet<>();
    List<Integer> nums = new ArrayList<>();
     
    public void store(int input) {
        if (!nums.isEmpty()) {
            for (int num : nums) {
                set.add(input + num);
            }
        }
         
        nums.add(input);
    }
     
    public boolean test(int val) {
        return set.contains(val);
    }
}

No comments:

Post a Comment