The time complexity of search in HashTable’s key or HashSet is O(1)
Useful functions
collections.Counter(list) can count the element in the list and generate a dictionary
for key, value in dic.items() can iterate the key and value at the same time
sorted(dic.keys()) is sorting the keys
dic.get(key, value) return the dic[key] if the key in dic, otherwise return value you give
Samples
Used for quick search
No.1 Two Sum
1 2 3 4 5 6
dic = {} for i, item inenumerate(nums): if target - item in dic: return [i, dic[target-item]] else: dic[item] = i
No.138 Copy List with Random Pointer
No.202 Happy Number
No.136 Single Number
1 2 3 4 5 6 7
se = set() for num in nums: if num in se: se.remove(num) else: se.add(num) return se.pop()
No.217 Contains Duplicate
Used for record the index
No.3 Longest Substring Without Repearting Characters
Used for record the count
No.49 Group Anagrams
1 2 3 4 5 6 7 8 9 10 11 12
dic = {} for str_ in strs: form = dict(collections.Counter(str_)) form_t = [0for _ inrange(26)] for (key, value) in form.items(): form_t[ord(key) - 97] = value form_t = str(form_t) if form_t in dic: dic[form_t].append(str_) else: dic[form_t] = [str_] return dic.values()
No.347 Top K Frequent Elements Swap the key and values
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
form = dict(collections.Counter(nums)) form_r = {} for key, value in form.items(): if value in form_r: form_r[value].append(key) else: form_r[value] = [key]
sort_fre = sorted(form_r)[::-1] ans = [] count = 0 index = 0 while count < k: ans.extend(form_r[sort_fre[index]]) count += len(form_r[sort_fre[index]]) index += 1 return ans
Fenwick tree is also called Binary Indexed Tree. This kind of data structure can do the calculation of sum from 0 to ith of a list very efficiently.
It can also be used to calculate the frequency. Below is a code used to calculate the number of values from 0 to i.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
classfenwickTree: def__init__(n): self.array = [0] * n
defadd(i): while i < len(self.array): self.array[i] += 1 i += i & -i
defquery(i): ans = 0 while i >= 0: ans += self.array[i] i -= i & -i return ans
Relevant application is in Leetcode No.315.
Heap
Heap is a useful data structure which can store the elements in order. In Python, there is a built in heap library called Heapq.
No.253 - Meeting Room
Make the start time of meeting in order
Use heap to store the end time of each meeting
When the meeting with earliest end time is smaller than the coming meeting with earliest start time, pop that meeting, otherwise not. Then heappush the new end time of the new coming meeting.
Divide the problem into a number of subproblems that are smaller instances of the same problem.
Conquer the subproblems by solving them recursively. If the subproblem sizes are small enough, however, just solve the subproblems in a straightforward manner.
Combine the solutions to the subproblems into the solution for the original problem.
Samples and exercise
Binary search
Decrease the time from $O(n)$ to $O(log(n))$
No.4 Median of Two Sorted Arrays This exercise need we use binary search to find the proper value.
Majority elements
If an element is the majority element(appears more than n/2 times), it should be the majority element in the left half sequence or in the right sequence, otherwise it cannot be the majority element.
Quick sort
Binary sort.
Merge sort
Merge two in-order sequence to a whole sequence. The best time is $O(nlog(n))$
Sometimes normal recursive method will cost a lot of time and not very efficient. In these cases, the DP(Dynamic Programming) can be a good choice. The key of DP is to record the previous solutions.
If a problem has two featrues:
Optimal Substructure
The solution of a problem depends on the solution of its subproblem
Overlapping subproblem
The subproblem needs to be used several times when dealing with the main problem Then we can think about using DP.
Two forms
There are two main ways to do DP. The bottom-up is the most common DP method.
Top-down(recursion with memory)
Establish a memory data structure(like a list) to store the previous values, avoiding the repeat calculation on that value.
Bottom-up(real DP)
Iterate from the bottom. This is better than the previous one because there is no recursive thus no extra cost.
Template
I felt DP is like a 2-demensional array, which can be reduced to a 1-D array. Usually the row i means the action at step i; the column j means a similar result to the original question.
1 2 3 4 5 6
dp = [[.. for i inrange(m)] for j inrange(n)] # Create dp[0][0] = ... # init for i in ... for j in ... dp[i][j] = ... # transition return dp[x][y]
Models
Linear Model
SubArray
dp[i] means subarray s[:i] and you must use s[i-1], return max(dp)
No.152 - Maximum Product Subarray dp1 contains the max product; dp2 contains the min product
List from 0 to i
dp[i] means s[:i], return dp[len(s)]
No.139 - Word Break
No.91 - Decode Ways
No.70 - Climbing Stairs
No.279 - Perfect Squares
No.62 - Unique Paths
Interval Model
The problem can be described as p[i, j]
Palindromic Substring
No.5 - Longest Palindromic Substring dp[i][j] means wether s[i: j + 1] is a palindromic substring
1 2 3 4 5 6 7 8 9
for i inrange(len(s)): dp[i][i] = True
for i inrange(len(s), -1, -1): for j inrange(i, len(s)): if i + 1 > j - 1: dp[i][j] = dp[i][j] or s[i] == s[j] else: dp[i][j] = dp[i][j] or dp[i + 1][j - 1] and s[i] == s[j]
1 2 3 4 5 6 7 8 9 10 11 12 13
# This function will recursively check the left and right value of a previous palindromic string defcheck(s, bg, ed): if bg >= 0and ed < len(s) and s[bg] == s[ed]: return check(s, bg - 1, ed + 1) else: return s[bg + 1: ed]
for i inrange(len(s)): # This palindromic substring is with odd num longest_palin_string1 = check(s, i, i)
# This palindromic substring is with even num, we just took the (i, i+1) because the condition of (i-1,i) is already considered in previous steps longest_palin_string2 = check(s, i, i + 1)
TBD
No.10 - Two string matching with special character
1 2 3 4 5
if j + 1 == '*': p[i][j] = p[i][j+2] or (current_match and p[i+1][j]) else: p[i][j] = current_match and p[i+1][j+1]
No.44 - Wildcard Matching
No.322 - Change Coin
1 2 3 4
for coin in coins: for j inrange(coin, amount+1): d[j] = min(d[j], d[j - coin] + 1) return d[amount]
Package Model
The problem can be described as a decision problem at step i