1. Given an input integer array, get all distinct elements in it (not necessary to keep their original relative order).
def distinct(arr):
if not arr:
return None
return list(set(arr))
Follow-up questions:
(1) What is the time complexity of your algorithm?
(2) Time complexity of set construction operation, set query operation, and techniques to deal with collisions.
2. Get the first occurrence of each distinct element.
def distinct(arr):
if not arr:
return None
# Resulting list.
result = []
# Elements that have already been added to the resulting list.
added = set()
for ele in arr:
if ele not in added:
added.add(ele)
result.append(ele)
return result
Follow-up questions:
(1) What is the time complexity of your algorithm?
3. Get the second occurrence (if exists, otherwise get the only occurrence) of each distinct element.
def distinct(arr):
if not arr:
return None
from collections import Counter
result = []
cnt = Counter(arr)
occ = dict()
for ele in arr:
if cnt[ele] == 1 or (ele in occ and occ[ele] == 1):
result.append(ele)
if ele in occ:
occ[ele] += 1
else:
occ[ele] = 1
return result
Follow-up questions:
(1) What is the time complexity of your algorithm?
(2) How to solve the problem using only one intermediate data structure (i.e. remove occ)?
(3) How is Counter implemented, and what’s the performance difference between list and Counter?
4. Generic version: Given an array of integers (may have duplicates), retrieve all the nth last occurrence (if exists else return the last occurrence) of each distinct element.
# Optimised solution.
def distinct(arr, n):
"""
Time Complexity: O(n), n is the size of array.
Space Complexity: O(n), n is the size of array.
"""
if not arr:
return None
from collections import Counter, deque
cnt = Counter(arr)
d = deque()
for index in xrange(len(arr) - 1, -1, -1):
ele = arr[index]
if cnt[ele] == n or (cnt[ele] > 0 and cnt[ele] < n):
d.appendleft(ele)
cnt[ele] = 0
else:
cnt[ele] -= 1
return list(d)