77# target = 9
88# return [0, 1]
99# Assume each input have exactly one solution
10+ # But you cannot assume all numbers are unique
1011def two_sum (nums , target ):
1112 length = len (nums )
1213 first = 0
@@ -90,6 +91,30 @@ def two_sum_hash(nums, target):
9091 return answer
9192
9293
94+ # There are duplicates, use list as the value of dictionary
95+ def two_sum_hash_list_as_value (nums , target ):
96+ stores = dict ()
97+ for index , value in enumerate (nums ):
98+ if value in stores :
99+ stores [value ].append (index )
100+ else :
101+ stores [value ] = [index ]
102+ result = [- 2 , - 1 ]
103+ for i in range (len (nums )):
104+ remainder = target - nums [i ]
105+ if remainder in stores :
106+ store = stores [remainder ]
107+ if remainder == nums [i ]:
108+ if len (store ) == 2 :
109+ result = store
110+ break
111+ else :
112+ continue
113+ result = [i , store [0 ]]
114+ break
115+ return result
116+
117+
93118print ('\n #1. Two Sum:' )
94119# two_sum_nums = [2, 7, 11, 15, 18, 20, 27]
95120# two_sum_nums = [2, 7, 11]
@@ -100,11 +125,11 @@ def two_sum_hash(nums, target):
100125# two_sum_target = 6
101126# two_sum_target = 0
102127two_sum_target = 7
103- print (two_sum (two_sum_nums , two_sum_target ))
104- print (two_sum_1 (two_sum_nums , two_sum_target ))
105- print (two_sum_2 (two_sum_nums , two_sum_target ))
128+ # print(two_sum(two_sum_nums, two_sum_target))
129+ # print(two_sum_1(two_sum_nums, two_sum_target))
130+ # print(two_sum_2(two_sum_nums, two_sum_target))
106131print (two_sum_hash (two_sum_nums , two_sum_target ))
107- print ('NOT done' )
132+ print (two_sum_hash_list_as_value ( two_sum_nums , two_sum_target ) )
108133
109134
110135# 4. Median of Two Sorted Arrays
@@ -1110,6 +1135,159 @@ def rotate_image(matrix):
11101135rotate_image (rotate_image_matrix )
11111136
11121137
1138+ # 49. Group Anagrams
1139+ # given: ["eat", "tea", "tan", "ate", "nat", "bat"]
1140+ # All inputs will be in lower-case
1141+ # return:
1142+ # [
1143+ # ["ate", "eat","tea"],
1144+ # ["nat", "tan"],
1145+ # ["bat"]
1146+ # ]
1147+ # Time Limit Exceeded, not happy
1148+ def group_anagrams_result_sorted (strs ):
1149+ if strs is None :
1150+ return [[]]
1151+ length = len (strs )
1152+ if length == 0 :
1153+ return [[]]
1154+ if length == 1 :
1155+ return [[strs [0 ]]]
1156+ copy = list ()
1157+ for word in strs :
1158+ copy .append (word )
1159+ for i in range (length ):
1160+ temp = '' .join (sorted (copy [i ]))
1161+ copy [i ] = temp
1162+ counts = [0 ] * length
1163+ for j in range (length ):
1164+ if counts [j ] != 0 :
1165+ continue
1166+ target = copy [j ]
1167+ for k in range (j + 1 , length ):
1168+ if counts [k ] != 0 :
1169+ continue
1170+ if copy [k ] == target :
1171+ counts [k ] = j + 1
1172+ counts [j ] = j + 1
1173+ indexes = dict ()
1174+ for index , item in enumerate (counts ):
1175+ if item in indexes :
1176+ indexes [item ].append (index )
1177+ else :
1178+ indexes [item ] = [index ]
1179+ lengths = dict ()
1180+ for key , value in indexes .items ():
1181+ lengths [key ] = len (value )
1182+ length_indexes = dict ()
1183+ for key , value in lengths .items ():
1184+ if value in length_indexes :
1185+ length_indexes [value ].append (key )
1186+ else :
1187+ length_indexes [value ] = [key ]
1188+ result = list ()
1189+ the_length = len (length_indexes )
1190+ for l in range (the_length ):
1191+ max_index = max (length_indexes )
1192+ max_item = length_indexes [max_index ]
1193+ for each_item in max_item :
1194+ temp = [strs [m ] for m in indexes [each_item ]]
1195+ result .append (temp )
1196+ del length_indexes [max_index ]
1197+ return result
1198+
1199+
1200+ # Time Limit Exceeded, not happy
1201+ def group_anagrams_result_not_sorted (strs ):
1202+ if strs is None :
1203+ return [[]]
1204+ length = len (strs )
1205+ if length == 0 :
1206+ return [[]]
1207+ if length == 1 :
1208+ return [[strs [0 ]]]
1209+ copy = list ()
1210+ for word in strs :
1211+ copy .append (word )
1212+ for i in range (length ):
1213+ temp = '' .join (sorted (copy [i ]))
1214+ copy [i ] = temp
1215+ counts = [0 ] * length
1216+ for j in range (length ):
1217+ if counts [j ] != 0 :
1218+ continue
1219+ target = copy [j ]
1220+ for k in range (j + 1 , length ):
1221+ if counts [k ] != 0 :
1222+ continue
1223+ if copy [k ] == target :
1224+ counts [k ] = j + 1
1225+ counts [j ] = j + 1
1226+ indexes = dict ()
1227+ for index , item in enumerate (counts ):
1228+ if item in indexes :
1229+ indexes [item ].append (index )
1230+ else :
1231+ indexes [item ] = [index ]
1232+ result = list ()
1233+ for key , value in indexes .items ():
1234+ result .append ([strs [l ] for l in value ])
1235+ return result
1236+
1237+
1238+ # https://www.youtube.com/watch?v=DhiT3hDt3ZA
1239+ # I think the one is not correct
1240+ # This one is answer to the following problem:
1241+ # https://www.lintcode.com/en/problem/anagrams/
1242+ def group_anagrams_jikai_tang (strs ):
1243+ dic = {}
1244+ res = []
1245+ for word in strs :
1246+ ordered_str = str (sorted (word ))
1247+ print (ordered_str )
1248+ if ordered_str in dic :
1249+ dic [ordered_str ].append (word )
1250+ else :
1251+ dic [ordered_str ] = [word ]
1252+ for key in dic :
1253+ if len (dic [key ]) >= 2 :
1254+ res += dic [key ]
1255+ return res
1256+
1257+
1258+ # http://www.cnblogs.com/zuoyuan/p/3769993.html
1259+ # Finally accepted. but only 42%, not good enough, will do it later
1260+ def group_anagrams_zuoyuan (strs ):
1261+ if strs is None :
1262+ return [[]]
1263+ length = len (strs )
1264+ if length == 0 :
1265+ return [[]]
1266+ if length == 1 :
1267+ return [[strs [0 ]]]
1268+ dic = {}
1269+ res = []
1270+ for word in strs :
1271+ sorted_word = '' .join (sorted (word ))
1272+ if sorted_word in dic :
1273+ dic [sorted_word ].append (word )
1274+ else :
1275+ dic [sorted_word ] = [word ]
1276+ for key , value in dic .items ():
1277+ res .append (value )
1278+ return res
1279+
1280+
1281+ group_anagrams_strs = ["eat" , "tea" , "tan" , "ate" , "nat" , "bat" ]
1282+ # group_anagrams_strs = ["", "b", 'c', 'ab', 'ba', 'ab']
1283+ print ('\n 49. Group Anagrams:' )
1284+ print (group_anagrams_result_sorted (group_anagrams_strs ))
1285+ print (group_anagrams_result_not_sorted (group_anagrams_strs ))
1286+ # print(group_anagrams_jikai_tang(group_anagrams_strs))
1287+ print (group_anagrams_zuoyuan (group_anagrams_strs ))
1288+ print ('NOT DONE' )
1289+
1290+
11131291# 53. Maximum Subarray
11141292# Find the contiguous subarray within an array(len >= 1) which has the largest sum.
11151293# Array = [−2,1,−3,4,−1,2,1,−5,4]
@@ -2771,7 +2949,7 @@ def product_except_self_constant_space(nums):
27712949# s = "anagram", t = "nagaram", return true.
27722950# s = "rat", t = "car", return false.
27732951# only lowercase alphabets
2774- def is_anagram (s , t ):
2952+ def is_anagram_lowercase (s , t ):
27752953 stores = dict ()
27762954 for i in range (97 , 123 ):
27772955 stores [chr (i )] = 0
@@ -2785,10 +2963,48 @@ def is_anagram(s, t):
27852963 return True
27862964
27872965
2966+ # This one is faster than the lowercase one
2967+ def is_anagram_dict (s , t ):
2968+ s_len = len (s )
2969+ t_len = len (t )
2970+ if s_len != t_len :
2971+ return False
2972+ letters = dict ()
2973+ for item in s :
2974+ if item in letters :
2975+ letters [item ] += 1
2976+ else :
2977+ letters [item ] = 1
2978+ for letter in t :
2979+ if letter not in letters :
2980+ return False
2981+ letters [letter ] -= 1
2982+ if letters [letter ] < 0 :
2983+ return False
2984+ return True
2985+
2986+
2987+ # Faster than lowercase but slower than dict one
2988+ def is_anagram_sort_first (s , t ):
2989+ s_len = len (s )
2990+ t_len = len (t )
2991+ if s_len != t_len :
2992+ return False
2993+ s = '' .join (sorted (s ))
2994+ t = '' .join (sorted (t ))
2995+ if s == t :
2996+ return True
2997+ else :
2998+ return False
2999+
3000+
27883001print ('\n #242. Valid Anagram:' )
27893002is_anagram_s = 'anagram'
27903003is_anagram_t = 'nagaram'
2791- print (is_anagram (is_anagram_s , is_anagram_t ))
3004+ print (is_anagram_lowercase (is_anagram_s , is_anagram_t ))
3005+ print (is_anagram_dict (is_anagram_s , is_anagram_t ))
3006+ print (is_anagram_sort_first (is_anagram_s , is_anagram_t ))
3007+ print (is_anagram_sort_first ('' , '' ))
27923008
27933009
27943010# 258. Add Digits:
@@ -3674,6 +3890,32 @@ def guess_number(n):
36743890print ('NOT done' )
36753891
36763892
3893+ # 378. Kth Smallest Element in a Sorted Matrix
3894+ # n x n matrix, rows and columns are sorted in ascending order
3895+ # Find the kth smallest element in the matrix
3896+ # It is the kth smallest element in the sorted order, not the kth distinct element
3897+ # 1 <= k <= n^2
3898+ def kth_smallest (matrix , k ):
3899+ length = len (matrix )
3900+ positions = [0 ] * length
3901+ result = matrix [0 ][0 ]
3902+ if k == 1 :
3903+ return result
3904+ count = 1
3905+ print ('NOT DONE' )
3906+ return positions * count
3907+
3908+
3909+ kth_smallest_matrix = [
3910+ [1 , 5 , 9 ],
3911+ [10 , 11 , 13 ],
3912+ [12 , 13 , 15 ]
3913+ ]
3914+ kth_smallest_k = 8
3915+ print ('\n #378. Kth Smallest Element in a Sorted Matrix:' )
3916+ print (kth_smallest (kth_smallest_matrix , kth_smallest_k ))
3917+
3918+
36773919# 383. Ransom Note
36783920# Use magazine to construct ransom_note
36793921# Each letter in the magazine can only be used once in your ransom note
@@ -4029,7 +4271,7 @@ def find_anagrams(s, p):
40294271 return []
40304272 result = list ()
40314273 for i in range (s_len - p_len + 1 ):
4032- if is_anagram (s [i :i + p_len ], p ):
4274+ if is_anagram_lowercase (s [i :i + p_len ], p ):
40334275 result .append (i )
40344276 return result
40354277
@@ -4052,10 +4294,73 @@ def is_anagram(a, b):
40524294 return True
40534295
40544296
4297+ # Submission Result: Time Limit Exceeded
4298+ def find_anagrams_sort_first (s , p ):
4299+ if s is None or p is None :
4300+ return []
4301+ s_len = len (s )
4302+ p_len = len (p )
4303+ if s_len < p_len :
4304+ return []
4305+ target = '' .join (sorted (p ))
4306+ result = []
4307+ for i in range (s_len - p_len + 1 ):
4308+ word = s [i :i + p_len ]
4309+ sorted_word = '' .join (sorted (word ))
4310+ if sorted_word == target :
4311+ result .append (i )
4312+ return result
4313+
4314+
4315+ # Accepted, 96.31% and bug free, awesome!!!
4316+ def find_anagrams_dict (s , p ):
4317+ if s is None or p is None :
4318+ return []
4319+ s_len = len (s )
4320+ p_len = len (p )
4321+ if s_len < p_len :
4322+ return []
4323+ if s_len == p_len :
4324+ if '' .join (sorted (s )) == '' .join (sorted (p )):
4325+ return [0 ]
4326+ else :
4327+ return []
4328+ target = {}
4329+ for letter in p :
4330+ if letter in target :
4331+ target [letter ] += 1
4332+ else :
4333+ target [letter ] = 1
4334+ result = []
4335+ current = {}
4336+ for i in range (p_len ):
4337+ if s [i ] in current :
4338+ current [s [i ]] += 1
4339+ else :
4340+ current [s [i ]] = 1
4341+ if current == target :
4342+ result .append (0 )
4343+ for j in range (1 , s_len - p_len + 1 ):
4344+ new_char = s [p_len + j - 1 ]
4345+ if new_char in current :
4346+ current [new_char ] += 1
4347+ else :
4348+ current [new_char ] = 1
4349+ remove_char = s [j - 1 ]
4350+ current [remove_char ] -= 1
4351+ if current [remove_char ] == 0 :
4352+ del current [remove_char ]
4353+ if current == target :
4354+ result .append (j )
4355+ return result
4356+
4357+
40554358find_anagrams_s = 'abab'
40564359find_anagrams_p = 'ab'
40574360print ('\n #438. Find All Anagrams in a String:' )
40584361print (find_anagrams (find_anagrams_s , find_anagrams_p ))
4362+ print (find_anagrams_sort_first (find_anagrams_s , find_anagrams_p ))
4363+ print (find_anagrams_dict (find_anagrams_s , find_anagrams_p ))
40594364
40604365
40614366# 448. Find all numbers disappeared in an array
0 commit comments