Leetcode

Lakukan tugas rumah & ujian kamu dengan baik sekarang menggunakan Quizwiz!

DFS Pattern: Binary Tree Path Sum Given a binary tree and a number 'S', find if the tree has a path from root-to-leaf such that the sum of all the node values of that path equals 'S'.

1. Start DFS with the root of the tree. 2. If the current node is not a leaf node, do two things: a. Subtract the value of the current node from the given number to get a new sum => S = S - node.value b. Make two recursive calls for both the children of the current node with the new number calculated in the previous step. 3. At every step, see if the current node being visited is a leaf node and if its value is equal to the given number 'S'. If both these conditions are true, we have found the required root-to-leaf path, therefore return true. 4. If the current node is a leaf but its value is not equal to the given number 'S', return false. Time complexity # The time complexity of the above algorithm is O(N), where 'N' is the total number of nodes in the tree. This is due to the fact that we traverse each node once. Space complexity # The space complexity of the above algorithm will be O(N) in the worst case. This space will be used to store the recursion stack. The worst case will happen when the given tree is a linked list (i.e., every node has only one child).

Space complexity of DFS

O(H), where 'H' is the maximum height of the tree.

DFS Pattern: Path with Maximum Sum Find the path with the maximum sum in a given binary tree. Write a function that returns the maximum sum. A path can be defined as a sequence of nodes between any two nodes and doesn't necessarily pass through the root.

This problem follows the Binary Tree Path Sum pattern and shares the algorithmic logic with Tree Diameter. We can follow the same DFS approach. The only difference will be to ignore the paths with negative sums. Since we need to find the overall maximum sum, we should ignore any path which has an overall negative sum.

DFS Pattern: Count Paths for a Sum Given a binary tree and a number 'S', find all paths in the tree such that the sum of all the node values of each path equals 'S'. Please note that the paths can start or end at any node but all paths must follow direction from parent to child (top to bottom).

This problem follows the Binary Tree Path Sum pattern. We can follow the same DFS approach. But there will be four differences: 1. We will keep track of the current path in a list which will be passed to every recursive call. 2. Whenever we traverse a node we will do two things: a. Add the current node to the current path. b. As we added a new node to the current path, we should find the sums of all sub-paths ending at the current node. If the sum of any sub-path is equal to 'S' we will increment our path count. 3. We will traverse all paths and will not stop processing after finding the first path. 4. Remove the current node from the current path before returning from the function. This is needed to Backtrack while we are going up the recursive call stack to process other paths. Time complexity # The time complexity of the above algorithm is O(N^2) in the worst case, where 'N' is the total number of nodes in the tree. This is due to the fact that we traverse each node once, but for every node, we iterate the current path. The current path, in the worst case, can be O(N) (in the case of a skewed tree). But, if the tree is balanced, then the current path will be equal to the height of the tree, i.e., O(logN). So the best case of our algorithm will be O(NlogN). Space complexity # The space complexity of the above algorithm will be O(N). This space will be used to store the recursion stack. The worst case will happen when the given tree is a linked list (i.e., every node has only one child). We also need O(N) space for storing the currentPath in the worst case. Overall space complexity of our algorithm is O(N).

DFS Pattern: Tree Diameter Given a binary tree, find the length of its diameter. The diameter of a tree is the number of nodes on the longest path between any two leaf nodes. The diameter of a tree may or may not pass through the root.

This problem follows the Binary Tree Path Sum pattern. We can follow the same DFS approach. There will be a few differences: 1. At every step, we need to find the height of both children of the current node. For this, we will make two recursive calls similar to DFS. 2. The height of the current node will be equal to the maximum of the heights of its left or right children, plus '1' for the current node. 3. The tree diameter at the current node will be equal to the height of the left child plus the height of the right child plus '1' for the current node: diameter = leftTreeHeight + rightTreeHeight + 1. To find the overall tree diameter, we will use a class level variable. This variable will store the maximum diameter of all the nodes visited so far, hence, eventually, it will have the final tree diameter.

DFS Pattern: All Paths for a Sum Given a binary tree and a number 'S', find all paths from root-to-leaf such that the sum of all the node values of each path equals 'S'

This problem follows the Binary Tree Path Sum pattern. We can follow the same DFS approach. There will be two differences: 1. Every time we find a root-to-leaf path, we will store it in a list. 2. We will traverse all paths and will not stop processing after finding the first path. Time complexity # The time complexity of the above algorithm is O(N^2)O(N​2​​), where 'N' is the total number of nodes in the tree. This is due to the fact that we traverse each node once (which will take O(N)O(N)), and for every leaf node we might have to store its path which will take O(N). We can calculate a tighter time complexity of O(NlogN) from the space complexity discussion below. Space complexity # If we ignore the space required for the allPaths list, the space complexity of the above algorithm will be O(N)O(N) in the worst case. This space will be used to store the recursion stack. The worst case will happen when the given tree is a linked list (i.e., every node has only one child).

Design Hit Counter Design a hit counter which counts the number of hits received in the past 5 minutes. Each function accepts a timestamp parameter (in seconds granularity) and you may assume that calls are being made to the system in chronological order (ie, the timestamp is monotonically increasing). You may assume that the earliest timestamp starts at 1. It is possible that several hits arrive roughly at the same time.

class HitCounter(object): def __init__(self): self.minheap = [] def hit(self, timestamp): while len(self.minheap) > 0 and (timestamp - self.minheap[0]) >= 300: heappop(self.minheap) heappush(self.minheap, timestamp) def getHits(self, timestamp): while len(self.minheap) > 0 and timestamp - self.minheap[0] >= 300: heappop(self.minheap) return len(self.minheap)

LRU Cache Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put. get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1. put(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item. The cache is initialized with a positive capacity.

class ListNode(object): def __init__(self, key=None, val=None): self.key = key self.val = val self.prev = None self.next = None class LRUCache(object): def __init__(self, capacity): self.cap = capacity self.hashmap = {} self.head = ListNode() self.tail = ListNode() self.head.next = self.tail self.tail.prev = self.head def pop(self): node = self.tail.prev self.tail.prev = node.prev node.prev.next = self.tail return node def moveToHead(self, node): node.prev.next = node.next node.next.prev = node.prev temp = self.head.next self.head.next = node node.prev = self.head node.next = temp temp.prev = node def addToHead(self, node): temp = self.head.next self.head.next = node node.prev = self.head node.next = temp temp.prev = node def get(self, key): if key in self.hashmap: node = self.hashmap[key] self.moveToHead(node) return node.val return -1 def put(self, key, value): if key in self.hashmap: node = self.hashmap[key] node.val = value self.moveToHead(node) else: if len(self.hashmap) == self.cap: node = self.pop() del self.hashmap[node.key] new_node = ListNode(key, value) self.addToHead(new_node) self.hashmap[key] = new_node Note: Use List to record most recently used items. But list need O(n) to insert to delete. Double linked list can achieve both in O(1)

Min Stack Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. push(x) -- Push element x onto stack. pop() -- Removes the element on top of the stack. top() -- Get the top element. getMin() -- Retrieve the minimum element in the stack.

class MinStack(object): def __init__(self): self.stack = [] self.min = [] def push(self, x): if self.stack == []: self.min.append(x) else: self.min.append(min(x, self.min[-1])) self.stack.append(x) def pop(self): self.stack.pop() self.min.pop() def top(self): return self.stack[-1] def getMin(self): return self.min[-1]

Implement Trie (Prefix Tree) Implement a trie with insert, search, and startsWith methods.

class Node(object): def __init__(self): self.children = collections.defaultdict(Node) self.isWord = False class Trie(object): def __init__(self): self.root = Node() def insert(self, word): current = self.root for w in word: current = current.children[w] current.isWord = True def search(self, word): current = self.root for w in word: current = current.children.get(w) if current == None: return False return current.isWord def startsWith(self, prefix): current = self.root for w in prefix: current = current.children.get(w) if current == None: return False return True

Python: dict of node

collections.defaultdict(Node)

Insert Delete GetRandom O(1) Design a data structure that supports all following operations in average O(1) time. insert(val): Inserts an item val to the set if not already present. remove(val): Removes an item val from the set if present. getRandom: Returns a random element from current set of elements. Each element must have the same probability of being returned.

def __init__(self): self.hashmap = {} self.value = [] def insert(self, val): if val in self.hashmap: return False self.value.append(val) self.hashmap[val] = len(self.value) - 1 return True def remove(self, val): if val not in self.hashmap: return False curr_index = self.hashmap[val] last_val = self.value[-1] self.value[curr_index] = last_val self.hashmap[last_val] = curr_index self.value.pop() del self.hashmap[val] return True def getRandom(self): return self.value[random.randint(0, len(self.value)-1)] Note: the challenging part is to randomize in O(1). Hashmap cannot access by index. So an additional list is required.

Find Median from Data Stream Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.

def __init__(self): self.minheap = [] self.maxheap = [] def addNum(self, num): if not self.maxheap or -num >= self.maxheap[0]: heappush(self.maxheap, -num) else: heappush(self.minheap, num) if len(self.maxheap) > len(self.minheap) + 1: heappush(self.minheap, -heappop(self.maxheap)) elif len(self.maxheap) < len(self.minheap): heappush(self.maxheap, -heappop(self.minheap)) def findMedian(self): if len(self.maxheap) == len(self.minheap): return -self.maxheap[0]/2.0 + self.minheap[0]/2.0 else: return -self.maxheap[0]

Word Search Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.

def exist(self, board, word): m = len(board) n = len(board[0]) start = [] for i in range(m): for j in range(n): if self.dfs(board, word, i, j): return True return False def dfs(self, board, word, i, j): if len(word) == 0: return True if i < 0 or i > (len(board) - 1) or j < 0 or j > (len(board[0]) - 1) or word[0] != board[i][j]: return False board[i][j] = '' res = self.dfs(board, word[1:], i+1, j) or \ self.dfs(board, word[1:], i-1, j) or\ self.dfs(board, word[1:], i, j-1) or\ self.dfs(board, word[1:], i, j+1) board[i][j] = word[0] return res

Concatenated Words Given a list of words (without duplicates), please write a program that returns all concatenated words in the given list of words. A concatenated word is defined as a string that is comprised entirely of at least two shorter words in the given array.

def findWords(self, w): if w in self.words: return True res = False for i in range(1, len(w)): if w[:i] in self.words and self.findWords(w[i:]): return True return False def findAllConcatenatedWordsInADict(self, words): """ :type words: List[str] :rtype: List[str] """ self.words = set(words) # if len(words) == 0 or words[0] == "": return [] res = [] for w in words: self.words.remove(w) if self.findWords(w): res.append(w) self.words.add(w) return res

Integer to English Words Convert a non-negative integer to its english words representation. Given input is guaranteed to be less than 231 - 1.

def hundredToWords(self, num): res = '' wordUnder20 = ['', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine',\ 'Ten', 'Eleven', 'Twelve', 'Thirteen', 'Fourteen', 'Fifteen', 'Sixteen', 'Seventeen', 'Eighteen', 'Nineteen'] wordOver20 = ['', '', 'Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety'] if (num//100) > 0: res += ' ' + wordUnder20[num // 100] + ' Hundred' num = num%100 if num < 20: res += ' ' + wordUnder20[num] else: res += ' ' + wordOver20[num//10] + ' ' + wordUnder20[num%10] return strip(res) def numberToWords(self, num): if num == 0: return 'Zero' wordBit = {0: '', 3: 'Thousand', 6: 'Million', 9: 'Billion'} return strip(self.buildWords(num, 0, wordBit)) def buildWords(self, num, bit, wordBit): if num == 0: return '' if num%1000 > 0: res = ' ' + self.hundredToWords(num%1000) + ' ' + wordBit[bit] else: res = '' return self.buildWords(num//(1000), bit+3, wordBit) + res

Subtree of Another Tree Given two non-empty binary trees s and t, check whether tree t has exactly the same structure and node values with a subtree of s. A subtree of s is a tree consists of a node in s and all of this node's descendants. The tree s could also be considered as a subtree of itself.

def isEqual(self, s, t): if not t and not s: return True if not t or not s or s.val != t.val: return False return self.isEqual(s.left, t.left) and self.isEqual(s.right, t.right) def isSubtree(self, s, t): if not t and not s: return True if not t or not s: return False if self.isEqual(s, t): return True return self.isSubtree(s.left, t) or self.isSubtree(s.right, t)

Longest Palindromic Substring Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

def longestPalindrome(self, s): if len(set(s)) <= 1: return s max_len = 1 res = s[0] n = len(s) dp = [[True]*n for _ in range(n)] for i in range(n-1, -1, -1): for j in range(i+1, n): if (dp[i+1][j-1] == True) and (s[i] == s[j]): dp[i][j] = True if (j-i+1) > max_len: max_len = j-i+1 res = s[i:j+1] else: dp[i][j] = False return res Note: DP from bottom to top DP can be applied to the following problems: 1. find min and max 2. does the plan work 3. total number of plan

Serialize and Deserialize Binary Tree Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment. Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.

def notNone(self, q): for p in q: if p: return True return False def num2str(self, num): res = '[' for n in num: if n or n == 0: res += str(n) + ',' else: res +='null,' res = res[0:-1] +']' return res def str2num(self, num_str): num = [] for s in num_str[1:-1].split(','): if s == 'null': num.append(None) else: num.append(int(s)) return num def serialize(self, root): if not root: return [] q = deque() q.append(root) res = [] while self.notNone(q): curr_level = len(q) for i in range(curr_level): node = q.popleft() if node: res.append(node.val) q.append(node.left) q.append(node.right) else: res.append(None) return self.num2str(res) def deserialize(self, data): if data == []: return [] data = self.str2num(data) root = TreeNode(data[0]) q = deque() q.append(root) i = 1 while q: node = q.popleft() if i < len(data) and data[i] != None: left = TreeNode(data[i]) node.left = left q.append(left) if (i+1) < len(data) and data[i+1] != None: right = TreeNode(data[i+1]) node.right = right q.append(right) i += 2 return root

Number of Islands Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.

def numIslands(self, grid): res = 0 for i in range(len(grid)): for j in range(len(grid[0])): if grid[i][j] == '1': self.dfs(grid, i, j) res += 1 return res def dfs(self, grid, i, j): if i < 0 or i > (len(grid) - 1) or j < 0 or j > (len(grid[0]) - 1) or grid[i][j] == '0': return grid[i][j] = '0' direction = [[-1, 0], [1, 0], [0, -1], [0, 1]] for d in direction: new_i = i + d[0] new_j = j + d[1] self.dfs(grid, new_i, new_j) return

Recover Binary Search Tree Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing its structure.

def traverse(self, root): if not root: return self.traverse(root.left) if self.prev and self.prev.val > root.val: if not self.p1: self.p1 = self.prev self.p2 = root self.prev = root self.traverse(root.right) def recoverTree(self, root): self.p1, self.p2, self.prev = None, None, None self.traverse(root) self.p1.val, self.p2.val = self.p2.val, self.p1.val return root Note: use prev to record the last node and compare the val.

Word Break II Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, add spaces in s to construct a sentence where each word is a valid dictionary word. Return all such possible sentences.

def wordBreak(self, s, wordDict): res = [] memo = {} return self.dfs(s, res, wordDict, memo) def dfs(self, s, path, wordDict, memo): if len(s) == 0: return [""] if s in memo: return memo[s] res = [] for word in wordDict: if s[:len(word)] != word: continue for r in self.dfs(s[len(word):], res, wordDict, memo): res.append(word + ("" if not r else " ") + r) memo[s] = res return res Note: Note: use recursive to define how the word is divided

Python: remove the current node from the path to backtrack

del currentPath[-1]

Word Break Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words.

dp = [False] * (len(s)+1) dp[0] = True for i in range(1, len(s)+1): for j in range(0, i): if s[j:i] in wordDict and dp[j]: dp[i] = dp[j] break return dp[len(s)]

Copy List with Random Pointer A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null. Return a deep copy of the list.

hashmap = {} d = Node(0, None, None) new_curr, curr = d, head while curr: node = Node(curr.val, curr.next, None) hashmap[curr] = node new_curr.next = node curr = curr.next new_curr = new_curr.next curr = head while curr: if curr.random: hashmap[curr].random = hashmap[curr.random] curr = curr.next return d.next Note: use hashmap to store the mapping between new node and old node

Two Sum Given an array of integers, return indices of the two numbers such that they add up to a specific target.

hashmap = {} for i, n in enumerate(nums): hashmap[n] = i for i, n in enumerate(nums): m = target - n if m in hashmap and i != hashmap[m]: return [i, hashmap[m]] return [-1, -1]

Group Anagrams Given an array of strings, group anagrams together

hashmap = {} for i, s in enumerate(strs): s = ''.join(sorted(s)) if s in hashmap: hashmap[s].append(i) else: hashmap[s] = [i] res = [] for key in hashmap: temp = [] for i in hashmap[key]: temp.append(strs[i]) res.append(temp) return res

Python: Use defaultdict and Counter to define graph and in degree

hashmap_graph = defaultdict(set) hashmap_degree = Counter({c: 0 for word in words for c in word})

Alien Dictionary There is a new alien language which uses the latin alphabet. However, the order among letters are unknown to you. You receive a list of non-empty words from the dictionary, where words are sorted lexicographically by the rules of this new language. Derive the order of letters in this language.

hashmap_graph = defaultdict(set) hashmap_degree = Counter({c: 0 for word in words for c in word}) for w1, w2 in zip (words, words[1:]): for c, d in zip(w1, w2): if c != d: if d not in hashmap_graph[c]: hashmap_graph[c].add(d) hashmap_degree[d] += 1 break elif len(w2) < len(w1) and len(words) == 2: return "" q = deque([node for node in hashmap_degree if hashmap_degree[node] == 0]) res = [] while q: node = q.popleft() res.append(node) for next_node in hashmap_graph[node]: hashmap_degree[next_node] -= 1 if hashmap_degree[next_node] == 0: q.append(next_node) if len(hashmap_degree) == len(res): return ''.join(res) return ''

Word Ladder Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that: Only one letter can be changed at a time. Each transformed word must exist in the word list. Note:

if endWord not in wordList: return 0 wordList = set(wordList) n = len(beginWord) q = deque() q.append((beginWord, 1)) while q: word, step = q.popleft() for i in range(n): for c in 'abcdefghijklmnopqrstuvwxyz': new_word = word[:i] + c + word[i+1:] if new_word == endWord: return step+1 if new_word in wordList: q.append((new_word, step+1)) wordList.remove(new_word) return 0 Note: shortest path = BFS, similar to maze problem

Merge Two Sorted Lists Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.

if not l1 or not l2: return l1 or l2 else: if l1.val <= l2.val: l1.next = self.mergeTwoLists(l1.next, l2) return l1 else: l2.next = self.mergeTwoLists(l1, l2.next) return l2

Search a 2D Matrix II Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: Integers in each row are sorted in ascending from left to right. Integers in each column are sorted in ascending from top to bottom.

if not matrix or len(matrix) == 0 or len(matrix[0]) == 0: return False i, j = 0, len(matrix[0]) - 1 while i >= 0 and i < len(matrix) and j >= 0 and j < len(matrix[0]): if target == matrix[i][j]: return True if target > matrix[i][j]: i+=1 else: j -= 1 return False

Course Schedule There are a total of numCourses courses you have to take, labeled from 0 to numCourses-1. Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1] Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?

if numCourses < 1: return False res = [] hashmap_graph = {i: [] for i in range(numCourses)} hashmap_degree = {i: 0 for i in range(numCourses)} for child, parent in prerequisites: hashmap_graph[parent].append(child) hashmap_degree[child] += 1 q = deque() for key in hashmap_degree: if hashmap_degree[key] == 0: q.append(key) while q: node = q.pop() res.append(node) for next_node in hashmap_graph[node]: hashmap_degree[next_node] -= 1 if hashmap_degree[next_node] == 0: q.append(next_node) return len(res) == numCourses Note: Two hashmap. One for graph and one for in-degree. Add node with zero degree in Q and BFS

Course Schedule II There are a total of n courses you have to take, labeled from 0 to n-1. Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1] Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take to finish all courses. There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array.

if numCourses < 1: return [] res = [] hashmap_graph = {i: [] for i in range(numCourses)} hashmap_degree = {i: 0 for i in range(numCourses)} q = deque() for child, parent in prerequisites: hashmap_graph[parent].append(child) hashmap_degree[child] += 1 for node in hashmap_degree: if hashmap_degree[node] == 0: q.append(node) while q: node = q.popleft() res.append(node) for next_node in hashmap_graph[node]: hashmap_degree[next_node] -= 1 if hashmap_degree[next_node] == 0: q.append(next_node) if len(res) == numCourses: return res else: return []

Meeting Rooms II Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si < ei), find the minimum number of conference rooms required.

intervals.sort(key = lambda x: x[0]) minheap = [] for meeting in intervals: if minheap and meeting[0] >= minheap[0]: heapreplace(minheap, meeting[1]) else: heappush(minheap, meeting[1]) return len(minheap)

Merge k Sorted Lists Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

minheap = [] heapq.heapify(minheap) d = ListNode() curr = d for l in lists: if l: heappush(minheap, (l.val, l)) while minheap: node = heappop(minheap)[1] curr.next = node if node.next: heappush(minheap, (node.next.val, node.next)) curr = curr.next return d.next Note: Use minheap to record the head of every list

Sliding Window Maximum Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position. Return the max sliding window.

q = deque() res = [] for i, n in enumerate(nums): while q and nums[i] >= nums[q[-1]]: q.pop() q.append(i) if (i - q[0]) == k: q.popleft() if i >= (k - 1): res.append(nums[q[0]]) return res Note: use double ended queue

Pattern: DFS

recursion or stack for the iterative approach to keep track of all the previous (parent) nodes while traversing

Best Time to Buy and Sell Stock Say you have an array for which the ith element is the price of a given stock on day i. If you were only permitted to complete at most one transaction (i.e., buy one and sell one share of the stock), design an algorithm to find the maximum profit. Note that you cannot sell a stock before you buy one.

res = 0 min_val = float("inf") for p in prices: res = max(res, p - min_val) min_val = min(min_val, p) return res

Basic Calculator II Implement a basic calculator to evaluate a simple expression string. The expression string contains only non-negative integers, +, -, *, / operators and empty spaces . The integer division should truncate toward zero.

res = 0 stack = [] pre_op = '+' num = 0 for i, c in enumerate(s): if c in '0123456789': num = 10*num + int(c) if c in '+-*/' or i == (len(s) - 1): if pre_op == '+': stack.append(num) if pre_op == '-': stack.append(-num) if pre_op == '*': pre_num = stack.pop() stack.append(pre_num * num) if pre_op == '/': pre_num = stack.pop() res = abs(pre_num) // abs(num) if pre_num < 0: stack.append(-res) else: stack.append(res) pre_op = c num = 0 return sum(stack)

3Sum Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

res = set() nums.sort() for i in range(len(nums)): p1 = i+1 p2 = len(nums)-1 while p1 < p2: triplet = [nums[i], nums[p1], nums[p2]] if sum(triplet) > 0: p2 -= 1 elif sum(triplet) < 0: p1 += 1 else: res.add(tuple(triplet)) p1 += 1 p2 -= 1 return list(res) Note: Sort first, then double pointer

Python: determine if tree node is leaf

root.left is None and root.right is None

Python: join and sort str

s = ''.join(sorted(s))

Trapping Rain Water Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.

stack = [] res = 0 for i, h in enumerate(height): while stack and h > height[stack[-1]]: j = stack.pop() if stack: left = stack[-1] a = i - left - 1 b = min(h, height[stack[-1]]) - height[j] res += a * b stack.append(i) return res Note: Use ascending stack to find low boundary and descending stack find high boundary. Stack top is the study subject. Push item is the right bound and the top after pop is the left bound.

Largest Rectangle in Histogram Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.

stack = [] res = 0 for i, h in enumerate(heights + [0]): while stack and h < heights[stack[-1]]: j = stack.pop() if stack: left = stack[-1] else: left = -1 a = i - left - 1 b = heights[j] res = max(res, a*b) stack.append(i) return res

Most Common Word Given a paragraph and a list of banned words, return the most frequent word that is not in the list of banned words. It is guaranteed there is at least one word that isn't banned, and that the answer is unique. Words in the list of banned words are given in lowercase, and free of punctuation. Words in the paragraph are not case sensitive. The answer is in lowercase.

words = [] temp = '' for c in paragraph: if lower(c) in 'abcdefghijklmnopqrstuvwxyz': temp += lower(c) else: if temp != '': words.append(temp) temp = '' if temp != '': words.append(temp) hashmap = {} for w in words: w = lower(w) if w not in hashmap: hashmap[w] = 0 hashmap[w] += 1 heap = [] heapq.heapify(heap) print(hashmap) for key in hashmap: if key not in banned: heappush(heap, (-hashmap[key], key)) return heap[0][1]


Set pelajaran terkait

Dispensing Sample Questions, Dispensing (GREEN), Dispensing (BLUE)

View Set

Chap 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 Human Develop

View Set

Key Concepts of Classical Conditioning

View Set

CHAPTER 10: Object-Oriented Thinking

View Set

Final Exam Review for Chapter 6-9

View Set

Exam 3 Test Bank: Mgmt. of pts. w/ oncologic or degenerative neuro disorders

View Set

NUR 243 PrepU Ch 2 Factors Influencing Child Health

View Set