diff --git a/dynamic_programming/decode_ways.py b/dynamic_programming/decode_ways.py new file mode 100644 index 000000000000..fcd80eb6ade0 --- /dev/null +++ b/dynamic_programming/decode_ways.py @@ -0,0 +1,47 @@ +""" +A message containing letters from A-Z is being encoded to numbers using the +following mapping: +'A' -> 1 +'B' -> 2 +... +'Z' -> 26 +Given a non-empty string containing only digits, +determine the total number of ways to decode it. +""" + +def num_decodings(s: str): + """ + >> num_decodings("12") + 2 + >> num_decodings("226") + 3 + """ + if not s or int(s[0]) == 0: + return 0 + + last = 1 + second_last = 1 + + for i in range(1, len(s)): + # 0 is a special digit since it does not + # correspond to any alphabet but can be + # meaningful if preceeded by 1 or 2 + + if s[i] == "0": + if s[i-1] in {"1", "2"}: + curr = second_last + else: + return 0 + elif 11 <= int(s[i-1:i+1]) <= 26: + curr = second_last + last + else: + curr = last + + last, second_last = curr, last + return last + + +if __name__ == "__main__": + import doctest + + doctest.testmod() diff --git a/hashes/topk.py b/hashes/topk.py new file mode 100644 index 000000000000..51320ed85172 --- /dev/null +++ b/hashes/topk.py @@ -0,0 +1,33 @@ +""" +Given a non-empty list of words, return the k most frequent elements. +Your answer should be sorted by frequency from highest to lowest. +If two words have the same frequency, then the word with the lower +alphabetical order comes first. +""" +import collections + +def topk_frequent(self, words, k): + """ + >> topk_frequent(["i", "love", "leetcode", "i", "love", "coding"], 2) + ["i", "love"] + """ + count = collections.Counter(words) + freqMap = collections.defaultdict(list) + + for word, freq in count.items(): + freqMap[freq].append(word) + + freqs = list(freqMap.keys()) + heapq.heapify(freqs) + + topK = [] + for freq in heapq.nlargest(k, freqs): + topK.extend(sorted(freqMap[freq])) + if len(topK) >= k: + return topK[:k] + + +if __name__ == "__main__": + import doctest + + doctest.testmod()