2014 interview problems organized

This commit is contained in:
Mari Wahl 2015-01-06 14:14:25 -05:00
parent d29e0d82ad
commit e31b9e4d5f
14 changed files with 159 additions and 285 deletions

View File

@ -1,5 +1,3 @@
#!/usr/bin/env python
__author__ = "bt3" __author__ = "bt3"

View File

@ -3,53 +3,43 @@
__author__ = "bt3" __author__ = "bt3"
""" """
Given an integer x and an unsorted array of integers, describe an algorithm to Given an integer x and an unsorted array of integers, describe an
determine whether two of the numbers add up to x. algorithm to determine whether two of the numbers add up to x.
1. Using hash tables. 1. Using hash tables.
2. Sorting the array and keeping two pointers in the array, one in the beginning and 2. Sorting the array and keeping two pointers in the array, one in
one in the end. Whenever the sum of the current two integers is less than x, move the the beginning and one in the end. Whenever the sum of the current
first pointer forwards, and whenever the sum is greater than x, move the second pointer two integers is less than x, move the first pointer forwards, and
whenever the sum is greater than x, move the second pointer
backwards. O(nln n). backwards. O(nln n).
3. Create a BST with x minus each element in the array. Check whether any element of 3. Create a BST with x minus each element in the array.
the array appears in the BST. It takes O(nlog n) times two. Check whether any element of the array appears in the BST.
It takes O(nlog n) times two.
""" """
def check_sum_hash_table(array, k):
'''
>>> check_sum_hash_table([3, 2, 6, 7, 9, 1], 8)
[(6, 2), (1, 7)]
>>> check_sum_hash_table([5, 2, 6, 7, 9, 1], 4)
[]
>>>
'''
def check_if_sum(arr, num): from collections import defaultdict
seq = sorted(arr)
p1, p2 = 0, len(arr) - 1
while p1 < p2 and p2 < len(arr) and p1 >= 0:
sum_here = seq[p1] + seq[p2]
if sum_here == num:
return True, seq[p1], seq[p2]
elif sum_here < num:
p1 += 1
elif sum_here > num:
p2 -= 1
return False
dict = defaultdict()
res = []
from collections import Counter for i in array:
def check_if_sum2(arr, num): if k-i in dict:
d = Counter() res.append((i, k-i))
for i in arr: del dict[k-i]
d[i] += 1 else:
dict[i] = 1
for i in arr: return res
other = num - i
d[i] -= 1
if d[other] == 1:
return True, other, i
return False
if __name__ == '__main__':
arr = [3, 1, 13, 7, 2, 10] import doctest
num1 = 11 doctest.testmod()
num2 = 6
print(check_if_sum(arr, num1))
print(check_if_sum(arr, num2))
print
print(check_if_sum2(arr, num1))
print(check_if_sum2(arr, num2))

View File

@ -3,16 +3,17 @@
__author__ = "bt3" __author__ = "bt3"
""" find whether two words are anagrams. Since sets do not count occurency, and sorting is O(nlogn) """ find whether two words are anagrams. Since sets do not count occurrence,
we will use hash tables. We scan the first string and add all the character occurences. Then we and sorting is O(nlogn) we will use hash tables. We scan the first string
scan the second tring and decrease all the caracther occurences. If all the counts are zero, it is and add all the character occurrences. Then we scan the second trying and
decrease all the character occurrences. If all the counts are zero, it is
an anagram""" an anagram"""
import string from collections import Counter
def verify_two_strings_are_anagrams(str1, str2): def verify_two_strings_are_anagrams(str1, str2):
ana_table = {key:0 for key in string.ascii_lowercase}
ana_table = Counter()
for i in str1: for i in str1:
ana_table[i] += 1 ana_table[i] += 1
@ -20,24 +21,24 @@ def verify_two_strings_are_anagrams(str1, str2):
for i in str2: for i in str2:
ana_table[i] -= 1 ana_table[i] -= 1
if len(set(ana_table.values())) < 2: return True if len(set(ana_table.values())) < 2:
else: return False return True
else:
return False
''' verify if words are anagrams by comparing a sum of Unicode code
point of the character'''
def get_unicode_sum(word):
s = 0
for p in word:
s += ord(p)
return s
''' verify if words are anagrams by comparying hash functions''' def find_anagram_get_unicode(word1, word2):
return get_unicode_sum(word1) == get_unicode_sum(word2)
def hash_func(astring, tablesize):
sump = 0
for p in astring:
sump += ord(p)
return sump%tablesize
def find_anagram_hash_function(word1, word2):
tablesize = 11
return hash_func(word1, tablesize) == hash_func(word2, tablesize)
@ -47,10 +48,8 @@ if __name__ == '__main__':
str2 = 'aniram' str2 = 'aniram'
str3 = 'anfaam' str3 = 'anfaam'
print verify_two_strings_are_anagrams(str1, str2) assert(verify_two_strings_are_anagrams(str1, str2) == True)
print verify_two_strings_are_anagrams(str1, str3) assert(verify_two_strings_are_anagrams(str1, str3) == False)
print
print find_anagram_hash_function(str1, str2)
print find_anagram_hash_function(str1, str3)
assert(find_anagram_get_unicode(str1, str2) == True)
assert(find_anagram_get_unicode(str1, str3) == False)

View File

@ -3,25 +3,27 @@
__author__ = "bt3" __author__ = "bt3"
def isSubstr(s1, s2):
if s1 in s2 or s2 in s1: return True
return False
def find_substr(s1, s2): def find_substr(s1, s2):
pl, ps = 0, 0
if len(s1) > len(s2): if len(s1) < len(s2):
larger, smaller = s1, s2 bs = s2
ss = s1
else: else:
larger, smaller = s2, s1 bs = s1
while ps < len(smaller) and pl < len(larger): ss = s2
if larger[pl] == smaller[ps]:
ps = 0
for c in bs:
if ss[ps] == c:
ps += 1 ps += 1
else: else:
ps = 0 ps = 0
pl += 1
if ps == len(smaller): if ps == len(ss)-1:
return True return True
return False return False
@ -30,5 +32,5 @@ if __name__ == '__main__':
s1 = 'buffy is a vampire slayer' s1 = 'buffy is a vampire slayer'
s2 = 'vampire' s2 = 'vampire'
s3 = 'angel' s3 = 'angel'
print find_substr(s2, s1) assert(find_substr(s2, s1) == True)
print find_substr(s3, s1) assert(find_substr(s3, s1) == False)

View File

@ -4,8 +4,10 @@ __author__ = "bt3"
'''You are given an array of integers (both positive and negative). Find the contiguous '''
sequence with the largest sum. Return the sum.''' You are given an array of integers (both positive and negative).
Find the contiguous sequence with the largest sum.
'''
def find_largest_sum(array): def find_largest_sum(array):
@ -17,43 +19,21 @@ def find_largest_sum(array):
>>> find_largest_sum([1]) >>> find_largest_sum([1])
1 1
''' '''
if not array: return 0
p1, p2 = 0, 1
all_sums = set()
sum_ = array[p1]
while p1 < p2 and p2 < len(array): sum_ = 0
if sum_ + array[p2] < 0: sum_here = 0
all_sums.add(sum_)
p2 += 1
p1 = p2
sum_ = 0
sum_ += array[p2]
p2 += 1
all_sums.add(sum_)
return max(all_sums)
for i in array:
sum_here += i
def find_largest_sum_simple(array): if sum_here < 0:
''' sum_here = 0
>>> find_largest_sum_simple([-1, 2, -3, 5, 3, 1, -16, 7, 1, -13, 1])
9
>>> find_largest_sum_simple([])
0
>>> find_largest_sum_simple([1])
1
'''
max_sum, sum_ = 0, 0
for item in array: if sum_ < sum_here:
sum_ += item sum_ = sum_here
if max_sum < sum_:
max_sum = sum_
elif sum_ < 0:
sum_ = 0
return max_sum
return sum_

View File

@ -6,43 +6,28 @@ __author__ = "bt3"
from collections import defaultdict from collections import defaultdict
def find_unique_number(arr): def find_unique_number(array):
table = defaultdict(int) '''
total = 0 >>> find_unique_number([1, 3, 6, 1, 5, 6, 9, 3, 7])
for i in arr: [1, 6, 3]
if table[i]: >>> find_unique_number([1, 3, 5, 6, 9, 7])
total -= i []
'''
table = defaultdict()
total = []
for i in array:
if i in table:
total.append(i)
else: else:
total += i table[i] = 1
table[i] +=1
return total return total
def find_unique_number_xor(arr):
xor = 0
for item in arr:
xor ^= item
return xor
def find_unique_char(s):
if len(s) < 2: return True
for i, c in enumerate(s):
for j in s[i+1:]:
if j == c:
return False
return True
if __name__ == '__main__': if __name__ == '__main__':
arr = [1, 3, 5, 6, 1, 5, 6, 3, 7,] import doctest
print(find_unique_number(arr)) doctest.testmod()
print(find_unique_number_xor(arr))
s1 = 'abcdefg'
s2 = 'buffy'
s3 = ''
print
print(find_unique_char(s1))
print(find_unique_char(s2))
print(find_unique_char(s3))

View File

@ -1,36 +0,0 @@
#!/usr/bin/env python
__author__ = "bt3"
from collections import defaultdict
def find_ints_sum(array, sum_):
'''
>>> find_ints_sum([4, 5, 3, 5, 2, 8, 1], 9)
set([(5, 4), (1, 8)])
>>> find_ints_sum([1, 2], 5)
set([])
>>> find_ints_sum([1], 1)
'Not enough values'
'''
if len(array)< 2:
return "Not enough values"
dict = defaultdict()
pairs = set()
for i in array:
if (sum_ - i) in dict:
pairs.add((i, sum_ -i))
else:
dict[i] = True
return pairs
# if the array was sorted, we could do this with two pointers
if __name__ == '__main__':
import doctest
doctest.testmod()

View File

@ -3,9 +3,9 @@
__author__ = "bt3" __author__ = "bt3"
''' Given a real number between 0 and 1 (eg: 0.72), this method print the binary ''' Given a real number between 0 and 1 (eg: 0.72), this method print the
representation. If the Number cannot be represented accurately in binary, with at binary representation. If the Number cannot be represented accurately
most 32 chars, print error: in binary, with at exit most 32 chars, print error:
''' '''
def get_float_rep(num): def get_float_rep(num):

View File

@ -3,77 +3,61 @@
__author__ = "bt3" __author__ = "bt3"
''' using sets '''
def intersection_two_arrays_sets(seq1, seq2): def intersection_two_arrays_sets(seq1, seq2):
''' find the intersection of two arrays using set proprieties ''' '''
>>> intersection_two_arrays_sets([1,2,3,5,7,8], [3,5,6])
set([3, 5])
>>> intersection_two_arrays_sets([1,2,7,8], [3,5,6])
set([])
'''
# O(n)
set1 = set(seq1) set1 = set(seq1)
set2 = set(seq2) set2 = set(seq2)
return set1.intersection(set2) #same as list(set1 & set2
return set1.intersection(set2) #same as list(set1 & set2)
def intersection_two_arrays_On2(seq1, seq2):
'''
>>> intersection_two_arrays_On2([1,2,3,5,7,8], [3,5,6])
[3, 5]
>>> intersection_two_arrays_On2([1,2,7,8], [3,5,6])
[]
'''
''' using merge sort ''' final = []
for i in seq1:
for j in seq2:
if i == j:
final.append(i)
return final
def intersection_two_arrays_On(seq1, seq2):
'''
>>> intersection_two_arrays_On([1,2,3,5,7,8], [3,5,6])
[5, 3]
>>> intersection_two_arrays_On([1,2,7,8], [3,5,6])
[]
'''
final = []
def intersection_two_arrays_ms(seq1, seq2):
''' find the intersection of two arrays using merge sort '''
res = []
while seq1 and seq2: while seq1 and seq2:
if seq1[-1] == seq2[-1]: if seq1[-1] == seq2[-1]:
res.append(seq1.pop()) final.append(seq1.pop())
seq2.pop() seq2.pop()
elif seq1[-1] > seq2[-1]: elif seq1[-1] > seq2[-1]:
seq1.pop() seq1.pop()
else: else:
seq2.pop() seq2.pop()
res.reverse()
return res
return final
''' using binary search '''
def binary_search(seq, key, lo=0, hi=None):
''' binary search iterative algorithm '''
hi = hi or len(seq)
while lo < hi:
mid = (hi+lo) // 2
if seq[mid] == key:
return True
elif key > seq[mid]:
lo = mid + 1
else:
hi = mid
return None
def intersection_two_arrays_bs(seq1, seq2):
''' if A small and B is too large, we can do a binary search on each entry in B '''
''' only works if sorted and the small sequence has not larger nmbers!!!'''
if len(seq1) > len(seq2): seq, key = seq1, seq2
else: seq, key = seq2, seq1
intersec = []
for item in key:
if binary_search(seq, item):
intersec.append(item)
return intersec
def test_intersection_two_arrays(module_name='this module'):
seq1 = [1,2,3,5,7,8]
seq2 = [3,5,6]
assert(set(intersection_two_arrays_sets(seq1,seq2)) == set([3,5]))
assert(intersection_two_arrays_bs(seq1,seq2) == [3,5])
assert(intersection_two_arrays_ms(seq1,seq2) == [3,5])
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__': if __name__ == '__main__':
test_intersection_two_arrays() import doctest
doctest.testmod()

View File

@ -25,13 +25,7 @@ def beating_stock(array):
if __name__ == '__main__':
array = [7, 2, 3, 6, 5, 8, 5, 3, 4]
print(array)
print("Profit: %d, buying at %d, selling at %d." %(beating_stock(array)))
array = [7, 2, 3, 6, 5, 8, 5, 3, 4]
print(array)
print("The best profit is %d, buying at %d, selling at %d." %(beating_stock(array)))

View File

@ -24,11 +24,11 @@ def check_if_ransom_note(magazines, note):
if __name__ == '__main__':
magazines1 = "avfegthhgrebvkdsvnijnvyijfdmckdsmovkmmfvskumvl;cdkmioswckofjbkreenyukjemjgnmkmvkmnvdkmvkr g gmvdvmldm vldfkmbldkmlvdkm"
magazines2 = "adfsfa"
note = "you should disobey"
magazines1 = "avfegthhgrebvkdsvnijnvyijfdmckdsmovkmmfvskumvl;cdkmioswckofjbkreenyukjemjgnmkmvkmnvdkmvkr g gmvdvmldm vldfkmbldkmlvdkm" print(check_if_ransom_note(magazines1, note))
magazines2 = "adfsfa" print(check_if_ransom_note(magazines2, note))
note = "you should disobey"
print(check_if_ransom_note(magazines1, note))
print(check_if_ransom_note(magazines2, note))

View File

@ -12,5 +12,5 @@ def revert(string):
if __name__ == '__main__': if __name__ == '__main__':
string = "Google is fun!" string = "buffy is fun!"
print(revert(string)) print(revert(string))

View File

@ -6,8 +6,8 @@ __author__ = "bt3"
def invert_word(word): def invert_word(word):
""" """
>>> invert_word('stripe is awesome') >>> invert_word('buffy is awesome')
'awesome is stripe' 'awesome is buffy'
""" """
new_word = [] new_word = []
@ -21,5 +21,3 @@ if __name__ == '__main__':
import doctest import doctest
doctest.testmod() doctest.testmod()
#word = 'stripe is awesome'
#print invert_word(word)

View File

@ -12,25 +12,6 @@ def reversing_words_setence_py2(s):
words.reverse() words.reverse()
return ' '.join(words) return ' '.join(words)
def reversing_words_setence_py3(s):
p1 = 0
word = ''
arr = []
while p1 < len(s):
if s[p1] != ' ':
word += s[p1]
else:
arr.append(word)
word = ''
p1 += 1
arr.append(word)
new = ''
while arr:
new += arr.pop()
new += ' '
return new
@ -39,6 +20,5 @@ if __name__ == '__main__':
s = "Buffy is a Vampire Slayer" s = "Buffy is a Vampire Slayer"
print reversing_words_setence_py(s) print reversing_words_setence_py(s)
print reversing_words_setence_py2(s) print reversing_words_setence_py2(s)
print reversing_words_setence_py3(s)