List/Array
- Max/Min subarray
- prefix sum array: pre calculate the sum
- track the current sum and max sum (min product and max product) + greedy
- two pointers (visit each num at most twice)
- use hash table to cache previous state (sum, index, count)
K-sum
- Use dict
- Sort + pointers
- Skip duplications
- Reduce to smaller problems
|
|
Hash
|
|
Subarray
Make sure to use different kind of prefix sum array
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354#1 https://leetcode.com/problems/maximum-subarray/description/def maxSubArray(self, nums):max_sum = nums[0]curr_sum = nums[0]for i in range(1, len(nums)):curr_sum = max(nums[i], curr_sum + nums[i])max_sum = max(max_sum, curr_sum)return max_sum# 2.def maxProduct(self, nums):max_product = nums[0]curr_min = nums[0]curr_max = nums[0]for i in range(1, len(nums)):a = nums[i] * curr_minb = nums[i] * curr_maxc = nums[i]curr_min = min(min(a,b), c)curr_max = max(max(a,b), c)max_product = max(max_product, curr_min, curr_max)return max_product# 3 use hash + prefix sum O(n) O(n)def maxSubArrayLen(self, nums, k):res = 0sums = 0dct = {}for i, num in enumerate(nums):if sums not in dct:dct[sums] = isums += numif sums-k in dct:res = max(res, i-dct[sums-k] + 1)return res# https://leetcode.com/problems/range-addition/description/def getModifiedArray(self, length, updates):# range cache O(N + K) O(1)res = [0] * lengthfor l, r, add in updates:res[l] += addif r + 1 <= length - 1:res[r+1] -= addcurr_sum = 0for i in range(length):curr_sum += res[i]res[i] = curr_sumreturn resMax rectangle
Linked List
https://www.jianshu.com/p/490cb181946f
- fast, slow pointer (cyclic detection, find middle node, find intersection of linked list)
- reverse linked list to simplify problems
- create dummy node pointing to the head
- use prev node to reverse / track
- list with index 0 ~ n-1 can be treated as linked list (next method: nums[curr_index])
- add tmp link to reduce problems (intersection -> detect cycle)
- use dict to achieve O(1) read/delete time for node123456789101112131415161718192021222324252627282930313233# use prev Node# Time: O(N) Space: O(1)def reverseList(self, head):prev, curr = None, headwhile curr:next_node = curr.nextcurr.next = prevprev = currcurr = next_nodereturn prev# fast - slow pointers# Time O(N) Space O(1)def detectCycle(self, head):if not head or not head.next:returnslow = headfast = headwhile fast and fast.next:slow = slow.nextfast = fast.next.nextif slow == fast:slow2 = headwhile slow != slow2:slow = slow.nextslow2 = slow2.nextreturn slowreturn# remove element# 第一种是向后比较结点,发现重复就删掉。因为可能会删掉后面的结点,所以一定要注意cur的判空条件。当正常遍历时,cur可能为空,当删掉了后面结点时cur.next可能为空,都要判断。if node.next.val == val:node.next = node.next.next
Collections of helper functions
- reversed linked list
stack
- in_stack and out_stack to build queue
- stack to check valid syntax, brackets, …
- append index and sign to stack
queue
- one queue to build stack (popleft all but the last one)
deque
- stack + queue 123from collections import dequedq = deque([])# could specify the length of deque
Questions Review
Intervals:
Evidently, two events [s1, e1) and [s2, e2) do not conflict if and only if one of them starts after the other one ends: either e1 <= s2 OR e2 <= s1. By De Morgan’s laws, this means the events conflict when s1 < e2 AND s2 < e1.
https://leetcode.com/problems/my-calendar-i/description/
https://leetcode.com/problems/my-calendar-ii/description/
https://leetcode.com/problems/my-calendar-iii/description/