Data Structure and Algorithm patterns
103. Binary Tree Zigzag Level Order Traversal Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between). For example: Given binary tree [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 return its zigzag level order traversal as: [ [3], [20,9], [15,7] ]
zigzagLevelOrder(root) : sol = [ ] travel(root, sol, 0) return sol; travel(curr, sol, level): if(curr == null) return; if(sol.length <= level): newLevel = new LinkedList sol.add(newLevel); collection = sol[level]; if level % 2 == 0: collection.add(curr.val); else: collection.add(0, curr.val); travel(curr.left, sol, level + 1); travel(curr.right, sol, level + 1); O(n) solution by using LinkedList along with ArrayList. So insertion in the inner list and outer list are both O(1), Using DFS and creating new lists when needed.
flatten a Dictionary: input: dict = { "Key1" : "1", "Key2" : { "a" : "2", "b" : "3", "c" : { "d" : "3", "e" : "1" } } } output: { "Key1" : "1", "Key2.a" : "2", "Key2.b" : "3", "Key2.c.d" : "3", "Key2.c.e" : "1" }
-need function flattenDictionary(dict): flatDictionary = {} flattenDictionaryHelper("", dict, flatDictionary) return flatDictionary - need function flattenDictionaryHelper(initialKey, dict, flatDictionary): for (key in dict): value = dict[key] if the value is not a dictionary: # the value is of a primitive type if initialKey is null OR initialKey is "": flatDictionary.put(key, value) else: flatDictionary.put(initialKey + "." + key, value) else: //if the value IS a dictionary if (initialKey == null || initialKey == "") flattenDictionaryHelper(key, value, flatDictionary) **IMPORTANT dict[key] becomes the new dict because value is a dictionary" else: flattenDictionaryHelper(initialKey + "." + key, value, flatDictionary)
BST.findInOrderOf successorNode(inputNode) 20 / \ 9 25 / \ 5 12 / \ 11 14
BST.fn(inputNode): make a while loop if the inputNode has a right node... get the leftmost node of that right node Like this: var rightNode=inputNode.right while (rightNode.left != null){ rightNode =rightNode.left } return rightNode otherwise, if no rightnode, keep getting the ancestor of the inputnode and keep switching the ancestor and child node around until you the ancestor is null or you find an ancestor's left node that equals the child... like this: while (ancestor != null && child != ancestor.left) {//9 20... but 20.right =26 not 9 child = ancestor //11=12 child=9 child =20 ancestor = child.parent //12=9 ancestor= 20 } return ancestor
findDuplicates: You have an array with all the numbers from 1 to N. The array may have duplicate entries and you do not know what N is. With only 4 kilobytes of memory available, how would you print all duplicate elements in the array
Do mergeSort but for the merge part... for the else statement dont forget to include that if a[0]<= b[0] to print out the duplicates if b[0] === a[0]
Search in Rotated Array like Shifted Array search in pramp
Needs 3 things: -find the pivot -Binary search function - If pivot is 0 or if target is less than arr[0], binSearch should happen starting from the pivot. else binsearch should only happen from 0 up to the pivot-1 Pivot while loop needs 3 cases: if (arr[mid] < arr[mid-1]) : return mid else if (arr[mid]>arr[0]) begin=mid+1 else: end=mid-1 binarySearch(arr, begin, end, num): if (arr[mid] ==num) : return mid else if (arr[mid]>num) end = mid-1 else: begin=mid+1
3. Longest Substring Without Repeating Characters Given a string, find the length of the longest substring without repeating characters. Examples: Given "abcabcbb", the answer is "abc", which the length is 3. Given "bbbbb", the answer is "b", with the length of 1. Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring.
Most Optimized: function lengthOfLongestSubstring( s ) : if (s.length ==0) return 0; map = { }; max=0; for (int i=0, j=0; i<s.length; ++i): if (map.containsKey( s[i] ): j = max(j, map[ s[i] ] + 1) map[s.charAt(i)] = i max = max(max, i-j+1) return max; Alternate: fn lengthOfLongestSubstring(s): int n = s.length(); set = { }; var ans = 0, i = 0, j = 0 while (i < n && j < n) { // try to extend the range [i, j] if (!set[ s[i] ] ){ set [(s.charAt(j))]; j+=1 ans = Math.max(ans, j - i); } else: delete set[ s [i] ]; i++ return ans;
141. Linked List Cycle Given a linked list, determine if it has a cycle in it. Follow up: Can you solve it without using extra space?
O(1) Space Solution fn hasCycle(ListNode head) : if(head==null) return false ListNode walker = head ListNode runner = head while(runner.next!=null && runner.next.next!=null): walker = walker.next; runner = runner.next.next; if(walker==runner) return true; return false; Use two pointers, walker and runner. walker moves step by step. runner moves two steps at time. if the Linked List has a cycle walker and runner will meet at some point. Hashmap Solution: fn hasCycle(ListNode head) : var nodesSeen = { }; while (head != null) if (nodesSeen.contains(head)) return true; else nodesSeen.add(head); head = head.next; return false; Pointer Solution fn hasCycle( head) : if (head == null || head.next == null) return false; ListNode slow = head; ListNode fast = head.next; while (slow != fast) : if (fast == null || fast.next == null) return false; slow = slow.next; fast = fast.next.next; return true;
palindrom linked list
can reverse and clone: fn reverseClode(node) head = null while(node!=null): n = new LinkedList(node.data) n.next = head head = n node = node.next return head then just check with two pointers p1 of origHead is equal to p2.data of the reversedClone head can also try the middle node + stack solution!
Find the Duplicate Number Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.
class Solution { public int findDuplicate(int[] nums) { // Find the intersection point of the two runners. int tortoise = nums[0]; int hare = nums[0]; do { tortoise = nums[tortoise]; hare = nums[nums[hare]]; } while (tortoise != hare); // Find the "entrance" to the cycle. int ptr1 = nums[0]; int ptr2 = tortoise; while (ptr1 != ptr2) { ptr1 = nums[ptr1]; ptr2 = nums[ptr2]; } return ptr1; } }
merge intervals Given a collection of intervals, merge all overlapping intervals. For example, Given [1,3],[2,6],[8,10],[15,18], return [1,6],[8,10],[15,18].
intervals.sort((a,b) => a.start<b.start? -1:1) var merged=[intervals[0]] for(var i=1;i<intervals.length;i++){ var last=merged.length-1 if(merged.length==0 || intervals[i].start>merged[last].end){ merged.push(intervals[i]) }else{ merged[last].end=Math.max(merged[last].end, intervals[i].end) } } return merged
bstSeq 4.9
//our main func fn bstSeq(bst): sequences =[] fn recurse(nodes, traveled): noChild= true for each node in nodes: if there is a left node and traveled has this left node's value: noChild=false mark this left node's value as traveled recurse(nodes.concat([left node]), traveled) unmark this left node by deleting it from traveled if there is a right node and traveled has this right node's value: noChild=false mark this right node's value as traveled recurse(nodes.concat([right node]), traveled) unmark this right node by deleting it from traveled if(noChild): push each node's value in nodes in sequences create startTraveled Object and mark the root of the bst as traveled startTraveld = {bst.value: true} remember to put the bst as an array when you recurse recurse([bst], startTraveled) return sequences
GroupByAnagrams sort ['ana', 'cat', 'naa'] into ['ana', 'naa', 'cat]
1) split each array element into an object with two keys { original: string sorted: string.sort() } 2) Sort the mapArray according to each sorted element. mapArray.sort( (el1, el2) => el1.sorted < el2.sorted? 1: -1) 3) return all the original elements of this new Arraymap
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. Follow up: Could you do both operations in O(1) time complexity? Example: LRUCache cache = new LRUCache( 2 /* capacity */ ); cache.put(1, 1); cache.put(2, 2); cache.get(1); // returns 1 cache.put(3, 3); // evicts key 2 cache.get(2); // returns -1 (not found) cache.put(4, 4); // evicts key 1 cache.get(1); // returns -1 (not found) cache.get(3); // returns 3 cache.get(4); // returns 4
1.The key to solve this problem is using a double linked list which enables us to quickly move nodes. 2.The LRU cache is a hash table of keys and double linked nodes. The hash table makes the time of get() to be O(1). The list of double linked nodes make the nodes adding/removal operations O(1). fn Node (key, val) : this.key = key; this.val = val; this.next = null; this.prev = null; fn LRUCache(capacity) : this.list = null; this.map = new Map(); this.head = null; this.tail = null; this.capacity = capacity; this.curSize = 0; LRUCache.prototype.get = function(key) { let node = this.map.get(key); if (!node) { return -1; } if (node === this.head) { return node.val; } // remove node from list if (node === this.tail) { this.tail.prev.next = null; this.tail = this.tail.prev; } else { node.prev.next = node.next; node.next.prev = node.prev; } // insert node to head node.next = this.head; this.head.prev = node; this.head = node; return node.val; LRUCache.prototype.put = function(key, value) { let newNode = new Node(key, value); if (this.curSize === 0) { this.tail = newNode; } else { newNode.next = this.head; this.head.prev = newNode; } this.head = newNode; // this.curSize++; // update if (this.map.get(key)) { let oldNode = this.map.get(key); // remove node if (oldNode === this.tail) { this.tail = this.tail.prev; this.tail.next = null; } else { oldNode.prev.next = oldNode.next; oldNode.next.prev = oldNode.prev; } } else { this.curSize++ if (this.curSize > this.capacity) { //delete tail this.map.delete(this.tail.key); this.tail = this.tail.prev; this.tail.next = null; this.curSize--; } } this.map.set(key, newNode);
63. Unique Paths II Follow up for "Unique Paths": Now consider if some obstacles are added to the grids. How many unique paths would there be? An obstacle and empty space is marked as 1 and 0 respectively in the grid. For example, There is one obstacle in the middle of a 3x3 grid as illustrated below. [ [0,0,0], [0,1,0], [0,0,0] ] The total number of unique paths is 2.
Leetcode solution function findPaths(grid) : var paths = [ ]; var endRow = grid.length - 1; var endCol = grid[0].length - 1; var recurse = function(row, col, currPath) : if (row === endRow && col === endCol) : paths.push(currPath.concat([[row, col]])); else if (row <= endRow && col <= endCol): if (row < endRow && grid[row+1][col] !== 'x'): recurse(row + 1, col, currPath.concat([[row, col]])); if (col < endCol && grid[row][col+1] !== 'x') : recurse(row, col + 1, currPath.concat([[row, col]])); recurse(0, 0, []); return paths; Green Book solution to find one path: fn getPath(grid): if(grid == null OR grid.length ==0) return null path =[ ] failedPoints={ } if (getPathHelper(grid, grid.length - 1, grid[0].length-1, path, failedPoints){ return path } return null fn getPathHelper(grid, row, col, path, failedPoints): if ( col < 0 OR row < 0 OR grid doesn't have a value at this point): return false var p = [row, col] if failedPoints' keys contain p: return false isAtOrigin= row ==0 AND col ==0 if(isAtOrigin OR getPathHelper(grid, row, col-1, path, failedPoints) OR getPathHelper(grid, row-1, col, path, failedPoints): path.add(p) return true failedPoints[p]=1 return false;
Random Node: You are implementing a binary search tree class from scratch, which, in addition to insert, find and delete, has a method getRandomNode() which returns a random node from the tree. All nodes should be equally likely to be chosen. Design and implement an algorithm for getRandomNode, and explain how you would implement the rest of the methods
Tree(): this.root=null Tree.size(): return root==null?0: root.size() Tree.getRandomNode(): if root == null, return null get a RandomIndex and return root's node with this randomIndex TreeNode(d): this.data=d this.size=1 TreeNode.getIthNode(randomIndex): leftSize = this.left==null?0: this.left.size() if randomIndex < leftSize: return left.getIthNode(randomIndex) else if this == leftSize return this else: return right.getIthNode(randomIndex - (leftSize+1))
208. Implement Trie (Prefix Tree) Implement a trie with insert, search, and startsWith methods. Note: You may assume that all inputs are consist of lowercase letters a-z.
Trie.prototype.insert =fn(word): node= this.root for( i =0 to word.length-1): currentCh= word[i] if node's keys doesn't contain this currentCh: //add this current character to the hash map with as an instance of a Trie node[currentCh] = new Trie //move the node to the next node with the currentCh being detected node = node[currentCh] Trie.prototype.search = fn (word): rootNode=this.root node = rootNode.searchPrefix(word) return node != null && node.isEnd() Trie.prototype.searchPrefix(word) : node = this.root for (int i = 0; i < word.length; i++) { curLetter = word[i] if (node.containsKey(curLetter)) { node = node.get(curLetter); } else { return null; } } return node; Trie.prototype.startsWith(prefix) : node = searchPrefix(prefix); return node != null;
buildOrder: You are given a list of projects and a list of dependencies... 4.7
build your graph. Graph has one private property: this.nodes={} Graph has the following prototypes: addNode, addEdge, removeEdge, removeNode IMPORTANT: removeNode must remove that certain node and any node with that certain node as an edge make your main function buildOrder. for each project in projects, add each project as a node to your graph for each dependency in your list of dependencies, add this edge to your graph. graph.addEdge(dependencies[i][1], dependencies[i][0]) IMPORTANT PART: var answers=[] take a currentNode to find the Nodes with noChildren, aka the nodes in graph.nodes with no properties var currentNode= findNodeWithNoChildren(graph) //while we can still find nodes with no children while(currNode !=undefined): answer.push(currNode) graph.removeNode(currNode) currNode = findNodeWithNoChildren(graph) findNodeChildren(graph): should loop through the graph.nodes and return any node that does not have children. otherwise, return undefined time complexity: O(number of projects + number of dependencies)
Top K Frequent Words 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. Example 1: Input: ["i", "love", "leetcode", "i", "love", "coding"], k = 2 Output: ["i", "love"] Explanation: "i" and "love" are the two most frequent words. Note that "i" comes before "love" due to a lower alphabetical order. Example 2: Input: ["the", "day", "is", "sunny", "the", "the", "the", "sunny", "is", "is"], k = 4 Output: ["the", "is", "sunny", "day"] Explanation: "the", "is", "sunny" and "day" are the four most frequent words, with the number of occurrence being 4, 3, 2 and 1 respectively. Note: You may assume k is always valid, 1 ≤ k ≤ number of unique elements. Input words contain only lowercase letters. Follow up: Try to solve it in O(n log k) time and O(n) extra space.
class Solution { public List<String> topKFrequent(String[] words, int k) { Map<String, Integer> count = new HashMap(); for (String word: words) { count.put(word, count.getOrDefault(word, 0) + 1); } List<String> candidates = new ArrayList(count.keySet()); Collections.sort(candidates, (w1, w2) -> count.get(w1) != count.get(w2) ? count.get(w2) - count.get(w1) : w1.compareTo(w2)); return candidates.subList(0, k);
535. Encode and Decode TinyURL Note: This is a companion problem to the System Design problem: Design TinyURL. TinyURL is a URL shortening service where you enter a URL such as https://leetcode.com/problems/design-tinyurl and it returns a short URL such as http://tinyurl.com/4e9iAk. Design the encode and decode methods for the TinyURL service. There is no restriction on how your encode/decode algorithm should work. You just need to ensure that a URL can be encoded to a tiny URL and the tiny URL can be decoded to the original URL.
const maxChars = 6; let charSet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; let urlMap = new Map(); // for bi-directional map let codeMap = new Map(); function encode (longUrl) { if (urlMap.has(longUrl)) return urlMap.get(longUrl); let code = [...Array(maxChars)] .map(_ => Math.floor(Math.random() * charSet.length)) .map(i => charSet[i]) .join(""); urlMap.set(longUrl, code); codeMap.set(code, longUrl); return "http://tinyurl.com/" + code; }; function decode(shortUrl) { let code = shortUrl.substr(-maxChars); if (!codeMap.has(code)) throw new Error(`The given code(${code}) is not existed!`); return codeMap.get(code); };
Route between Nodes: Given a directed graph design an algorithm to find out whether there is a route between two nodes.
fn (graph, A, B, hasVisited): make a hasVisitedHash if(graph doesn't even have starting point A) return false hasVisitedHash[A] = true if hasVisitedHash.hasOwnProperty(B) return true else if hasVisitedHash[A] 's array includes B return true else for (loop through children array of A): if(recurse fn(graph, ***specific child of A****, B, hasVisited)): return true
Sorted Matrix Search: Given an M x N matrix in which each row and each column is sorted in ascending order, write a method to find an element.
fn (matrix, target, begin, end): const m = matrix.length const n = matrix[0].length; //total row begin = begin || 0 end = end || m *n if(begin> end): return can't find number mid = floor((begin + end) /2) row = Math.floor(mid / n) //IMPORTANT: row is midIndex/length of one row col = mid % n // IMPORTANT if matrix[row] [col] ===target: return [row, col] else if (matrix[row][col] >value): adjust the end by calling return fn(matrix, target, begin, mid) else if value at that matrix is too low adjust the beginning by calling return fn(matrix, target, mid+1, end)
Validate BST: Implement a function to check if a binary tree is a binary search tree
fn (node, min, max): if(min != undefined AND node.data<min) OR (max!= undefined AND node.data>max): return false if(fn(node.left, min, node.data) ===false OR fn(node.right, node.data, max)==false): return false return true
Sparse Search: Given a sorted array of strings that is interspersed with empty strings, write a method to find a location of a given string. input: ball, {"at", "", "", "" , ball, "", "" }
fn (word, arr, firstIndex, lastIndex): find the mid point if(the mid value isn't a string), use binary search to find closest middle value that is a string left=mid-1 right = mid +1 while(it isn't a string): if(left < firstIndex AND right >lastIndex): return -1 else if right <= lastIndex AND string[right] hasValue: mid = right break else if left >= firstIndex AND string[left] hasValue: mid = left break left++ right-- if(the mid value is a string): return mid if strings[mid] else if(mid value < word): search more towards right by calling fn(word, arr, mid+1, lastIndex) else if(mid value > word): search more towards the left by calling fn(word, arr, firstIndex, mid-1)
Valid Parentheses Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]" are not.
fn Valid(s) { stack = [ ]; for (let c of s.split("")) { if (c == '(') stack.push(')'); else if (c == '{') stack.push('}'); else if (c == '[') stack.push(']'); else if (stack.length==0 || stack.pop() != c) return false; } return stack.length==0; }
105. Construct Binary Tree from Preorder and Inorder Traversal Given preorder and inorder traversal of a tree, construct the binary tree. Note: You may assume that duplicates do not exist in the tree. For example, given preorder = [3,9,20,15,7] inorder = [9,3,15,20,7] Return the following binary tree: 3 / \ 9 20 / \ 15 7
fn buildTree(preorder, inorder) : return helper(0, 0, inorder.length - 1, preorder, inorder) fn helper(preStart, inStart, inEnd, preorder, inorder) : if (preStart > preorder.length - 1 || inStart > inEnd): return null; var root = new TreeNode(preorder[preStart]) var inIndex = 0; // Index of current root in inorder for (int i = inStart; i <= inEnd; i++) : if (inorder[i] == root.val) : inIndex = i; root.left = helper(preStart + 1, inStart, inIndex - 1, preorder, inorder) root.right = helper(preStart + inIndex - inStart + 1, inIndex + 1, inEnd, preorder, inorder) return root
pathsWithSum: you are given a binary tree in which each node contains an integer value (which might be positive or negative). Design an algorithm to count the number of paths that sum to a given value. The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes)
fn countPathsWithSum(node=root, targetSum, runningSum=0, pathCount={}): if node ==null, return 0 runningSum+=node.data sum = runningSum-targetSum totalPaths = 0 if(pathCount[sum]) totalPaths+=pathCount[sum] if runningSum == targetSum: totalPaths++ incrementHash(pathCount, runningSum, 1) //increase pathCount //left totalPath+= countPathsWithSum(node.left. .,...) //right totalPath += countPathsWithSum(node.right,...,..) incrementHash(pathCount, runningSum, -1) //decrease pathCount return totalPaths fn incrementHash(hash, key, delta): newCount = 0 newCount=hash[key] + delta if newCount==0: delete hash[key] else: hash[key] = newCount //update
215. Kth Largest Element in an Array DescriptionHintsSubmissionsDiscussSolution Pick One Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element. For example, Given [3,2,1,5,6,4] and k = 2, return 5. Note: You may assume k is always valid, 1 ≤ k ≤ array's length.
fn findKthLargest (nums, k) : if (k < 1 || nums == null) : return 0; return getKth(nums.length - k +1, nums, 0, nums.length - 1); function getKth(k, nums, start, end) { var pivot = nums[end]; var left = start; var right = end; while (true) : while (nums[left] < pivot && left < right) : left++; while (nums[right] >= pivot && right > left) : right--; if (left == right) : break; swap(nums, left, right); swap(nums, left, end); if (k == left + 1) : return pivot; else if (k < left + 1) : return getKth(k, nums, start, left - 1); else : return getKth(k, nums, left + 1, end);
First Common Ancestor: Design an algorithm and write code to find the first common ancestor of two nodes in a binary tree. Avoid strong additional nodes in a data structure. Note: This is not necessarily a binary search tree
fn firstCommonAncestor(node1, node2): var currNode = node1 while isAncestor(currNode, node2) == FALSE : if currNode == null: throwError else: currNode = currNode.parent return currNode.value fn isAncestor(currNode, node2): if currNode == node2: return true else: var answer1 = false var answer2 = false if there's a currNode.left: answer1 = isAncestor(currNode.left, node2) answer2 = isAncestor(currNode.right, node2) if answer1 OR ancestor2 is true: return true else return false
100. Same Tree Given two binary trees, write a function to check if they are the same or not. Two binary trees are considered the same if they are structurally identical and the nodes have the same value. Example 1: Input: 1 1 / \ / \ 2 3 2 3 [1,2,3], [1,2,3] Output: true Example 2: Input: 1 1 / \ 2 2 [1,2], [1,null,2] Output: false Example 3: Input: 1 1 / \ / \ 2 1 1 2 [1,2,1], [1,1,2] Output: false
fn isSameTree(TreeNode p, TreeNode q) : if(p == null && q == null) return true; if(p == null || q == null) return false; if(p.val == q.val) return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); return false;
230. Kth Smallest Element in a BST Given a binary search tree, write a function kthSmallest to find the kth smallest element in it. Note: You may assume k is always valid, 1 ≤ k ≤ BST's total elements. Follow up: What if the BST is modified (insert/delete operations) often and you need to find the kth smallest frequently? How would you optimize the kthSmallest routine?
fn kthSmallest(TreeNode root, int k) : int count = countNodes(root.left) if (k <= count) : return kthSmallest(root.left, k) else if (k > count + 1) : return kthSmallest(root.right, k-1-count) // 1 is counted as current node return root.val; fn countNodes(TreeNode n) : if (n == null) return 0; return 1 + countNodes(n.left) + countNodes(n.right)
Binary Tree Level Order Traversal Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level). For example: Given binary tree [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 return its level order traversal as: [ [3], [9,20], [15,7] ]
fn levelOrder(TreeNode root) { List<List<Integer>> res = new ArrayList<List<Integer>>(); levelHelper(res, root, 0); return res; fn levelHelper(List<List<Integer>> res, TreeNode root, int height) { if (root == null) return; if (height >= res.size()) { res.add(new LinkedList<Integer>()); } res.get(height).add(root.val); levelHelper(res, root.left, height+1); levelHelper(res, root.right, height+1); }
386. Lexicographical Numbers Given an integer n, return 1 - n in lexicographical order. For example, given 13, return: [1,10,11,12,13,2,3,4,5,6,7,8,9]. Please optimize your algorithm to use less time and space. The input size may be as large as 5,000,000.
fn lexicalOrder(n) : list = [ ]; curr = 1; for (i =1 to n inclusive; i++): list.push(curr); if (curr * 10 <= n) : curr *= 10; else if (curr % 10 != 9 && curr + 1 <= n) : curr++ else: while ((curr / 10) % 10 == 9): curr /= 10 curr = curr / 10 + 1 return list; The basic idea is to find the next number to add. Take 45 for example: if the current number is 45, the next one will be 450 (450 == 45 * 10)(if 450 <= n), or 46 (46 == 45 + 1) (if 46 <= n) or 5 (5 == 45 / 10 + 1)(5 is less than 45 so it is for sure less than n). We should also consider n = 600, and the current number = 499, the next number is 5 because there are all "9"s after "4" in "499" so we should divide 499 by 10 until the last digit is not "9". It is like a tree, and we are easy to get a sibling, a left most child and the parent of any node.
Sorted Search no Size Listy is a sorted array but it doesn't have a length, how would you find a given element x if it has a findElementAt(index)
need two things: 1. Find the length 2. Binary search Find the length: while loop needs (Listy[i] !==-1 AND Listy[i]<value): i*=2 BinarySearch: needs to include if mid would give -1 end = length begin= length/2 while(begin<end): mid=(end+begin)/2 if(arr[mid] > target OR arr[mid] !=-1): decrease mid else if(too small) increase mid else if equal, return mid
5. 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. Example: Input: "babad" Output: "bab" Note: "aba" is also a valid answer. Example: Input: "cbbd" Output: "bb"
fn longestPalindrome( s ) : maxLen=0 low=0 int len = s.length(); if (len < 2) return s; fn extendPalindrome(s, j, k) : while (j >= 0 && k < s.length() && s.charAt(j) == s.charAt(k)) : j--; k++; if (maxLen < k - j - 1) : lo = j + 1; maxLen = k - j - 1; for (int i = 0; i < len-1; i++) : extendPalindrome(s, i, i); //assume odd length, try to extend Palindrome as possible extendPalindrome(s, i, i+1); //assume even length. return s.substring(lo, lo + maxLen);
11. Container With Most Water Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water. Note: You may not slant the container and n is at least 2.
fn maxArea(height): var maxarea = 0 var l = 0 var r = height.length - 1; while (l < r) { maxarea = Math.max(maxarea, Math.min(height[l], height[r]) * (r - l)); if (height[l] < height[r]) l++; else r--; return maxarea;
Best Time to Buy and Sell Stock with Transaction Fee Your are given an array of integers prices, for which the i-th element is the price of a given stock on day i; and a non-negative integer fee representing a transaction fee. You may complete as many transactions as you like, but you need to pay the transaction fee for each transaction. You may not buy more than 1 share of a stock at a time (ie. you must sell the stock share before you buy again.) Return the maximum profit you can make. Example 1: Input: prices = [1, 3, 2, 8, 4, 9], fee = 2 Output: 8 Explanation: The maximum profit can be achieved by: Buying at prices[0] = 1 Selling at prices[3] = 8 Buying at prices[4] = 4 Selling at prices[5] = 9 The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8. Note: 0 < prices.length <= 50000. 0 < prices[i] < 50000. 0 <= fee < 50000.
fn maxProfit(prices, fee) : cash = 0, hold = -prices[0]; for (int i = 1; i < prices.length; i++) : cash = Math.max(cash, hold + prices[i] - fee); hold = Math.max(hold, cash - prices[i]); return cash; Complexity Analysis Time Complexity: O(N), where N is the number of prices. Space Complexity: O(1), the space used by cash and hold.
53. Maximum Subarray Find the contiguous subarray within an array (containing at least one number) which has the largest sum. For example, given the array [-2,1,-3,4,-1,2,1,-5,4], the contiguous subarray [4,-1,2,1] has the largest sum = 6. If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
fn maxSubArray(A) { var maxSoFar=A[0], maxEndingHere=A[0]; for (var i=1;i<A.length;++i){ maxEndingHere= Math.max(maxEndingHere+A[i],A[i]); maxSoFar=Math.max(maxSoFar, maxEndingHere); } return maxSoFar; }
Permutation without Dups : Write a method to compute all permutations of a string of unique characters
fn permuteString(string): answers=[] fn recurse(currPerm, remainingChars): if remainingChars.length == 0: answers. push the currPerm else: for(var i =0; i<remainingChars.length; i++): recurse(currPerm + remainingChar[i], remainingChars.slice(0,i) + remainingChars.slice(i+1) recurse('', string) return answers
26. Remove Duplicates from Sorted Array Given a sorted array, remove the duplicates in-place such that each element appear only once and return the new length. Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory. Example: Given nums = [1,1,2], Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the new length.
fn removeDuplicates( nums) : if (nums.length == 0): return 0 i = 0 for ( j = 1; j < nums.length; j++) : if (nums[j] != nums[i]) : i++; nums[i] = nums[j]; return i + 1
13. Roman to Integer Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 to 3999.
fn romanToInt(s) : int res = 0; for (int i = s.length() - 1; i >= 0; i--) : char c = s.charAt(i); switch (c) { case 'I': res += (res >= 5 ? -1 : 1); break; case 'V': res += 5; break; case 'X': res += 10 * (res >= 50 ? -1 : 1); break; case 'L': res += 50; break; case 'C': res += 100 * (res >= 500 ? -1 : 1); break; case 'D': res += 500; break; case 'M': res += 1000; break; } return res;
Peaks and Valleys: In an array of integers, a "peak" is an element which is greater than or equal to the adjacent integers and a "valley" is an element which is less than or equal to the adjacent array of integers, sort the array into an alternating sequence of peaks and valleys Input: [5, 3, 1, 2, 3] Output: [5, 1, 3, 2, 3]
fn sortValleyPeak(arr): for(var i = 1; i < arr.length; i+=2): var biggestIndex = maxIndex( arr, i-1 , i , i+1) if(i !=biggestIndex): swap(array, i, biggestIndex) maxIndex(arr, a, b, c): var max = Math.max(arr[i-1], arr[i] , arr[i+1]) if(a gives max) return a else if b gives max return b else return c
172. Factorial Trailing Zeroes Given an integer n, return the number of trailing zeroes in n!. Note: Your solution should be in logarithmic time complexity.
fn trailingZeroes(n): return n == 0 ? 0 : n / 5 + trailingZeroes(n / 5)
Minimal Tree: Given a sorted (increasing) array with unique integer elements, write an algorithm to create a BST with minimal height
fn(arr): find mid point create a node with value of mid point length=arr.length node.left = recurse fn(arr.slice(0, mid)) node.right = recurse fn(arr.slice(mid+1, length)) return node
List of Depths: Given a binary tree, design an algorithm which creates a linked list of all the nodes at each depth
fn(currNode, listOfLinkedLists=[], level = 0): if(currNode == null) //basecase return if(LOLL.length==level) create new Linkedlist() else just get LinkedList at the level where we're at, list = LOLL[level] then list.addToTail(currentNode) if(list.left) recurse fn with (currNode.left, LOLL, level+1) do the same if has list.right return LOLL
Coins (how many ways to give n coins given that you can give in pennies, dimes, or quarters)
fn(value, currCoin) needs a hash if(currCoin ===undefined) currCoin=1 key= [value, currCoin] if key not in hash: base case if(value===0): hash[key]=1 else ways=0 if(depending if currCoin <=1 . or currCount<=5 and such coins ways+= recurse of fn(value - *** 1, 5, 10 or 25*** , ***1, 5, 10, or 25***) Hash[key] = ways return Hash[key]
Construct heap data structure
function BinaryHeap(scoreFunction){ this.content = []; this.scoreFunction = scoreFunction; } BinaryHeap.prototype = { push: function(element) { // Add the new element to the end of the array. this.content.push(element); // Allow it to bubble up. this.bubbleUp(this.content.length - 1); }, pop: function() { // Store the first element so we can return it later. var result = this.content[0]; // Get the element at the end of the array. var end = this.content.pop(); // If there are any elements left, put the end element at the // start, and let it sink down. if (this.content.length > 0) { this.content[0] = end; this.sinkDown(0); } return result; }, remove: function(node) { var length = this.content.length; // To remove a value, we must search through the array to find // it. for (var i = 0; i < length; i++) { if (this.content[i] != node) continue; // When it is found, the process seen in 'pop' is repeated // to fill up the hole. var end = this.content.pop(); // If the element we popped was the one we needed to remove, // we're done. if (i == length - 1) break; // Otherwise, we replace the removed element with the popped // one, and allow it to float up or sink down as appropriate. this.content[i] = end; this.bubbleUp(i); this.sinkDown(i); break; } }, size: function() { return this.content.length; }, bubbleUp: function(n) { // Fetch the element that has to be moved. var element = this.content[n], score = this.scoreFunction(element); // When at 0, an element can not go up any further. while (n > 0) { // Compute the parent element's index, and fetch it. var parentN = Math.floor((n + 1) / 2) - 1, parent = this.content[parentN]; if (score >= this.scoreFunction(parent)) break; swap(parentN, n, this.content) n = parentN; } }, sinkDown: function(n) { // Look up the target element and its score. var length = this.content.length, element = this.content[n], elemScore = this.scoreFunction(element); while(true) { // Compute the indices of the child elements. var child2N = (n + 1) * 2, child1N = child2N - 1; // This is used to store the new position of the element, // if any. var swappedN = null; // If the first child exists (is inside the array)... if (child1N < length) { // Look it up and compute its score. var child1 = this.content[child1N], child1Score = this.scoreFunction(child1); // If the score is less than our element's, we need to swap. if (child1Score < elemScore){ swappedN=child1N } } // Do the same checks for the other child. if (child2N < length) { var child2 = this.content[child2N], child2Score = this.scoreFunction(child2); if (child2Score < (swappedN==null ? elemScore : child1Score)){ swappedN=child2N } } // No need to swap further, we are done. if (swappedN==null) break; // Otherwise, swap and continue. swap(n, swappedN, this.content) n = swappedN; } } }; function swap(i1, i2, arr){ let temp = arr[i1] arr[i1]=arr[i2] arr[i2]= temp }
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.
function copyRandomList(head) { if (head == null) return null; var iter = head var temp; // First round: make copy of each node, // and link them together side-by-side in a single list. while (iter != null) { temp = iter.next; var copy = new RandomListNode(iter.label); iter.next = copy; copy.next = temp; iter = temp; } // Second round: assign random pointers for the copy nodes. iter = head; while (iter != null) { if (iter.random != null) { iter.next.random = iter.random.next; } iter = iter.next.next; } // Third round: restore the original list, and extract the copy list. iter = head; var pseudoHead = new RandomListNode(0); var copy var copyIter = pseudoHead; while (iter != null) { temp = iter.next.next; // extract the copy copy = iter.next; copyIter.next = copy; copyIter = copy; // restore the original list iter.next = temp; iter = temp; } return pseudoHead.next;
build deepClone
function deepClone(o) { var output, v, key; output = Array.isArray(o) ? [] : {}; for (key in o) { v = o[key]; output[key] = (typeof v === "object") ? copy2(v) : v; } return output; }
547. Friend Circles There are N students in a class. Some of them are friends, while some are not. Their friendship is transitive in nature. For example, if A is a direct friend of B, and B is a direct friend of C, then A is an indirect friend of C. And we defined a friend circle is a group of students who are direct or indirect friends. Given a N*N matrix M representing the friend relationship between students in the class. If M[i][j] = 1, then the ith and jth students are direct friends with each other, otherwise not. And you have to output the total number of friend circles among all the students. Example 1: Input: [[1,1,0], [1,1,0], [0,0,1]] Output: 2 Explanation:The 0th and 1st students are direct friends, so they are in a friend circle. The 2nd student himself is in a friend circle. So return 2. Example 2: Input: [[1,1,0], [1,1,1], [0,1,1]] Output: 1 Explanation:The 0th and 1st students are direct friends, the 1st and 2nd students are direct friends, so the 0th and 2nd students are indirect friends. All of them are in the same friend circle, so return 1. Note: N is in range [1,200]. M[i][i] = 1 for all students. If M[i][j] = 1, then M[j][i] = 1.
function findCircleNum(M) : var visited = {}; //visited[i] means if ith person is visited in this algorithm var count = 0; for(var i = 0; i < M.length; i++) : if(visited[i]==undefined) : dfs(M, visited, i); count++; return count; function dfs(M, visited, person) : for(var other = 0; other < M.length; other++) : if(M[person][other] == 1 && visited[other]==undefined) { //We found an unvisited person in the current friend cycle visited[other] = true; dfs(M, visited, other); //Start DFS on this new found person
215. Kth Largest Element in an Array DescriptionHintsSubmissionsDiscussSolution Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element. For example, Given [3,2,1,5,6,4] and k = 2, return 5. Note: You may assume k is always valid, 1 ≤ k ≤ array's length.
function findKthLargest(nums, k) { if (k < 1 || nums == null) { return 0; } return getKth(nums.length - k +1, nums, 0, nums.length - 1); } function getKth(k, nums, start, end) { var pivot = nums[end]; var left = start; var right = end; while (true) { while (nums[left] < pivot && left < right) { left++; } while (nums[right] >= pivot && right > left) { right--; } if (left == right) { break; } swap(nums, left, right); } swap(nums, left, end); if (k == left + 1) { return pivot; } else if (k < left + 1) { return getKth(k, nums, start, left - 1); } else { return getKth(k, nums, left + 1, end); } } function swap(nums, n1, n2) { var tmp = nums[n1]; nums[n1] = nums[n2]; nums[n2] = tmp; }
Sudoku Solver Write the function sudokuSolve that checks whether a given sudoku board (i.e. sudoku puzzle) is solvable.
function getCandidates(board, row, col): // **This is your helper function**** //What values can be placed in empty cell board[row][col] ? stringArray='123456789'.split('') var candidates=[] for(var chr=0; chr<9; chr++): var collision= false for(var i=0; i<9; i++): if(board[row][i]===stringArray[chr] || board[i][col] === stringArray[chr] || board[(row -row % 3) + Math.floor(i/3)][(col -col % 3) + i%3] === stringArray[chr]): collision=true break if(collision===false): candidates.push(stringArray[chr]) return candidates function sudokuSolve(board): var row = -1 var col = -1 var candidates = null for(var r=0; r<9; r++): for(var c= 0; c<9; c++): if(board[r][c] === '.'): var newCandidates = getCandidates(board, r, c) if(candidates == null || (newCandidates.length < candidates.length)): candidates = newCandidates row = r // we remember the row and column if we've got fewer candidates col = c //This is our base case... when there's no empty cell and the sudoku board has already been filled with a valid solution if(candidates === null): return true // The following is when we try to fill up the sudoku board with a working solution for(var i=0; i<candidates.length; i++): board[row][col]= candidates[i] //we try this value if(sudokuSolve(board)): return true board[row][col]='.' //the tried value didn't return true so back to '.' return false
Triple Step given that a child can hop 1, 2, or 3 steps
order matters for this one unlike the coins one fn (n, memo): //base case if(n<0) return 0 else if(n==0): return 1 else memo[n]= fn(n-1, memo) + fn (n-2, memo) +fn(n-3, memo) return memo[n]
160. Intersection of Two Linked Lists Write a program to find the node at which the intersection of two singly linked lists begins. For example, the following two linked lists: A: a1 → a2 ↘ c1 → c2 → c3 ↗ B: b1 → b2 → b3 begin to intersect at node c1. Notes: If the two linked lists have no intersection at all, return null. The linked lists must retain their original structure after the function returns. You may assume there are no cycles anywhere in the entire linked structure. Your code should preferably run in O(n) time and use only O(1) memory.
function getIntersectionNode (headA, headB) { if(headA == null || headB == null) return null; let a = headA; let b = headB; //if a & b have different len, then we will stop the loop after second iteration while( a != b){ //for the end of first iteration, we just reset the pointer to the head of another linkedlist a = a == null? headB : a.next; b = b == null? headA : b.next; } return a; };
119. Pascal's Triangle II Given an index k, return the kth row of the Pascal's triangle. For example, given k = 3, Return [1,3,3,1]. Note: Could you optimize your algorithm to use only O(k) extra space?
function getRow(rowIndex) { let res = []; res.push(1); for (let i = 1; i <= rowIndex; i++) { for (let j = i - 1; j >= 1; j--) { let tmp = res[j - 1] + res[j]; res[j] = tmp; } res.push(1); } return res };
49. Group Anagrams Given an array of strings, group anagrams together. For example, given: ["eat", "tea", "tan", "ate", "nat", "bat"], Return: [ ["ate", "eat","tea"], ["nat","tan"], ["bat"] ]
function groupAnagrams(strs) { if (strs == null || strs.length == 0) return []; let map = {}; for (let s of strs) { let ca = s.split(''); ca.sort(); let keyStr = ca.join(''); if (map[keyStr]==undefined) map[keyStr]=[]; map[keyStr].push(s); } return (Object.values(map)) };
implement insertion sort
function insertionSort(arr): for i from 1 to arr.length-1: x = arr[i] j = i-1 while (j >= 0 AND arr[j] > x): arr[j+1] = arr[j] j-- arr[j+1] = x return arr
127. Word Ladder DescriptionHintsSubmissionsDiscussSolution 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 that beginWord is not a transformed word. For example, Given: beginWord = "hit" endWord = "cog" wordList = ["hot","dot","dog","lot","log","cog"] As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", return its length 5. Note: Return 0 if there is no such transformation sequence. All words have the same length. All words contain only lowercase alphabetic characters. You may assume no duplicates in the word list. You may assume beginWord and endWord are non-empty and are not the same. UPDATE (2017/1/20): The wordList parameter had been changed to a list of strings (instead of a set of strings). Please reload the code definition to get the latest changes.
function ladderLength(beginWord, endWord, wordArr) { let wordList= new Set() wordArr.forEach(word => wordList.add(word)) var visited = new Set(); var queue = []; var level = 1; var letters = 'abcdefghijklmnopqrstuvwxyz'; queue.push(beginWord); visited.add(beginWord); while(queue.length > 0) : var len = queue.length; for(var i = 0 to len) { var word = queue.shift(); // console.log(word) for(var j = 0; j < word.length; j++) { for(var k = 0; k < letters.length; k++) { var newWord = word.substring(0, j) + letters[k] + word.substring(j + 1); // console.log(newWord) if(wordList.has(newWord) && !visited.has(newWord)) { queue.push(newWord); visited.add(newWord); if(newWord === endWord) { return level + 1; } } } } } level++; } return 0; }
235. Lowest Common Ancestor of a Binary Search Tree Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST. According to the definition of LCA on Wikipedia: "The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself)." _______6______ / \ ___2__ ___8__ / \ / \ 0 _4 7 9 / \ 3 5 For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition.
function lowestCommonAncestor (root, p, q) { if(root.val > p.val && root.val > q.val){ return lowestCommonAncestor(root.left, p, q); }else if(root.val < p.val && root.val < q.val){ return lowestCommonAncestor(root.right, p, q); }else{ return root; } };
617. Merge Two Binary Trees Given two binary trees and imagine that when you put one of them to cover the other, some nodes of the two trees are overlapped while the others are not. You need to merge them into a new binary tree. The merge rule is that if two nodes overlap, then sum node values up as the new value of the merged node. Otherwise, the NOT null node will be used as the node of new tree. Example 1: Input: Tree 1 Tree 2 1 2 / \ / \ 3 2 1 3 / \ \ 5 4 7 Output: Merged tree: 3 / \ 4 5 / \ \ 5 4 7 Note: The merging process must start from the root nodes of both trees.
function mergeTrees(t1, t2) : if (t1 == null && t2 == null) return null; val = (t1 == null ? 0 : t1.val) + (t2 == null ? 0 : t2.val); newNode = new TreeNode(val); newNode.left = mergeTrees(t1 == null ? null : t1.left, t2 == null ? null : t2.left); newNode.right = mergeTrees(t1 == null ? null : t1.right, t2 == null ? null : t2.right); return newNode;
771. Jewels and Stones You're given strings J representing the types of stones that are jewels, and S representing the stones you have. Each character in S is a type of stone you have. You want to know how many of the stones you have are also jewels. The letters in J are guaranteed distinct, and all characters in J and S are letters. Letters are case sensitive, so "a" is considered a different type of stone from "A". Example 1: Input: J = "aA", S = "aAAbbbb" Output: 3 Example 2: Input: J = "z", S = "ZZ" Output: 0 Note: S and J will consist of letters and have length at most 50. The characters in J are distinct.
function numJewelsInStones(J, S) { res = 0; setJ = {}; for (let j of J.split("")) setJ[j]= true; for (let s of S.split("")) if (setJ[s]) res++; return res; };
permutation of string WITH DUPS
function permuteWITHDups(string) { var answers = []; var recurse = function(currPerm, remainingChars) if (remainingChars.length === 0) : answers.push(currPerm); else: var usedChars = {}; //IMPORTANT for (var i = 0; i < remainingChars.length; i++) { if (!usedChars[remainingChars[i]]): //IMPORTANT usedChars[remainingChars.charAt(i)] = true; recurse(currPerm + remainingChars[i], remainingChars.slice(0, i) + remainingChars.slice(i+1)) recurse('', string) return answers };
238. Product of Array Except Self Given an array of n integers where n > 1, nums, return an array output such that output[i] is equal to the product of all the elements of nums except nums[i]. Solve it without division and in O(n). For example, given [1,2,3,4], return [24,12,8,6]. Follow up: Could you solve it with constant space complexity? (Note: The output array does not count as extra space for the purpose of space complexity analysis.)
function productExceptSelf(nums) { let output = new Array(nums.length) let productSoFar=1 //left for(let i=0; i<nums.length; i++){ output[i]=productSoFar productSoFar*=nums[i] } productSoFar=1 //right for(let i=nums.length-1; i>=0; i--){ output[i]*=productSoFar productSoFar *=nums[i] } return output };
quickSort algorithm
function quickSort(items, left, right) { var index; if (items.length > 1) { index = partition(items, left, right); if (left < index - 1) { quickSort(items, left, index - 1); } if (index < right) { quickSort(items, index, right); } } return items; } function partition(items, left, right) { var pivot = items[Math.floor((right + left) / 2)], i = left, j = right; while (i <= j) { while (items[i] < pivot) { i++; } while (items[j] > pivot) { j--; } if (i <= j) { swap(items, i, j); i++; j--; } } return i; }
189. Rotate Array DescriptionHintsSubmissionsDiscussSolution Rotate an array of n elements to the right by k steps. For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4]. Note: Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem. [show hint] Hint: Could you do it in-place with O(1) extra space?
function rotate (nums, k) { k %= nums.length; reverse(nums, 0, nums.length - 1); reverse(nums, 0, k - 1); reverse(nums, k, nums.length - 1); } function reverse(nums, start, end) { while (start < end) { let temp = nums[start]; nums[start] = nums[end]; nums[end] = temp; start++; end--; } }
73. Set Matrix Zeroes Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place. click to show follow up.
function setZeroes(matrix) { var col0 = 1, rows = matrix.length, cols = matrix[0].length; for (var i = 0; i < rows; i++) { if (matrix[i][0] == 0) col0 = 0; for (var j = 1; j < cols; j++) if (matrix[i][j] == 0) matrix[i][0] = matrix[0][j] = 0; } for (var i = rows - 1; i >= 0; i--) { for (var j = cols - 1; j >= 1; j--) if (matrix[i][0] == 0 || matrix[0][j] == 0) matrix[i][j] = 0; if (col0 == 0) matrix[i][0] = 0; } };
Subsets Given a set of distinct integers, nums, return all possible subsets (the power set). Note: The solution set must not contain duplicate subsets. For example, If nums = [1,2,3], a solution is: [ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]
function subsetsWithDup(nums) { var result = [] len = nums.length; var used={} helper(nums, 0, len-1, [], result); return result; } function helper(nums, start, end, curArr, result) { result.push(curArr); var i; var used={} for (i = start; i <= end; i++) { // skip duplicates if (used[nums[i]]!==undefined) { continue; } used[nums[i]]=true curArr.push(nums[i]); helper(nums, i + 1, end, curArr.concat(), result); curArr.pop(); } }
24. Swap Nodes in Pairs Given a linked list, swap every two adjacent nodes and return its head. For example, Given 1->2->3->4, you should return the list as 2->1->4->3. Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.
function swapPairs(head) { if (head == null) return null var newhead = new ListNode(-1);//dummy newhead.next = head; var temp = newhead; var one = null var two = null // {dummy->1->2->3->4->null} //explanation for one loop rest are same. while(temp.next!= null && temp.next.next!=null) : // temp points to dummy in the beginning. // one -> 1 one = temp.next //two -> 2 two = temp.next.next // 1-> = 2.next = 3 one.next=two.next; // 2-> = 1 two.next = one //now dummy should point to 2 //if the below is not done dummy->1; temp.next = two // temp was pointing to dummy //temp->1 temp = one // now { dummy->2->1->3->4 } return newhead.next
15. 3Sum Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero. Note: The solution set must not contain duplicate triplets. For example, given array S = [-1, 0, 1, 2, -1, -4], A solution set is: [ [-1, 0, 1], [-1, -1, 2] ]
function triplet(arr, sum=0): arr.sort((a,b)=> a<b? -1:1) result={} for(let i = 0; i<=arr.length-2; i++): var low=i+1 var hi=arr.length-1 while(low<hi && hi<arr.length && low>=0): if(arr[low]+ arr[hi]> sum-arr[i]): hi-- else if(arr[low]+ arr[hi]< sum-arr[i]): low++ else: var a=[arr[i], arr[low], arr[hi]] if(result[a]==undefined) result[a]=1 low-- hi++ return Object. keys(result).map((str)=>str.split(",").map((el)=>parseInt(el)))
139. 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. You may assume the dictionary does not contain duplicate words. For example, given s = "leetcode", dict = ["leet", "code"]. Return true because "leetcode" can be segmented as "leet code".
function(s, wordDict): booleanArray=[] booleanArray[0]=true for(var i = 1; i <= s.length; i++): for(key of wordDict): if(key.length is less than i): if(array[i - key.length]): if(s.substring(i-key.length, i) == (key)): array[i] = true break return array[s.length] || false
Island Count Given a 2D array binaryMatrix of 0s and 1s, implement a function getNumberOfIslands that returns the number of islands of 1s in binaryMatrix. An island is defined as a group of adjacent values that are all 1s. A cell in binaryMatrix is considered adjacent to another cell if they are next to each either on the same row or column. Note that two values of 1 are not part of the same island if they're sharing only a mutual "corner" (i.e. they are diagonally neighbors). Explain and code the most efficient solution possible and analyze its time and space complexities. Example: input: binaryMatrix = [ [0, 1, 0, 1, 0], [0, 0, 1, 1, 1], [1, 0, 0, 1, 0], [0, 1, 1, 0, 0], [1, 0, 1, 0, 1] ] output: 6 # since this is the number of islands in binaryMatrix. # See all 6 islands color-coded below.
getNumberOfIslands(binaryMatrix): var islands = 0 rows = binaryMatrix.length cols=binaryMatrix[0].length for (var i=0; i<binaryMatrix.length; i++): for(var j=0; j<binaryMatrix[0].length; j++): if (value of matrix == 1){ markIsland(binaryMatrix, rows, cols, i, j) islands++ return islands markIsland(binaryMatrix, rows, cols, i, j): q = [ ] //make a queue q.push([i, j]) push the coordinates while (q.length>0){ //breadth first search like queue console.log(q) var item = q.pop() var x = item[0] //row coordinate var y = item[1] //col coordinate if (binaryMatrix[x][y] == 1){ binaryMatrix[x][y] = -1 //we've already visited this coordinate so mark value at coordinate as -1 pushIfValid(q, rows, cols, x-1, y) pushIfValid(q, rows, cols, x, y-1) pushIfValid(q, rows, cols, x+1, y) pushIfValid(q, rows, cols, x, y+1) } } //push if Valid just makes code cleaner //will push neighboring coordinates to the queue if is within the bounds function pushIfValid(q, rows, cols, x, y): if (x >= 0 && x < rows && y >= 0 && y < cols){ q.push([x,y]) }
trap 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. For example, Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.
int trap(vector<int>& height) { if(height == null) return 0; int ans = 0; int size = height.size(); vector<int> left_max(size), right_max(size); left_max[0] = height[0]; for (int i = 1; i < size; i++) { left_max[i] = max(height[i], left_max[i - 1]); } right_max[size - 1] = height[size - 1]; for (int i = size - 2; i >= 0; i--) { right_max[i] = max(height[i], right_max[i + 1]); } for (int i = 1; i < size - 1; i++) { ans += min(left_max[i], right_max[i]) - height[i]; } return ans; }
checkSubtree 4.10. check if T2 is a subtree of the much bigger T1
make a containsTree main function - if T2 is null, return true because null tree is a tree - else use the subTree function subTree function -arguments : T1, T2 -if T1 is null then return false because we can't have an empty T1 when we haven't finished checking T2 -else if T1.data == T2.data AND matchTree of the trees gives true, return true -return true if subTree of T1.left OR T1.right returns true matchTree function (T1, T2) if(T1 ==null AND T2 ==null): return true else if T1 == null OR T2 ==null: return false else if T1.data != T2.data return false else: return true if T1.left matches T2.left AND T1.right matches T2.right, else return false
find intersection of a two linked lists
need a pointer for linkedlist 1 and another pointer for LL2 var startingpoint=[p1,p2] while(pointer 1 != null && pointer 2 !=null): if(p1.data ===p2.data): return p1 else: p1=p1.next p2=p2.next if ran out switch the pointers assignment to linked list if(startingpoint===[p1,p2]): //we came back to starting point, this never intersects return false
Check Balanced: Implement a function to check if a binary tree is balanced. For the purposes of this question, a balanced tree is defined to be a tree such that the heights of the two subtrees of any node never differ by more than one
need getHeight(node) recursive function that has base case return -1 if node == null and recursive case of adding +1 to the Math.max of getHeight(node.left) and getHeight(node.right) need isBalanced(node) : recursive function that calculates the height difference if there is a node - base case that returns true if node is null or if the Math.abs of the height difference is more than 1 - a recursive case that returns true if both isBalanced(node.left) and isBalanced(node.right) are true Each node is touched once per node above it so the run time is NlogN A optimization for the O(n) solution is by using Number.MIN_VALUE if the height difference is greater than one return the Number.MIN_Value. Or if either the node.left or node.right is equal to this value, return this value. Otherwise recurse checkHeight(node.left) and recurse checkHeight(node.riight) if(Math.abs(difference between the two checkHeights) > 1 : return number.min_value else return Math.max(checkHeight(node.left), checkHeight(node.right) + 1 //add one to max height There should be an overarching isBalanced that would return true as long as our getHeight doesn't return Number.MIN_Value
Unique Paths A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below). How many possible unique paths are there?
public class Solution { public int uniquePaths(int m, int n) { Integer[][] map = new Integer[m][n]; for(int i = 0; i<m;i++){ map[i][0] = 1; } for(int j= 0;j<n;j++){ map[0][j]=1; } for(int i = 1;i<m;i++){ for(int j = 1;j<n;j++){ map[i][j] = map[i-1][j]+map[i][j-1]; } } return map[m-1][n-1]; } } The other solution: class Solution { int uniquePaths(int m, int n) { if (m > n) return uniquePaths(n, m); vector<int> cur(m, 1); for (int j = 1; j < n; j++) for (int i = 1; i < m; i++) cur[i] += cur[i - 1]; return cur[m - 1]; } };
Best Time to Buy and Sell Stock II Say you have an array for which the ith element is the price of a given stock on day i. Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
public int maxProfit(int[] prices) { int i = 0; int valley = prices[0]; int peak = prices[0]; int maxprofit = 0; while (i < prices.length - 1) { while (i < prices.length - 1 && prices[i] >= prices[i + 1]) i++; valley = prices[i]; while (i < prices.length - 1 && prices[i] <= prices[i + 1]) i++; peak = prices[i]; maxprofit += peak - valley; } return maxprofit; } Simple One pass solution: public int maxProfit(int[] prices) { int maxprofit = 0; for (int i = 1; i < prices.length; i++) { if (prices[i] > prices[i - 1]) maxprofit += prices[i] - prices[i - 1]; } return maxprofit; }
Implement int sqrt(int x). Compute and return the square root of x. x is guaranteed to be a non-negative integer. Example 1: Input: 4 Output: 2 Example 2: Input: 8 Output: 2 Explanation: The square root of 8 is 2.82842..., and since we want to return an integer, the decimal part will be truncated.
public int sqrt(int x) { if (x == 0) return 0; int left = 1, right = Integer.MAX_VALUE; while (true) { int mid = left + (right - left)/2; if (mid > x/mid) { right = mid - 1; } else { if (mid + 1 > x/(mid + 1)) return mid; left = mid + 1; } } }
two sum
public int[] twoSum(int[] nums, int target) { Map<Integer, Integer> map = new HashMap<>(); for (int i = 0; i < nums.length; i++) { int complement = target - nums[i]; if (map.containsKey(complement)) { return new int[] { map.get(complement), i }; } map.put(nums[i], i); } throw new IllegalArgumentException("No two sum solution"); } or public int[] twoSum(int[] nums, int target) { Map<Integer, Integer> map = new HashMap<>(); for (int i = 0; i < nums.length; i++) { map.put(nums[i], i); } for (int i = 0; i < nums.length; i++) { int complement = target - nums[i]; if (map.containsKey(complement) && map.get(complement) != i) { return new int[] { i, map.get(complement) }; } } throw new IllegalArgumentException("No two sum solution"); }
101. Symmetric Tree DescriptionHintsSubmissionsDiscussSolution Pick One Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). For example, this binary tree [1,2,2,3,4,4,3] is symmetric: 1 / \ 2 2 / \ / \ 3 4 4 3 But the following [1,2,2,null,3,null,3] is not: 1 / \ 2 2 \ \ 3 3 Note: Bonus points if you could solve it both recursively and iteratively.
recursive fn isSymmetric(TreeNode root) : return isMirror(root, root); fn isMirror(TreeNode t1, TreeNode t2) : if (t1 == null && t2 == null) return true; if (t1 == null || t2 == null) return false; return (t1.val == t2.val) && isMirror(t1.right, t2.left) && isMirror(t1.left, t2.right); iterative fn isSymmetric(TreeNode root) { Queue<TreeNode> q = new LinkedList<>(); q.add(root); q.add(root); while (!q.isEmpty()) : TreeNode t1 = q.poll(); TreeNode t2 = q.poll(); if (t1 == null && t2 == null) continue; if (t1 == null || t2 == null) return false; if (t1.val != t2.val) return false; q.add(t1.left); q.add(t2.right); q.add(t1.right); q.add(t2.left); return true;
add two linked list numbers You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. You may assume the two numbers do not contain any leading zero, except the number 0 itself. Example Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) Output: 7 -> 0 -> 8 Explanation: 342 + 465 = 807.
var addTwoNumbers = function(l1, l2) { var dummyHead = new ListNode(0); var p = l1, q = l2, curr = dummyHead; var carry = 0; while (p != null || q != null) { var x = (p != null) ? p.val : 0; var y = (q != null) ? q.val : 0; var sum = carry + x + y; carry = sum / 10; curr.next = new ListNode(sum % 10); curr = curr.next; if (p != null) p = p.next; if (q != null) q = q.next; } if (carry > 0) { curr.next = new ListNode(carry); } return dummyHead.next;
445. Add Two Numbers II You are given two non-empty linked lists representing two non-negative integers. The most significant digit comes first and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. You may assume the two numbers do not contain any leading zero, except the number 0 itself. Follow up: What if you cannot modify the input lists? In other words, reversing the lists is not allowed. Example: Input: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4) Output: 7 -> 8 -> 0 -> 7
var addTwoNumbers = function(l1, l2) { var s1 = []; var s2 = [] while(l1 != null) { s1.push(l1.val); l1 = l1.next; }; while(l2 != null) { s2.push(l2.val); l2 = l2.next; } var sum = 0; var list = new ListNode(0); var carry=0 while (s1.length || s2.length) { sum+=list.val sum+= s1.length? s1.pop():0 sum+= s2.length? s2.pop():0 if(sum >= 10){ carry =1 sum = sum - 10 } list.val=sum sum=0 var head = new ListNode(carry) carry=0 head.next = list list = head } return list.val == 0 ? list.next : list;
189. Rotate Array Rotate an array of n elements to the right by k steps. For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4]. Note: Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem. [show hint] Hint: Could you do it in-place with O(1) extra space?
var array = [1,2,3,4,5,6,7] function rotate(nums, k) { k %= nums.length; reverse(nums, 0, nums.length - 1); reverse(nums, 0, k - 1); reverse(nums, k, nums.length - 1); } function reverse(nums, start, end) { while (start < end) { var temp = nums[start]; nums[start] = nums[end]; nums[end] = temp; start++; end--; } } function rotate2(nums, k){ console.log(nums.slice(k+1, nums.length).concat(nums.slice(0,k+1))) }
Populating Next Right Pointers in Each Node II
var connect = function(root) { var head=root;//The left most node in the lower level var prev=null;//The previous node in the lower level var curr=null;//The current node in the upper level while (head!=null){ curr=head; prev=null; head=null; while (curr!=null){ if (curr.left!=null){ if (prev!=null) prev.next=curr.left; else head=curr.left; prev=curr.left; } if (curr.right!=null){ if (prev!=null) prev.next=curr.right; else head=curr.right; prev=curr.right; } curr=curr.next; } } };
79. 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. For example, Given board = [ ['A','B','C','E'], ['S','F','C','S'], ['A','D','E','E'] ] word = "ABCCED", -> returns true, word = "SEE", -> returns true, word = "ABCB", -> returns false.
var exist = function(board, word) : for(var i =0; i<board.length; i++){ for(var j = 0; j < board[0].length; j++): if(existHelper(board, i, j, word, 0)) return true; return false; function existHelper(board, i, j, word, ind): if(ind == word.length) return true; if(i > board.length-1 || i <0 || j<0 || j >board[0].length-1 || board[i][j]!= word[ind]): return false board[i][j]='*'; var result = existHelper(board, i-1, j, word, ind+1) || existHelper(board, i, j-1, word, ind+1) || existHelper(board, i, j+1, word, ind+1) || existHelper(board, i+1, j, word, ind+1); board[i][j] = word.charAt(ind); return result;
400. Nth Digit Find the nth digit of the infinite integer sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... Note: n is positive and will fit within the range of a 32-bit signed integer (n < 231). Example 1: Input: 3 Output: 3 Example 2: Input: 11 Output: 0 Explanation: The 11th digit of the sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... is a 0, which is part of the number 10.
var findNthDigit = function(n) { var length = 1; var count = 9; var digits = 9; while (n > digits) { length++; count *= 10; digits += length * count; } n = n - (digits - length * count); var position = Math.ceil(n / length); var number = Math.pow(10, (length - 1)) + position - 1; if (n % length === 0) { return number % 10; } else { return parseInt(String(number)[n % length - 1]); } };
274. H-Index Given an array of citations (each citation is a non-negative integer) of a researcher, write a function to compute the researcher's h-index. According to the definition of h-index on Wikipedia: "A scientist has index h if h of his/her N papers have at least h citations each, and the other N − h papers have no more than h citations each." For example, given citations = [3, 0, 6, 1, 5], which means the researcher has 5 papers in total and each of them had received 3, 0, 6, 1, 5 citations respectively. Since the researcher has 3 papers with at least 3 citations each and the remaining two with no more than 3 citations each, his h-index is 3. Note: If there are several possible values for h, the maximum one is taken as the h-index.
var hIndex = function(citations) { var n = citations.length; var buckets = {}; for(let c of citations) { if(c >= n) { if(buckets[n]==undefined){ buckets[n]=0 } buckets[n]++; } else { if(buckets[c]==undefined){ buckets[c]=0 } buckets[c]++; } } var count = 0; //loop through n to 0 for buckets for(var i = n INCLUSIVE; i >= 0; i--) { if(buckets[i] != undefined) count += buckets[i]; if(count >= i) { return i; } } return 0; };
Pow(x, n) Implement pow(x, n). Example 1: Input: 2.00000, 10 Output: 1024.00000 Example 2: Input: 2.10000, 3 Output: 9.26100
var myPow = function(x, n) { if (n < 0) { return 1 / power(x, n); } return power(x, n); }; function power(x, n) { if (n === 0) { return 1; } var v = power(x, parseInt(n/2)); if (n % 2 === 0) { return v * v; } return v times v times x; }
200. 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. Example 1: 11110 11010 11000 00000 Answer: 1 Example 2: 11000 11000 00100 00011 Answer: 3
var numIslands = function(grid) { let count =0 for(let r = 0; r<grid.length; r++){ for(let c = 0; c<grid[0].length; c++){ if(grid[r][c]==1){ mark(r, c, grid) count++ } } } return count }; function mark(r, c, grid){ let q=[] q.push([r, c]) while(q.length){ let item = q.pop() let x= item[0] let y= item[1] if(grid[x][y]==1){ grid[x][y]=-1 pushIfValid(x+1, y, grid, q) pushIfValid(x-1, y, grid, q) pushIfValid(x, y+1, grid, q) pushIfValid(x, y-1, grid, q) } } } function pushIfValid(r, c, grid, q){ if(r>=0 && r<= (grid.length-1) && c>=0 && c<= (grid[0].length-1)){ q.push([r, c]) } }
131. Palindrome Partitioning Given a string s, partition s such that every substring of the partition is a palindrome. Return all possible palindrome partitioning of s. For example, given s = "aab", Return [ ["aa","b"], ["a","a","b"] ]
var partition = function(s): var result = []; partitionHelper(s, result, 0, []); return result; function partitionHelper(s, result, index, curArr) : if (index === s.length): result.push(curArr); return; var len = s.length, j; for (j = index + 1; j <= len; j++) { if (isPalindrome(s.substring(index, j))) : curArr.push(s.substring(index, j)); partitionHelper(s, result, j, curArr.concat()); curArr.pop(); function isPalindrome(a) { var len = a.length, i = 0, j = len - 1; if (len === 0 || len === 1) { return true; } while(i < j) { if (a.charAt(i) !== a.charAt(j)) { return false; } i++; j--; } return true; }
113. Path Sum II Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum. For example: Given the below binary tree and sum = 22, 5 / \ 4 8 / / \ 11 13 4 / \ / \ 7 2 5 1 return [ [5,4,11,2], [5,8,4,5] ]
var pathSum = function(root, sum) : var result = []; if (!root) : return result; pathSumHelper(result, root, [], 0, sum); return result; fn pathSumHelper(result, root, curArr, curSum, target): curArr.push(root.val); curSum += root.val; if ((curSum === target) && !root.left && !root.right) result.push(curArr); return; if (root.left) : pathSumHelper(result, root.left, curArr.concat(), curSum, target); if (root.right) : pathSumHelper(result, root.right, curArr.concat(), curSum, target);
Permutations II (contains duplicates)
var permNoDups = function(string) { var answers = []; var recurse = function(currPerm, remainingChars) { if (remainingChars.length === 0) { answers.push(currPerm); } else { var usedChars = {}; for (var i = 0; i < remainingChars.length; i++) { if (!usedChars[remainingChars.charAt(i)]) { usedChars[remainingChars.charAt(i)] = true; recurse(currPerm + remainingChars.charAt(i), remainingChars.slice(0, i) + remainingChars.slice(i+1)); } } } };
240. 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. For example, Consider the following matrix: [ [1, 4, 7, 11, 15], [2, 5, 8, 12, 19], [3, 6, 9, 16, 22], [10, 13, 14, 17, 24], [18, 21, 23, 26, 30] ] Given target = 5, return true. Given target = 20, return false.
var searchMatrix = function(matrix, target) { if(matrix == null || matrix.length < 1 || matrix[0].length <1) { return false; } let col = matrix[0].length-1; let row = 0; while(col >= 0 && row <= matrix.length-1) { if(target == matrix[row][col]) { return true; } else if(target < matrix[row][col]) { col--; } else if(target > matrix[row][col]) { row++; } } return false; };
297. 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. For example, you may serialize the following tree 1 / \ 2 3 / \ 4 5 as "[1,2,3,null,null,4,5]", just the same as how LeetCode OJ serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.
var serialize = function(root) : var res = ""; function recurse(node): if(node !== null && node.val !== undefined): res += "#" + node.val; if(node.left !== null): recurse(node.left); else: res += "#N"; if(node.right !== null): recurse(node.right); else: res += "#N"; recurse(root); if(res[0] === '#'): res = res.substring(1); return res; var deserialize = function(data) { var nodes = data.split('#'); function recurse(i): if(nodes[i] !== undefined && nodes[i] !== "" && nodes[i] !== 'N'): var root = new TreeNode(parseInt(nodes[i])); i++; var res = LDR(i); i = res.i; root.left = res.node; res = LDR(i); i = res.i; root.right = res.node; return {node : root, i : i}; else: return {node : null, i : ++i}; return recurse(0).node;
669. Trim a Binary Search Tree Given a binary search tree and the lowest and highest boundaries as L and R, trim the tree so that all its elements lies in [L, R] (R >= L). You might need to change the root of the tree, so the result should return the new root of the trimmed binary search tree. Example 1: Input: 1 / \ 0 2 L = 1 R = 2 Output: 1 \ 2 Example 2: Input: 3 / \ 0 4 \ 2 / 1 L = 1 R = 3 Output: 3 / 2 / 1
var trimBST = function(root, L, R) { if (root == null) return null; if (root.val < L) return trimBST(root.right, L, R); if (root.val > R) return trimBST(root.left, L, R); root.left = trimBST(root.left, L, R); root.right = trimBST(root.right, L, R); return root; };
Given a list of tuples representing birth date and and death date for a single person, return the year with the maximum population var arr =[ [1990, 2000], [1995, 2003], [1993, 2001], [2001, 2003] ]
var yearsArray= arr.map(el => el[0]).concat(arr.map(el => el[1])) var maxYear= Math.max(...yearsArray) var minYear= Math.min(...yearsArray) var yearsHash={} var yearCount=minYear while(yearCount<=maxYear){ yearsHash[yearCount]=0 yearCount++ } for(let person of arr){ for(let year in yearsHash){ if(year>=person[0] && year<person[1]){ yearsHash[year]++ } else if(year==person[1]){ yearsHash[year]-- if(yearsHash[year]<0){ yearsHash[year]=0 } } } } console.log(Object.keys(yearsHash).filter( key => yearsHash[key] ==Math.max(...Object.values(yearsHash)))[0])