leetcode.com

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

Given a List of words, return the words that can be typed using letters of alphabet on only one row's of American keyboard like the image below. American keyboard Example 1: Input: ["Hello", "Alaska", "Dad", "Peace"] Output: ["Alaska", "Dad"] Note: You may use one character in the keyboard more than once. You may assume the input string will only contain letters of alphabet.

Maintain 3 sets, each represents a set of characters from each row. Iterate over an array of words and check if a word can be built from first, second or third row. Set will allow to check in a constant time. Time complexity - O(n*m) where n is a number of words and m is a length of a word Space complexity - O(1)

Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases. Note: For the purpose of this problem, we define empty string as valid palindrome. Example 1: Input: "A man, a plan, a canal: Panama" Output: true Example 2: Input: "race a car" Output: false

Using two pointers. First we need to make a string lower case. Then we have two pointers, first starts from the beginning and another one starts from the end. Move pointers while a character is not a letter or digit, then compare characters. Time complexity - O(n) Space complexity - O(1)

Invert a binary tree. Example: Input: 4 / \ 2 7 / \ / \ 1 3 6 9 Output: 4 / \ 7 2 / \ / \ 9 6 3 1

1. Recursive Simple change left and right element for each node Time complexity - O(n) Space complexity - O(1) not counting the recursion stack 2. Iteratively TBI

Given a list of strings words representing an English Dictionary, find the longest word in words that can be built one character at a time by other words in words. If there is more than one possible answer, return the longest word with the smallest lexicographical order. If there is no answer, return the empty string. Example 1: Input: words = ["w","wo","wor","worl", "world"] Output: "world" Explanation: The word "world" can be built one character at a time by "w", "wo", "wor", and "worl". Example 2: Input: words = ["a", "banana", "app", "appl", "ap", "apply", "apple"] Output: "apple" Explanation: Both "apply" and "apple" can be built from other words in the dictionary. However, "apple" is lexicographically smaller than "apply". Note: All the strings in the input will only contain lowercase letters. The length of words will be in the range [1, 1000]. The length of words[i] will be in the range [1, 30].

1. Brute Force Add all the words to a set. Iterate over a list of words and check if every string is greater or equal then the intermediate result and can be built from other words in a set. If a string can be built and the length is the same as the previous result, then we need to check their lexicographical order. We can use String.compareTo to check it. Time complexity - ? Space complexity - ? 2. Improved brute force In the above example we check every word if it can be built by other words one letter by one, e.g if we're check a word world, then we need to check if there are all the following words in a set - [w, wo, wor, worl]. Next time when we need to check a word "worlds" we'll be doing the same - [w, wo, wor, worl, world]. We can use memoization, to save the previous results, e.g if we already check a word 'world' and now we need to check a word 'worlds', we don't need to check all substrings, we may check only 'world' substring. Time complexity - ? Space complexity - ?

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.

1. Brute Force Check every letter in S if it exists in J using a nested loop. Time complexity - O(n*m) Space complexity - O(1) 2. Efficient Save all characters from J in a set. Iterate over J and check if the set contains each character. Time complexity - O(n + m) Space complexity - O(n)

Given a non-empty, singly linked list with head node head, return a middle node of linked list. If there are two middle nodes, return the second middle node. Example 1: Input: [1,2,3,4,5] Output: Node 3 from this list (Serialization: [3,4,5]) The returned node has value 3. (The judge's serialization of this node is [3,4,5]). Note that we returned a ListNode object ans, such that: ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, and ans.next.next.next = NULL. Example 2: Input: [1,2,3,4,5,6] Output: Node 4 from this list (Serialization: [4,5,6]) Since the list has two middle nodes with values 3 and 4, we return the second one. Note: The number of nodes in the given list will be between 1 and 100.

1. Brute Force Count a number of nodes. Find the middle node. Iterate over the list till the middle node. Time complexity - O(n) Space complexity - O(1) 2. Efficient One pass Maintain two pointers slow and fast. Slow goes one step forward, fast goes two steps. When fast is null or fast.next is null then slow pointer will point to a middle of the list. Time complexity - O(n) Space complexity - O(1)

Given two strings s and t which consist of only lowercase letters. String t is generated by random shuffling string s and then add one more letter at a random position. Find the letter that was added in t. Example: Input: s = "abcd" t = "abcde" Output: e Explanation: 'e' is the letter that was added.

1. Brute Force Count the number os characters in 's' and 't' and store it in two maps. Iterate over 't' characters and check if sMap.get(c) != tMap.get(c), if not equal, then we found the extra character. Time complexity - O(n+m) Space complexity - O(n+m) 2. Efficient We can use only one array. Iterate over 's' character and increment its ASCII number in the array. Iterate over 't' characters and decrement its ASCII number in the array. Iterate over the array, if value is not 0 then we found the extra character. Time complexity - O(n+m) Space complexity - O(1)

Given two strings s and t , write a function to determine if t is an anagram of s. Example 1: Input: s = "anagram", t = "nagaram" Output: true Example 2: Input: s = "rat", t = "car" Output: false Note: You may assume the string contains only lowercase alphabets. Follow up: What if the inputs contain unicode characters? How would you adapt your solution to such case?

1. Brute Force If both strings have different length then they're no anagrams. Otherwise they might be anograms. Sort both strings. Iterate over them and compare each character. If characters at the same position differ then strings are not anagrams. Time complexity - O(nlogn + mlogm) Space complexity - O(1) 2. Efficient First, check if two strings have the same length. If lengths differ then return false. Create an empty array with 26 positions. Iterate over the first string and increment the value at its position in ASCII. Then iterate over the second string and decrement the value in the array where index is equal to the character position in ASCII. In the end, if all the elements in the array equal to 0 then we have anagrams. Time complexity - O(n + m) Space complexity - O(1) Follow up answer: Use a hash table instead of a fixed size counter. Imagine allocating a large size array to fit the entire range of unicode characters, which could go up to more than 1 million. A hash table is a more generic solution and could adapt to any range of characters.

Given a linked list, determine if it has a cycle in it. Follow up: Can you solve it without using extra space?

1. Brute Force Iterate over a list. While iterating check if we already seen this node. We can save a node on each iteration step in a set. If we have a cycle we will meet the same node again. Otherwise the loop will end which means that there's no cycle. Time complexity - O(n) Space complexity - O(n) 2. Two pointers Intuition: Imagine two runners running on a track at different speed. What happens when the track is actually a circle? Maintain two pointers slow and fast. Iterate over a list while fast or fast.next is not null. If the iteration is finished it means that there's no cycle, otherwise fast pointer will meet slow pointer along its way. Info: https://leetcode.com/problems/linked-list-cycle/solution/ Time complexity - O(n) Space complexity - O(1)

Given a linked list, remove the n-th node from the end of list and return its head. Example: Given linked list: 1->2->3->4->5, and n = 2. After removing the second node from the end, the linked list becomes 1->2->3->5. Note: Given n will always be valid. Follow up: Could you do this in one pass?

1. Brute Force Two passes Count the length of the linked list. Then iterate up to length - n - 1 element and replace the next element of the last element in the iteration with next.next. Time complexity - O(n) Space complexity - O(1) 2. Efficient One pass Use two pointers fast and slow. First move fast pointer n steps forward. Then iterate moving both pointers at the same time. Once fast pointer reached the end of the link slow point will be right before the element that we need to remove. Time complexity - O(n) Space complexity - O(1)

Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Note: Do not modify the linked list. Follow up: Can you solve it without using extra space?

1. Brute Force Use a set to check if we've already seen a node. Iterate over the list and check if a set contains this node, if so, then return this node, otherwise add this node to the set. Time complexity - O(n) Space complexity - O(n) 2. Floyd algorithm TBI

Given a non-empty array of integers, return the k most frequent elements. Example 1: Input: nums = [1,1,1,2,2,3], k = 2 Output: [1,2] Example 2: Input: nums = [1], k = 1 Output: [1] Note: You may assume k is always valid, 1 ≤ k ≤ number of unique elements. Your algorithm's time complexity must be better than O(n log n), where n is the array's size.

1. Brute Force Using a heap. Count the number of occurrences for each element using a map. Iterate over the entries in a map and put them in a max-heap. In the end the element with a most frequency will be on top of a heap. Get first k elements from the heap. Time complexity - O(nlogn) Space complexity - O(n) 2. Efficient Using a bucket sort. Count the number of occurrences for each element using a map. Create a new array 'buckets' of lists with a length equal to a length of the input array + 1. Each index in this array will represent the frequency of an element. Iterate over the help array (from the end) and get k elements. Time complexity - O(n) Space complexity - O(n) Info: https://www.youtube.com/watch?v=EYFcQRwcqk0

Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST. For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1. Example: Given the sorted linked list: [-10,-3,0,5,9], One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST: 0 / \ -3 9 / / -10 5

1. Brute Force We can solve this problem as another problem, where we need to convert a sorted array into a BST. It's really easy to do as long as we have an index-based access to the elements of the list. Since we can't get an element from a list by index we can create a temporary array(array list) and put all elements of the linked list in the array list. Then solve this problem the same as 108. Convert Sorted Array to Binary Search Tree Time complexity - O(n) Space complexity - O(n) to store all elements in the array 2. Break the list Find the middle of the list and make it a root. Then recursively build a right sub-tree from the all elements starting from the middle.next. Build the left sub-tree from all the elements prior to middle element. In order to facilitate the building process of the left sub-tree, set next of the element before middle to null. Time complexity - ? Space complexity - ? 3. Efficient without breaking the input list Use low and high pointers to find a middle. Initially low is a head, and high is a null. Find a middle element using slow and fast pointers. After first operation, slow will point to a middle element. Make slow a root, then build a left sub-tree with low equal to low and high equal to slow. Then build a right sub-tree with lo equal to slow.next and high equal to high. Time complexity - O(nlogn) Space complexity - O(n)

Given a non-empty array of integers, every element appears twice except for one. Find that single one. Note: Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? Example 1: Input: [2,2,1] Output: 1 Example 2: Input: [4,1,2,1,2] Output: 4

1. Brute Force Iterate over array and add element to a list if the list doesn't contain it, otherwise add it. In the end there will be only one element in the list. Time complexity - O(n^2) Space complexity - O(n) 2. Improved brute force We can improve the above solution using set instead of a list. Look up operation will take O(1) instead of O(n) which will reduce time complexity. Time complexity - O(n) Space complexity - O(n) 3. Sorting Sort the array. While iterating check if the current element is equal to the next one. If not equal, then this element is a result, otherwise jump two elements forward. If the loop terminated, then the result is a last element in the array. Time complexity - O(nlogn) Space complexity - O(n) 4. Bit manipulation TBI

You are given a data structure of employee information, which includes the employee's unique id, his importance value and his direct subordinates' id. For example, employee 1 is the leader of employee 2, and employee 2 is the leader of employee 3. They have importance value 15, 10 and 5, respectively. Then employee 1 has a data structure like [1, 15, [2]], and employee 2 has [2, 10, [3]], and employee 3 has [3, 5, []]. Note that although employee 3 is also a subordinate of employee 1, the relationship is not direct. Now given the employee information of a company, and an employee id, you need to return the total importance value of this employee and all his subordinates. Example 1: Input: [[1, 5, [2, 3]], [2, 3, []], [3, 3, []]], 1 Output: 11 Explanation: Employee 1 has importance value 5, and he has two direct subordinates: employee 2 and employee 3. They both have importance value 3. So the total importance value of employee 1 is 5 + 3 + 3 = 11. Note: One employee has at most one direct leader and may have several subordinates. The maximum number of employees won't exceed 2000.

1. Brute Force DFS Using dfs. Find a required if from the list. Get its importance value and then recursively find all the subordinates. Time complexity - O(n^2) Space complexity - O(n) for recursion stack 2. DFS Using dfs with a cache. Put all the employees into a map. Find an employee by requested id, then recursively find all the subordinates. Instead of a linear search we can take advantage of a O(1) look up provided by map. Time complexity - O(n) Space complexity - O(n) 3. BFS We can replace recursion with a queue. Put all the employees into a map. Then add an employee by requested id in a queue. While queue is not empty poll an employee from it, get the result, and add all the subordinates in the queue. Time complexity - O(n) Space complexity - O(n)

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. Example 1: Given tree s: 3 / \ 4 5 / \ 1 2 Given tree t: 4 / \ 1 2 Return true, because t has the same structure and node values with a subtree of s. Example 2: Given tree s: 3 / \ 4 5 / \ 1 2 / 0 Given tree t: 4 / \ 1 2 Return false.

1. By comparing pre-order traversal Create two strings with pre-order traversal of two trees. If the first string contains the second then s is a sub-tree of t. Time complexity - O(n + m) Space complexity - O(n + m) 2. Comparing nodes Compare each node of 't' with each node of 's' recursively using dfs. If root node of 't' is equal to root node of 's' then compare their left and right sub-trees. If root of 't' is not equal to root of 's' then compare left node of 't' with root node of 's' and right node of 't' with root node of 's'. Time complexity - O(n*m) Space complexity - O(n)

You are given a string representing an attendance record for a student. The record only contains the following three characters: 'A' : Absent. 'L' : Late. 'P' : Present. A student could be rewarded if his attendance record doesn't contain more than one 'A' (absent) or more than two continuous 'L' (late). You need to return whether the student could be rewarded according to his attendance record. Example 1: Input: "PPALLP" Output: True Example 2: Input: "PPALLL" Output: False

1. Count lates and absents Iterate over a string and count a number of continuous L and if there are more than one A in the string. Time complexity - O(n) Space complexity - O(1) 2. Using String's methods Check that string doesn't contain three Ls and that first and last index of A is the same. Time complexity - O(n) Space complexity - O(1)

Find the minimum length word from a given dictionary words, which has all the letters from the string licensePlate. Such a word is said to complete the given string licensePlate Here, for letters we ignore case. For example, "P" on the licensePlate still matches "p" on the word. It is guaranteed an answer exists. If there are multiple answers, return the one that occurs first in the array. The license plate might have the same letter occurring multiple times. For example, given a licensePlate of "PP", the word "pair" does not complete the licensePlate, but the word "supper" does. Example 1: Input: licensePlate = "1s3 PSt", words = ["step", "steps", "stripe", "stepple"] Output: "steps" Explanation: The smallest length word that contains the letters "S", "P", "S", and "T". Note that the answer is not "step", because the letter "s" must occur in the word twice. Also note that we ignored case for the purposes of comparing whether a letter exists in the word. Example 2: Input: licensePlate = "1s3 456", words = ["looks", "pest", "stew", "show"] Output: "pest" Explanation: There are 3 smallest length words that contains the letters "s". We return the one that occurred first. Note: licensePlate will be a string with length in range [1, 7]. licensePlate will contain digits, spaces, or letters (uppercase or lowercase). words will have a length in the range [10, 1000]. Every words[i] will consist of lowercase letters, and have length in range [1, 15].

1. Count the number of letter in a licensePlate ignoring a case using an array. Then iterate over the words array and check if a length of the word is less or equal then a previous result, then check if this word completes the licensePlate. How to check: Count the number of characters in a word using an array. Iterate over this array and plate array and check if element is not 0 in plate array and less or equal to an element in the word array. Time complexity - O(n) Space complexity - O(n)

Given a string, find the first non-repeating character in it and return it's index. If it doesn't exist, return -1. Examples: s = "leetcode" return 0. s = "loveleetcode", return 2. Note: You may assume the string contain only lowercase letters.

1. Efficient Count the number of each character in a string. Then iterate over the string and return first element with count 1 in the hashset/array Time complexity - O(n) Space complexity - O(1)

The set S originally contains numbers from 1 to n. But unfortunately, due to the data error, one of the numbers in the set got duplicated to another number in the set, which results in repetition of one number and loss of another number. Given an array nums representing the data status of this set after the error. Your task is to firstly find the number occurs twice and then find the number that is missing. Return them in the form of an array. Example 1: Input: nums = [1,2,2,4] Output: [2,3] Note: The given array size will in the range [2, 10000]. The given array's numbers won't have any order.

1. Efficient with extra space Create an extra array with the length equal to length + 1 of the original array. Count the occurrences of each number in the input array and save it in the help array. Then iterate over the help array and find an elements with 0 and 2 values appropriately. Time complexity - O(n) Space complexity - O(n) 2. Efficient without extra space TBI https://leetcode.com/problems/set-mismatch/discuss/105507/Java-O(n)-Time-O(1)-Space https://leetcode.com/problems/set-mismatch/solution/

Remove all elements from a linked list of integers that have value val. Example: Input: 1->2->6->3->4->5->6, val = 6 Output: 1->2->3->4->5

1. Iterative A naive idea is to check if the current node's value is equal to target, then set the value of the next node, and set next = next.next. But it will fail if we need to remove the last element. Another approach is to check whether we need to remove a next node or not. The problem is that we might need to remove a first node of the list. The idea is to move head node if it is equal to a target value till it is not null and not equal to the target value and only then check the next node. Time complexity - O(n) Space complexity - O(1) 2. Recursive The recursive solution is more simple. Find the last node recursively. If it should be removed, then return its next element which is null, otherwise return the node itself. Do the same for each node. Time complexity - O(n) Space complexity - O(n) for recursion stack

Reverse a singly linked list. Example: Input: 1->2->3->4->5->NULL Output: 5->4->3->2->1->NULL Follow up: A linked list can be reversed either iteratively or recursively. Could you implement both?

1. Iterative Maintain two pointers prev and curr. Initially prev is null and curr is a head. Time complexity - O(n) Space complexity - O(1) 2. Recursively Using tail recursion and helper function. Time complexity - O(n) Space complexity - O(n) for recursion stack

Given a singly linked list, group all odd nodes together followed by the even nodes. Please note here we are talking about the node number and not the value in the nodes. You should try to do it in place. The program should run in O(1) space complexity and O(nodes) time complexity. Example 1: Input: 1->2->3->4->5->NULL Output: 1->3->5->2->4->NULL Example 2: Input: 2->1->3->5->6->4->7->NULL Output: 2->3->6->7->1->5->4->NULL Note: The relative order inside both the even and odd groups should remain as it was in the input. The first node is considered odd, the second node even and so on ...

1. One pass Maintain two pointer odd and event, odd is a head of the list and event is head.next. Iterate over a list while even and even.next is not null and set odd.next = even.next and even.next = odd.next In the end just link two linked lists (one containing even elements and one with odd ones). Time complexity - O(n) Space complexity - O(1)

Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x. You should preserve the original relative order of the nodes in each of the two partitions. Example: Input: head = 1->4->3->2->5->2, x = 3 Output: 1->2->2->4->3->5

1. One pass The idea: maintain two lists, the first one contains all the element with value less than x and another one contains all the elements greater than x. In the end, link them together. Important point: we need to set next element of the last element in the second list to null to avoid cycling. Time complexity - O(n) Space complexity - O(1)

You are given a doubly linked list which in addition to the next and previous pointers, it could have a child pointer, which may or may not point to a separate doubly linked list. These child lists may have one or more children of their own, and so on, to produce a multilevel data structure, as shown in the example below. Flatten the list so that all the nodes appear in a single-level, doubly linked list. You are given the head of the first level of the list. Example: Input: 1---2---3---4---5---6--NULL | 7---8---9---10--NULL | 11--12--NULL Output: 1-2-3-7-8-11-12-9-10-4-5-6-NULL

1. Recursive If node has a child, then make the child its next element, otherwise move to the next node. Time complexity - O(n) Space complexity - O(1) 2. Iteratively TBI

Problem: Print a binary tree in an m*n 2D string array following these rules: The row number m should be equal to the height of the given binary tree. The column number n should always be an odd number. The root node's value (in string format) should be put in the exactly middle of the first row it can be put. The column and the row where the root node belongs will separate the rest space into two parts (left-bottom part and right-bottom part). You should print the left subtree in the left-bottom part and print the right subtree in the right-bottom part. The left-bottom part and the right-bottom part should have the same size. Even if one subtree is none while the other is not, you don't need to print anything for the none subtree but still need to leave the space as large as that for the other subtree. However, if two subtrees are none, then you don't need to leave space for both of them. Each unused space should contain an empty string "". Print the subtrees following the same rules. Example 1: Input: 1 / 2 Output: [["", "1", ""], ["2", "", ""]] Example 2: Input: 1 / \ 2 3 \ 4 Output: [["", "", "", "1", "", "", ""], ["", "2", "", "", "", "3", ""], ["", "", "4", "", "", "", ""]] Example 3: Input: 1 / \ 2 5 / 3 / 4 Output: [["", "", "", "", "", "", "", "1", "", "", "", "", "", "", ""] ["", "", "", "2", "", "", "", "", "", "", "", "5", "", "", ""] ["", "3", "", "", "", "", "", "", "", "", "", "", "", "", ""] ["4", "", "", "", "", "", "", "", "", "", "", "", "", "", ""]] Note: The height of binary tree is in the range of [1, 10].

1. Recursively A height of a matrix will be a height of a tree. A width of the matrix will be the width of the last level of a full tree, which is equal to width = height ^ 2 - 1. Then build an empty matrix and do dfs on it. Time complexity - ? Space complexity - ? 2. Iteratively TBI

Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum. Note: A leaf is a node with no children. 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] ]

1. Recursively Do DFS recursively, extracting node's value from a target while recurring for left and child nodes. If we reached the leave node (left and right child are null) and target value is 0 then we found a path. We can maintain a temp list which will hold all elements along the path, once left sub-tree has been visited we remove the last element from a list and recur for right sub-tree. Once right sub-tree has been visited we remove the last element from a temporary list as well. Time complexity - O(n) Space complexity - O(h) 2. Iteratively TBI

Given a balanced parentheses string S, compute the score of the string based on the following rule: () has score 1 AB has score A + B, where A and B are balanced parentheses strings. (A) has score 2 * A, where A is a balanced parentheses string. Example 1: Input: "()" Output: 1 Example 2: Input: "(())" Output: 2 Example 3: Input: "()()" Output: 2 Example 4: Input: "(()(()))" Output: 6 Note: S is a balanced parentheses string, containing only ( and ). 2 <= S.length <= 50

1. Recursively Find first balanced substring (a number of open brackets is equal to a number of closing brackets) and if the difference between first and last index is not 1 then the result will be 2 * substring between first and last characters of this balanced string plus the result of a string after the last brackets. If the difference between first and last index is equal to 1, then the result will be 1 plus the result of a string after the last index. Time complexity - ? Space complexity - ? 2. Using a stack TBI

Given a string, find the length of the longest substring without repeating characters. Example 1: Input: "abcabcbb" Output: 3 Explanation: The answer is "abc", which the length is 3. Example 2: Input: "bbbbb" Output: 1 Explanation: The answer is "b", with the length of 1. Example 3: Input: "pwwkew" Output: 3 Explanation: 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.

1. Sliding window Maintain a sliding window in a form of a hash set. Iterate over the string, using two pointers. Fast pointer moves forward until all elements in a set are unique. Once we encountered a duplicate element, then we move slow pointer and remove elements from a set until it contains only unique elements. Time complexity - O(n) Space complexity - O(n) where n is a number of characters in a string 2. Improved sliding window Iterate over a string using a fast pointer and store in a map a character and its index. Once we found a duplicate character, we can check its previous index using a map. Then we can start slow pointer 'j' from Math.max(j, map.get(s.charAt(i)) + 1) In this case we don't need to reduce a window iterating the string via a slow pointer, we can find its position right away. Time complexity - O(n) Space complexity - O(n)

Suppose Andy and Doris want to choose a restaurant for dinner, and they both have a list of favorite restaurants represented by strings. You need to help them find out their common interest with the least list index sum. If there is a choice tie between answers, output all of them with no order requirement. You could assume there always exists an answer. Example 1: Input: ["Shogun", "Tapioca Express", "Burger King", "KFC"] ["Piatti", "The Grill at Torrey Pines", "Hungry Hunter Steakhouse", "Shogun"] Output: ["Shogun"] Explanation: The only restaurant they both like is "Shogun". Example 2: Input: ["Shogun", "Tapioca Express", "Burger King", "KFC"] ["KFC", "Shogun", "Burger King"] Output: ["Shogun"] Explanation: The restaurant they both like and have the least index sum is "Shogun" with index sum 1 (0+1). Note: The length of both lists will be in the range of [1, 1000]. The length of strings in both lists will be in the range of [1, 30]. The index is starting from 0 to the list length minus 1. No duplicates in both lists.

1. Three-pass solution Put all elements from the first list in a map, where key is a string and value is an index. Then iterate over the second list and check if a restaurant exists in the first list, if we so check the min sum. After the second pass we will have a minimum sum. We need to pass again over the second list, and check if a restaurant exists in the first list and a sum of indices is equal to min sum. Time complexity - O(n + m) Space complexity - O(n) 2. Two-pass solution We can get rid of one pass from the above solution. Put all elements from the first list in a map, where key is a string and value is an index. Iterate over the second list and if a restaurant from the second list exists in the first list and sum of their indices is equal to a minimum sum, then put this restaurant name in a temp list, if the sum is less than minimum sum, then clear the temp list before adding this restaurant. Time complexity - O(n + m) Space complexity - O(n)

Write a function that takes a string as input and reverse only the vowels of a string. Example 1: Input: "hello" Output: "holle" Example 2: Input: "leetcode" Output: "leotcede" Note: The vowels does not include the letter "y".

1. Two pointers One pointer starts from the beginning and another one from the end. If both pointers point to vowels then swap them. There are only 5 vowels in english - "aeoui" and we also should check for uppercase vowels. To check if a character is a vowel or not, we can have a set containing all vowels in uppers case and lower case or we can use just string. Look up in a set will take O(1) time, in a string - O(12) so we can ignore it and consider as a constant. Time complexity - O(n) Space complexity - O(1)

Given two arrays, write a function to compute their intersection. Example 1: Input: nums1 = [1,2,2,1], nums2 = [2,2] Output: [2] Example 2: Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4] Output: [9,4] Note: Each element in the result must be unique. The result can be in any order.

1. Using a set Put all elements from the first array in a set. Iterate over the second array and check if element exists in a set, if exists then add it to another result set. In the end the result set will contains all intersections. Time complexity - O(n + m) iterate over n element to put them in a set, iterate over m to check intersections Space complexity - O(n) 2. Using two pointers Sort two arrays. Iterate over two arrays using two pointers. If elements are equal then put this value in a intersection set and move two pointers. If an element in a first array is greater than element in a second array, then move second pointer, otherwise move the second pointer. Time complexity - O(nlogn + mlogm) Space complexity - O(n) 3. Using a binary search Sort element from the first array. Iterate over a second array and check if an element exists in a first array using a binary search. If the element exists in the first array, then put it in a intersection set. Time complexity - O(nlogn + mlogn), nlogn is to sort the first array, then mlogn is to iterate over the second array and check every element in the first array is logn Space complexity - O(n)

Given two arrays, write a function to compute their intersection. Example 1: Input: nums1 = [1,2,2,1], nums2 = [2,2] Output: [2,2] Example 2: Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4] Output: [4,9] Note: Each element in the result should appear as many times as it shows in both arrays. The result can be in any order. Follow up: 1. What if the given array is already sorted? How would you optimize your algorithm? 2. What if nums1's size is small compared to nums2's size? Which algorithm is better? 3. What if elements of nums2 are stored on disk, and the memory is limited such that you cannot load all elements into the memory at once?

1. Using sorting Sort both arrays. Iterate over two arrays via two pointers. If both elements are equal, add this element to the result list and increment both pointers. If element from the first array is less than the element from the second array, then increment the first pointer, otherwise increment the second pointer. Time complexity - O(nlogn + mlogm) to sort both arrays Space complexity - O(n) for a temp list 2. Using a binary search Sort the first array. Iterate over the second array and check if element exists in the first array using a binary search. The problem may occur if we have the following arrays: 1st - [1,2,3] 2nd - [2,2] As a result we need to return only [2]. Once we checked that first '2' int the second array exists in the first array, we don't need to count second '2' from the second array, that's why we need to remove '2' from the first array after a first match. We can put all elements from the first sorted array in a list, and then do binary search for this list. If binary search return a successful response, then we remove this element from a list. Remove operation will increase time complexity since it will be done in a linear time. Complexity analysis: We need to sort the first array - O(mlogm) Then iterate the second array and do binary search on the first array and remove element from the first array if we found a match - O(m*logn*n) Time complexity - O(nlogn + n*mlogn) Space complexity - O(n) 3. Using a map Put all the element from the first list in a map, where a key is an element itself and value is a count. Iterate over the second list, check if this element exists as a key in the map and value is greater than 0, if so then add this element to a result list and decrement by one count in a map for this element. Time complexity - O(n + m) Space complexity - O(n) Follow up answers: 1. If the array os already sorted we can iterate over another array and do a binary search on the sorted one 2. If the first array is smaller than the second one, then we can sort the first array to do a binary search on it. It's more efficient to sort a smaller array. 3. If only nums2 cannot fit in memory, put all elements of nums1 into a HashMap, read chunks of array that fit into the memory, and record the intersections. If both nums1 and nums2 are so huge that neither fit into the memory, sort them individually (external sort), then read 2 elements from each array at a time in memory, record intersections. We can also sort the first array (it won't use any extra space) then load chunks of the second array and do binary search on the first sorted array. 3rd solution - https://leetcode.com/problems/intersection-of-two-arrays-ii/discuss/82243/Solution-to-3rd-follow-up-question

Given an array of strings, group anagrams together. Example: Input: ["eat", "tea", "tan", "ate", "nat", "bat"], Output: [ ["ate","eat","tea"], ["nat","tan"], ["bat"] ] Note: All inputs will be in lowercase. The order of your output does not matter.

1. Using sorting. Two words are anagrams if both strings are equal when they're sorted. We can group anagrams by its sorting value using a hash map. Iterate over an array, sort each word and put the original word in a map where they key is a sorted word. Time complexity - O(nklogk) where n is a number of words and k is a length of a word Space complexity - O(n) 2. Efficient We don't really need to sort every word. We can calculate a hash of each word and then use this values as a key in a hash map. Hash function implementation: We can take advantage of the fact that all the characters will be in lower case. We can map the word to an array of 26 elements. Count the number of characters in a string and save these values in the array. Then create a string from this array and use it as a key. Two anagrams will always have equal arrays, since the number of characters will be the same. Time complexity - O(n*k) where n is a number of words and m is a length of a word Space complexity - O(n)

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. Example: Input: paragraph = "Bob hit a ball, the hit BALL flew far after it was hit." banned = ["hit"] Output: "ball" Explanation: "hit" occurs 3 times, but it is a banned word. "ball" occurs twice (and no other word does), so it is the most frequent non-banned word in the paragraph. Note that words in the paragraph are not case sensitive, that punctuation is ignored (even if adjacent to words, such as "ball,"), and that "hit" isn't the answer even though it occurs more because it is banned. Note: 1 <= paragraph.length <= 1000. 1 <= banned.length <= 100. 1 <= banned[i].length <= 10. The answer is unique, and written in lowercase (even if its occurrences in paragraph may have uppercase symbols, and even if it is a proper noun.) paragraph only consists of letters, spaces, or the punctuation symbols !?',;. Different words in paragraph are always separated by a space. There are no hyphens or hyphenated words. Words only consist of letters, never apostrophes or other punctuation symbols.

Algorithm: 1. Add banned words to a set for a quick look up 2. Make a paragraph lowercase and remove all special symbols 3. Count the number of non banned words in a paragraph (use the banned set for a quick look up) using a map. 4. Find a word in a map with a largest frequency Time complexity - O(n + m) where n is a length of a paragraph and m is a length of a banned words Space complexity - O(n + m)

Given a string and a string dictionary, find the longest string in the dictionary that can be formed by deleting some characters of the given string. If there are more than one possible results, return the longest word with the smallest lexicographical order. If there is no possible result, return the empty string. Example 1: Input: s = "abpcplea", d = ["ale","apple","monkey","plea"] Output: "apple" Example 2: Input: s = "abpcplea", d = ["a","b","c"] Output: "a" Note: All the strings in the input will only contain lower-case letters. The size of the dictionary won't exceed 1,000. The length of all the strings in the input won't exceed 1,000.

Basically the problem is to find a longest word from the words array which is a sub-sequence of the input word. To check if a word 'a' is a sub sequence of a word 'b' iterate over two strings and check if both characters are equal, then increment both pointers, otherwise increment only 'b' pointer. In the end if 'a' pointer is equal to a.length then 'a' is a sub-sequence of 'b'. Time complexity - O(n*k) where n is a number of words and k is average word length Space complexity - O(1)

S and T are strings composed of lowercase letters. In S, no letter occurs more than once. S was sorted in some custom order previously. We want to permute the characters of T so that they match the order that S was sorted. More specifically, if x occurs before y in S, then x should occur before y in the returned string. Return any permutation of T (as a string) that satisfies this property. Example: Input: S = "cba" T = "abcd" Output: "cbad" Explanation: "a", "b", "c" appear in S, so the order of "a", "b", "c" should be "c", "b", and "a". Since "d" does not appear in S, it can be at any position in T. "dcba", "cdba", "cbda" are also valid outputs.

Calculate a count of each character in a string 't'. Then iterate over a string 's' and add each character with an appropriate count to a string builder, in the end we'll have the same order as it is in a string 's'. Then iterate over a string 't' again and all the rest characters to a string builder. Complexity analysis: we can consider iterating over a string 's' as a constant since its length is fixed (26 chars) and no duplicates are allowed. We need to take into account only a number of character in a string 't'. Space complexity is also constant since we use a fixed length size for array. Time complexity - O(n) where n is a number of characters in a string 't'. Space complexity - O(1)

Given an arbitrary ransom note string and another string containing letters from all the magazines, write a function that will return true if the ransom note can be constructed from the magazines ; otherwise, it will return false. Each letter in the magazine string can only be used once in your ransom note. Note: You may assume that both strings contain only lowercase letters. canConstruct("a", "b") -> false canConstruct("aa", "ab") -> false canConstruct("aa", "aab") -> true

Count a number of each letter in a magazine word. Count a number of each letter in a ransom note. If count for the same letter in magazine word is more than count in a ransom note, then we can't construct this note. Time complexity - O(n) Space complexity - O(1)

Consider all the leaves of a binary tree. From left to right order, the values of those leaves form a leaf value sequence. For example, in the given tree above, the leaf value sequence is (6, 7, 4, 9, 8). Two binary trees are considered leaf-similar if their leaf value sequence is the same. Return true if and only if the two given trees with head nodes root1 and root2 are leaf-similar. Note: Both of the given trees will have between 1 and 100 nodes.

Do DFS over two trees and save all leave nodes in two lists then compare the lists. Time complexity - O(n + m) Space complexity - O(n + m)

Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the length of last word in the string. If the last word does not exist, return 0. Note: A word is defined as a character sequence consists of non-space characters only. Example: Input: "Hello World" Output: 5

First we need to find the end of the last word, it will be the first non empty character from the end. Then we need to find where the last word starts, it will be the next index after the first empty character before the last word. The most important things is to consider all possible edge cases: some of them: "Hello word", " Hello word ", "", " ", "hello", " hello", " hello" Time complexity - O(n) Space complexity - O(1)

The count-and-say sequence is the sequence of integers with the first five terms as following: 1. 1 2. 11 3. 21 4. 1211 5. 111221 1 is read off as "one 1" or 11. 11 is read off as "two 1s" or 21. 21 is read off as "one 2, then one 1" or 1211. Given an integer n, generate the nth term of the count-and-say sequence. Note: Each term of the sequence of integers will be represented as a string. Example 1: Input: 1 Output: "1" Example 2: Input: 4 Output: "1211"

In order to find a value for nth element, we need to know a value for nth - 1 element. Time complexity - O(n*k) where k is an average length of a value from 1 up to n elements Space complexity - O(1)

Implement function ToLowerCase() that has a string parameter str, and returns the same string in lowercase. Example 1: Input: "Hello" Output: "hello" Example 2: Input: "here" Output: "here" Example 3: Input: "LOVELY" Output: "lovely"

Iterate over a string and check if a letter is in upper case (between A and C) make it lower case using ASCII table number. Time complexity - O(n) Space complexity - O(n)

Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M. Symbol Value I 1 V 5 X 10 L 50 C 100 D 500 M 1000 For example, two is written as II in Roman numeral, just two one's added together. Twelve is written as, XII, which is simply X + II. The number twenty seven is written as XXVII, which is XX + V + II. Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used: I can be placed before V (5) and X (10) to make 4 and 9. X can be placed before L (50) and C (100) to make 40 and 90. C can be placed before D (500) and M (1000) to make 400 and 900. Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 to 3999. Example 1: Input: "III" Output: 3 Example 2: Input: "IV" Output: 4 Example 3: Input: "IX" Output: 9 Example 4: Input: "LVIII" Output: 58 Explanation: C = 100, L = 50, XXX = 30 and III = 3. Example 5: Input: "MCMXCIV" Output: 1994 Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.

Iterate over a string, if current element's values is less than next's value, then we need to extract this values, otherwise add it. Time complexity - O(n) Space complexity - O(1)

Given a word, you need to judge whether the usage of capitals in it is right or not. We define the usage of capitals in a word to be right when one of the following cases holds: All letters in this word are capitals, like "USA". All letters in this word are not capitals, like "leetcode". Only the first letter in this word is capital if it has more than one letter, like "Google". Otherwise, we define that this word doesn't use capitals in a right way. Example 1: Input: "USA" Output: True Example 2: Input: "FlaG" Output: False Note: The input will be a non-empty word consisting of uppercase and lowercase latin letters.

Iterate over the characters in a string and count the number of upper case letter. There are three options: 1. count is equal to word's length -> true 2. count is equal to 1 and first letter is in upper case -> true 3. count is equal to zero -> true otherwise the result is false Time complexity - O(n) Space complexity - O(1)

Initially, there is a Robot at position (0, 0). Given a sequence of its moves, judge if this robot makes a circle, which means it moves back to the original place. The move sequence is represented by a string. And each move is represent by a character. The valid robot moves are R (Right), L (Left), U (Up) and D (down). The output should be true or false representing whether the robot makes a circle. Example 1: Input: "UD" Output: true Example 2: Input: "LL" Output: false

Let's say that in the beginning the robot is located at x = 0 and y = 0. Increase or decrease x/y depending on a move. In the end x and y should be equal to 0. Time complexity - O(n) Space complexity - O(1)

Given an array of characters, compress it in-place. The length after compression must always be smaller than or equal to the original array. Every element of the array should be a character (not int) of length 1. After you are done modifying the input array in-place, return the new length of the array. Follow up: Could you solve it using only O(1) extra space? Example 1: Input: ["a","a","b","b","c","c","c"] Output: Return 6, and the first 6 characters of the input array should be: ["a","2","b","2","c","3"] Explanation: "aa" is replaced by "a2". "bb" is replaced by "b2". "ccc" is replaced by "c3". Example 2: Input: ["a"] Output: Return 1, and the first 1 characters of the input array should be: ["a"] Explanation: Nothing is replaced. Example 3: Input: ["a","b","b","b","b","b","b","b","b","b","b","b","b"] Output: Return 4, and the first 4 characters of the input array should be: ["a","b","1","2"]. Explanation: Since the character "a" does not repeat, it is not compressed. "bbbbbbbbbbbb" is replaced by "b12". Notice each digit has it's own entry in the array. Note: All characters have an ASCII value in [35, 126]. 1 <= len(chars) <= 1000.

Shitty as all similar problems (move zeros, remove element, etc) Time complexity - O(n) Space complexity - O(1)

Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order. Example 1: Input: [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ] Output: [1,2,3,6,9,8,7,4,5] Example 2: Input: [ [1, 2, 3, 4], [5, 6, 7, 8], [9,10,11,12] ] Output: [1,2,3,4,8,12,11,10,9,5,6,7]

Simple traverse using offset. Time complexity - O(n*m) Space complexity - O(1)

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.

The idea is the same as in 347. Top K Frequent Elements and 451. Sort Characters By Frequency problems. Two solutions: 1. Using a heap 2. Using a bucket sort

Write a function to find the longest common prefix string amongst an array of strings. If there is no common prefix, return an empty string "". Example 1: Input: ["flower","flow","flight"] Output: "fl" Example 2: Input: ["dog","racecar","car"] Output: "" Explanation: There is no common prefix among the input strings. Note: All given inputs are in lowercase letters a-z.

The idea is to iterate over all words and check a character at each index starting from 0. Time complexity - O(n*k) where n is a number of all words and k is a length of the shortest word Space complexity - O(n)

Given a sorted linked list, delete all duplicates such that each element appear only once. Example 1: Input: 1->1->2 Output: 1->2 Example 2: Input: 1->1->2->3->3 Output: 1->2->3

The idea: if the current element is equal to the next element then we need to skip the next element curr.next = curr.next.next 1. Iteratively Iterate over a list and check if the current element is equal to the next element. Time complexity - O(n) Space complexity - O(1) 2. Recursively The same approach but recursively Time complexity - O(n) Space complexity - O(n) for recursion stack

Given an integer array with even length, where different numbers in this array represent different kinds of candies. Each number means one candy of the corresponding kind. You need to distribute these candies equally in number to brother and sister. Return the maximum number of kinds of candies the sister could gain. Example 1: Input: candies = [1,1,2,2,3,3] Output: 3 Explanation: There are three different kinds of candies (1, 2 and 3), and two candies for each kind. Optimal distribution: The sister has candies [1,2,3] and the brother has candies [1,2,3], too. The sister has three different kinds of candies. Example 2: Input: candies = [1,1,2,3] Output: 2 Explanation: For example, the sister has candies [2,3] and the brother has candies [1,1]. The sister has two different kinds of candies, the brother has only one kind of candies. Note: The length of the given array is in range [2, 10,000], and will be even. The number in given array is in range [-100,000, 100,000].

The idea: if the number of different kinds is equal or greater than the total number / 2, the the sister will get total /2 kinds. Otherwise she'll get just a number of different kinds (less than total / 2). Time complexity - O(n) Space complexity - O(n)

A string S of lowercase letters is given. We want to partition this string into as many parts as possible so that each letter appears in at most one part, and return a list of integers representing the size of these parts. Example 1: Input: S = "ababcbacadefegdehijhklij" Output: [9,7,8] Explanation: The partition is "ababcbaca", "defegde", "hijhklij". This is a partition so that each letter appears in at most one part. A partition like "ababcbacadefegde", "hijhklij" is incorrect, because it splits S into less parts. Note: S will have length in range [1, 500]. S will consist of lowercase letters ('a' to 'z') only.

The idea: in order to split array into partitions we need to know last index for each character. e.g let's consider the following string "abcdsabkopk" We can split this string into two partitions [7,4] -> "abcdsda" and "kopk". First, find the last index of the first character 'a', it is 5, so we might say that the first partition should be of length 6 which is not correct, since the last index of the second character 'b' is 6 which makes the first partition be at least 7 characters long. Therefore the pattern is that we need to iterate over the string, and find a last index of each character, if we reached the last index that means that we have a first partition. 1. Brute Force Iterate over the string, find last occurrence of each element using a nested loop. Time complexity - O(n^2) Space complexity - O(1) 2. Efficient We can pre process the input string. Create an empty array representing an alphabet, iterate over a string and save the last index of each character in the array. The index in the array represents a character and value represents a last index in the input string. Then iterate over the input string, and check the last index of each character via the alphabet array. Once reached the last index save the length of the partition. Although we have a temporary alphabet array we can say that our space complexity is constant since this array has a fixed size 26 and doesn't depend on the input size. Time complexity - O(n) Space complexity - O(1)

Write a function to delete a node (except the tail) in a singly linked list, given only access to that node. Given linked list -- head = [4,5,1,9], which looks like following: 4 -> 5 -> 1 -> 9 Example 1: Input: head = [4,5,1,9], node = 5 Output: [4,1,9] Explanation: You are given the second node with value 5, the linked list should become 4 -> 1 -> 9 after calling your function. Example 2: Input: head = [4,5,1,9], node = 1 Output: [4,5,9] Explanation: You are given the third node with value 1, the linked list should become 4 -> 5 -> 9 after calling your function. Note: The linked list will have at least two elements. All of the nodes' values will be unique. The given node will not be the tail and it will always be a valid node of the linked list. Do not return anything from your function.

The idea: since we don't have an access to the previous node then we can't remove node, but we can change the node's value. ​ Time complexity - O(1) Space complexity - O(1)

Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. An input string is valid if: Open brackets must be closed by the same type of brackets. Open brackets must be closed in the correct order. Note that an empty string is also considered valid. Example 1: Input: "()" Output: true Example 2: Input: "()[]{}" Output: true Example 3: Input: "(]" Output: false Example 4: Input: "([)]" Output: false Example 5: Input: "{[]}" Output: true

The idea: use stack to track open and closed brackets Iterate over a string and check if a bracket is open then push it onto stack. Otherwise if a bracket is closed, then if a stack is empty or last element is not the same open bracket then return false. In the end stack should be empty. Time complexity - O(n) Space complexity - O(n)

Count the number of segments in a string, where a segment is defined to be a contiguous sequence of non-space characters. Please note that the string does not contain any non-printable characters. Example: Input: "Hello, my name is John" Output: 5

The idea: we need to count a number of words (including special symbols). Let's count the word once we iterated over it. Iterate over a string and check if current element is equal to ' ' (or the current index is equal to the length of the string) and previous element is not equal to ' ' then we just passed as word and we can count it. Time complexity - O(n) Space complexity - O(1)

Given a string which consists of lowercase or uppercase letters, find the length of the longest palindromes that can be built with those letters. This is case sensitive, for example "Aa" is not considered a palindrome here. Note: Assume the length of given string will not exceed 1,010. Example: Input: "abccccdd" Output: 7 Explanation: One longest palindrome that can be built is "dccaccd", whose length is 7.

The important thing is to understand how a palindrome can be formed. All numbers with even and odd - 1 number of occurrences characters will form a palindrome. Besides that, we can add one more character to a center of the word and it will be still a palindrome. 1. Brute Force using a set Using set. Iterate over the characters in a string. If set contains this character then we remove it, otherwise add this character to a set. In the end all the characters that are not in the set can be used to form a palindrome. If the set is not empty, then we can get one extra character and add it to a palindrome. Time complexity - O(n) Space complexity - O(n) 2. Brute Force using a map Using map. Iterate over the count map and add up all the even values. If the count is odd, then add odd - 1. Check if one extra character can be added to the result. Time complexity - O(n) Space complexity - O(n) 3. Efficient We can use a fixed space to solve this problem, namely an array with 128 elements to fit all the possible characters. Time complexity - O(n) Space complexity - O(1)

Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the characters in s can be replaced to get t. All occurrences of a character must be replaced with another character while preserving the order of characters. No two characters may map to the same character but a character may map to itself. Example 1: Input: s = "egg", t = "add" Output: true Example 2: Input: s = "foo", t = "bar" Output: false Example 3: Input: s = "paper", t = "title" Output: true Note: You may assume both s and t have the same length.

The most important thing is to find the edge cases. Let's save the mapping in a HashMap where a character from 's' will be a key, and a character from 't' will be a value. Iterate over two strings and do the following check on each iteration step - if the map contains a key equal to s.charAt(i) and a value is not equal to t.charAt(i), then the strings are not isomorphic - if the map doesn't contains a key equal to s.charAt(i) but it contains a value equal to t.charAt(i), then the strings are not isomorphic - if two above cases are false then put s.charAt(i) - t.charAt(i) in the map and check the following pair of characters Check if the map contains value will cost O(n) will will increase the total time complexity up to O(n^2) Time complexity - O(n^2) Space complexity - O(n)

Implement strStr(). Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack. Example 1: Input: haystack = "hello", needle = "ll" Output: 2 Example 2: Input: haystack = "aaaaa", needle = "bba" Output: -1 Clarification: What should we return when needle is an empty string? This is a great question to ask during an interview. For the purpose of this problem, we will return 0 when needle is an empty string. This is consistent to C's strstr() and Java's indexOf().

The problem is called Pattern Searching. 1. Brute Force We compare every substring starting from 0 ... n - m + 1 with a pattern string (where n is a length of a text and m is a length of a pattern) text: AAAAAAAAAAB pattern: AAAAB Visualisation: AAAAAAAAAAB AAAAB AAAAB AAAAB AAAAB AAAAB AAAAB AAAAB Time complexity - O(m * (n - m + 1)) Space complexity - O(1) 2. KMP algorithm: https://www.youtube.com/watch?v=GTJr8OvyEVQ https://www.youtube.com/watch?v=y2b94AxPlF8 Basically, there are two steps: 1. Create a new array with the same size as pattern and determine for each substring starting from 0 the length of the longerst prefix which is also a suffi of this substring. This is called - LPS - longest proper prefix which is a suffix. 2. Iterate over two string and if there's a mismatch then look up the LSP table to find a shifting position. Complexity analysis: Requires O(m) time and O(m) space to build an LSP table, where m is a length of a pattern. And also O(n) to iterate over the text string. Time complexity - O(n + m) Space complexity - O(m)

Given a pattern and a string str, find if str follows the same pattern. Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empty word in str. Example 1: Input: pattern = "abba", str = "dog cat cat dog" Output: true Example 2: Input:pattern = "abba", str = "dog cat cat fish" Output: false Example 3: Input: pattern = "aaaa", str = "dog cat cat dog" Output: false Example 4: Input: pattern = "abba", str = "dog dog dog dog" Output: false Notes: You may assume pattern contains only lowercase letters, and str contains lowercase letters separated by a single space.

The problem is similar to 205. Isomorphic Strings. 1. Efficient Split the 'str' into array. If the pattern length is not the same as 'str' length then return false. Otherwise create a mapping between a character in a pattern and word in the array using a hash map. If key exists and differs from the word in the array then return false. If key is absent but a word from the array exists as a value in a map, meaning that there's already mapping between this word and another character then return false. Time complexity - O(n^2) Map#containsValue will increase the time complexity up to n^2 Space complexity - O(n) 2. Improved We can reduce the time complexity from the above solution. Add one more map where key is a word and value is a character from the pattern. Time complexity - O(n) Space complexity - O(n)

Given a n-ary tree, find its maximum depth. The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. 1 3 2 4 5 6 We should return its max depth, which is 3. Note: The depth of the tree is at most 1000. The total number of nodes is at most 5000.

The solution is the same as for a binary tree. Use DFS and recursion. Depth for a given node will be 1 + the largest depth out of all children. Do it recursively for all nodes. Time complexity - O(n) Space complexity - O(h)

Write a function that takes a string as input and returns the string reversed. Example 1: Input: "hello" Output: "olleh" Example 2: Input: "A man, a plan, a canal: Panama" Output: "amanaP :lanac a ,nalp a ,nam A"

There are many ways to solve this problem. 1. Using a stack Put all characters in a stack. The pop them from the stack and attach to an empty string. Finally we'll get a reversed string. Time complexity - O(n) Space complexity - O(n) 2. Using two pointers. One pointer starts from the beginning, another one from the end. Swap characters under these pointers and move them to the center. Time complexity - O(n) Space complexity - O(n) - to create an array of chars 3. Using one pointer. Just iterate over the string from the beginning till the middle and swap current element and element at array.length - current - 1. Time complexity - O(n) Space complexity - O(n) - to create an array of chars 4. Using recursion Get first character and reverse the substring starting from the second character and append first character to the end of the reversed substring. Do it recursively. Time complexity - O(n) Space complexity - O(n) for recursion stack 5. Using StringBuffer StringBuffer in java has a method called reverse().

Given a string, you need to reverse the order of characters in each word within a sentence while still preserving whitespace and initial word order. Example 1: Input: "Let's take LeetCode contest" Output: "s'teL ekat edoCteeL tsetnoc" Note: In the string, each word is separated by single space and there will not be any extra space in the string.

Transform a string to array. Use two pointers to find starting and ending indices of each word. Reverse each word within the array. Time complexity - O(n) Space complexity - O(n)

A website domain like "discuss.leetcode.com" consists of various subdomains. At the top level, we have "com", at the next level, we have "leetcode.com", and at the lowest level, "discuss.leetcode.com". When we visit a domain like "discuss.leetcode.com", we will also visit the parent domains "leetcode.com" and "com" implicitly. Now, call a "count-paired domain" to be a count (representing the number of visits this domain received), followed by a space, followed by the address. An example of a count-paired domain might be "9001 discuss.leetcode.com". We are given a list cpdomains of count-paired domains. We would like a list of count-paired domains, (in the same format as the input, and in any order), that explicitly counts the number of visits to each subdomain. Example 1: Input: ["9001 discuss.leetcode.com"] Output: ["9001 discuss.leetcode.com", "9001 leetcode.com", "9001 com"] Explanation: We only have one website domain: "discuss.leetcode.com". As discussed above, the subdomain "leetcode.com" and "com" will also be visited. So they will all be visited 9001 times. Example 2: Input: ["900 google.mail.com", "50 yahoo.com", "1 intel.mail.com", "5 wiki.org"] Output: ["901 mail.com","50 yahoo.com","900 google.mail.com","5 wiki.org","5 org","1 intel.mail.com","951 com"] Explanation: We will visit "google.mail.com" 900 times, "yahoo.com" 50 times, "intel.mail.com" once and "wiki.org" 5 times. For the subdomains, we will visit "mail.com" 900 + 1 = 901 times, "com" 900 + 50 + 1 = 951 times, and "org" 5 times. Notes: The length of cpdomains will not exceed 100. The length of each domain name will not exceed 100. Each address will have either 1 or 2 "." characters. The input count in any count-paired domain will not exceed 10000. The answer output can be returned in any order.

Use a map to store a count for each subdomain. Caveat: in order to split a domain into a sub-domains we need to use .split("\\."), if we skip \\ then dot is treated as a regexp. Time complexity analysis: At first glance the time complexity is O(n * k) where k is a number of sub-domains, but according to the problem each domain will have at most two dots, which means that there'll be max 3 sub-domains and we can treat it as a constant. Therefore time complexity will be O(n) where n is a number of count-paired domains. Time complexity - O(n) Space complexity - O(n)

Given an input string, reverse the string word by word. Example: Input: "the sky is blue", Output: "blue is sky the". Note: A word is defined as a sequence of non-space characters. Input string may contain leading or trailing spaces. However, your reversed string should not contain leading or trailing spaces. You need to reduce multiple spaces between two words to a single space in the reversed string.

Use two pointers. First pointer will point to a first letter of a word, second pointer will point to a first empty character after the word. Caveats: - First we need to skip over all starting empty characters - There might be multiple empty characters between words - There might be empty tailing characters Time complexity - O(n) Space complexity - O(n)

A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' -> 1 'B' -> 2 ... 'Z' -> 26 Given a non-empty string containing only digits, determine the total number of ways to decode it. Example 1: Input: "12" Output: 2 Explanation: It could be decoded as "AB" (1 2) or "L" (12). Example 2: Input: "226" Output: 3 Explanation: It could be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2 6).

Well explained: https://www.youtube.com/watch?v=qli-JCrSwuk The most important part to start with is to consider all possible edge cases. Let's say that the input is "12345", then we can decode first two letters as 1 + 2 and 12, that means that the result will be "1" + decode("2345") plus "12" + decode("345"). This looks like recursion. Edge cases: - if the input string starts with 0, then the result will be 0, e.g "010" or "200" - if the first two letter form an integer > 26 then, e.g "345", then we can decode 34 so the result will be 3 + decode("45") 1. Brute Force Using recursion. First check if the string starts with 0 then result is 0 as well. Then take two first characters and if their integer representation is <= 26 there will be two possible ways: first letter + decode(everything after the first letter) first letter + second letter + decode(everything after the second letter) if the string is greater than 26 then there will be only one result: first letter + second letter + decode(everything after the second letter) Recursion base cases: - if string is empty then return 1 - if string starts with 0 then return 0 Time complexity - ? Space complexity - ? 2. Recursively with memoization If we take a look at the brute force solution we'll see that we solve the same sub-problems over and over again e.g if the input string is "12345", then the recursion three will look like this decode(12345) 1 + decode(2345) 1 + 2 + decode(345) 2 + decode(345) 23 + decode(45) 3 + decode(45) n/a The tree is not complete, but it's already seen that there are overlapping problems. We can add a memo map to save a solution for a sub-problem for a given index. Time complexity - O(n) Space complexity - O(n) 3. Dynamic Programming TBI

Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the root node of a BST. Calling next() will return the next smallest number in the BST. Note: next() and hasNext() should run in average O(1) time and uses O(h) memory, where h is the height of the tree.

1. Brute force Save in-order traversal in a list. Maintain a cursor variable which points to the list's index. Time complexity - O(n) Space complexity - O(1) 2. Efficient solution. Using stack. Put all left nodes of the root in the stack. When the next() method is called, then pop the element from the stack. If the element contains right sub-tree, then push all left elements of the right sub-tree onto stack. Time complexity - O(n) Space complexity - O(h)

Given an array of integers, return indices of the two numbers such that they add up to a specific target. You may assume that each input would have exactly one solution, and you may not use the same element twice. Example: Given nums = [2, 7, 11, 15], target = 9, Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1].

1. Brute Force Check all possible pair combinations using a nested loop Time complexity - O(n^2) Space complexity - O(1) 2. Using a hash map For each element check if the hashmap contains a key equal to target - nums[i], otherwise put the value and the index in the map. Time complexity - O(n) Space complexity - O(n) Info: Google Tutorial - https://www.youtube.com/watch?v=XKu_SEDAykw

Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous subarray of which the sum ≥ s. If there isn't one, return 0 instead. Example: Input: s = 7, nums = [2,3,1,2,4,3] Output: 2 Explanation: the subarray [4,3] has the minimal length under the problem constraint. Follow up: If you have figured out the O(n) solution, try coding another solution of which the time complexity is O(n log n).

1. Brute Force Check all possible sub-arrays. Time complexity - O(n^2) Space complexity - O(1) 2. Sliding window Sliding window using two pointers. Time complexity - O(n) Space complexity - O(1) 3. Binary Search TBI

Given an array of integers, 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once. Find all the elements that appear twice in this array. Could you do it without extra space and in O(n) runtime? Example: Input: [4,3,2,7,8,2,3,1] Output: [2,3]

1. Brute Force Check every element via a nested loop. Time complexity - O(n^2) Space complexity - O(1) 1. Better solution using extra space. Simply count the number of times every number appears in the array. Iterate over the map and add every entry with value equal to 2. Time complexity - O(n) Space complexity - O(n) 2. Optional solution using 'negating' We can take advantage of the following - 1 >= arr[i] <= arr.length Use the value - 1 as an index and try to negate the value. If the value has been already negated then we have a duplicate. Note: We need to modify the input array by negating its elements, but we can bring it back to the initial state using one more loop. Time complexity - O(n) Space complexity - O(1)

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. Example 1: Input: [7,1,5,3,6,4] Output: 5 Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5. Not 7-1 = 6, as selling price needs to be larger than buying price. Example 2: Input: [7,6,4,3,1] Output: 0 Explanation: In this case, no transaction is done, i.e. max profit = 0.

1. Brute Force Compare each pair of elements using a tested loop. Time complexity - O(n^2) Space complexity - O(n) 2. Efficient Let's assume that the minimum price is a price for the first day. Iteratve over an array starting from the second day. If the current price is greater than minimum, then find the profit and check if it is maximum, otherwise if the current price is less then the current minimum price then override the current minimum price. Time complexity - O(n) Space complexity - O(1)

Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in-place. Example 1: Input: [ [1,1,1], [1,0,1], [1,1,1] ] Output: [ [1,0,1], [0,0,0], [1,0,1] ] Example 2: Input: [ [0,1,2,0], [3,4,5,2], [1,3,1,5] ] Output: [ [0,0,0,0], [0,4,5,0], [0,3,1,0] ] Follow up: A straight forward solution using O(mn) space is probably a bad idea. A simple improvement uses O(m + n) space, but still not the best solution. Could you devise a constant space solution?

1. Brute Force Create a temporary boolean array with the same size as the input array. Set true if cell has 0 values in the input array. Then iterate over the input array, and nullify the row and the column if the corresponding cell contains 'true' in the temporary array. Time complexity - O(n*m) Space complexity - O(n*m) 2. Efficient We only need to know if some column and row contains 0 and we don't care where exactly. If the row contains 0 then we can set 0 in the first column of this row. If the column contains 0 then we can set 0 in the first row of this column. In this way we will know which row and column we need to nullify. The only thing is that we need to first check if the first column and first column contained 0 themselves. Time complexity - O(n*m) Space complexity - O(1)

You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). Note: You have to rotate the image in-place, which means you have to modify the input 2D matrix directly. DO NOT allocate another 2D matrix and do the rotation. Example 1: Given input matrix = [ [1,2,3], [4,5,6], [7,8,9] ], rotate the input matrix in-place such that it becomes: [ [7,4,1], [8,5,2], [9,6,3] ] Example 2: Given input matrix = [ [ 5, 1, 9,11], [ 2, 4, 8,10], [13, 3, 6, 7], [15,14,12,16] ], rotate the input matrix in-place such that it becomes: [ [15,13, 2, 5], [14, 3, 4, 1], [12, 6, 8, 9], [16, 7,10,11] ]

1. Brute Force Create an extra 2d array and move all elements from the input array into the extra array in a rotated order. Then move elements from the extra array into the input in the same order. Time complexity - O(n*m) Space complexity - O(n*m) 2. Efficient Rotating by layers. Time complexity - O(n*m) Space complexity - O(1) Info: https://www.youtube.com/watch?v=aClxtDcdpsQ

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]). Find the minimum element. You may assume no duplicate exists in the array. Example 1: Input: [3,4,5,1,2] Output: 1 Example 2: Input: [4,5,6,7,0,1,2] Output: 0

1. Brute Force Do a simple linear scan maintaining a minimum value Time complexity - O(n) Space complexity - O(1) 2. Binary Search The idea: Since array initially was sorted we can use a binary search. Find the middle element. If the middle element is greater than the high element, the the minimum element will be on the right side of the middle element exclusively. If the middle element is less than the high element, the the middle element itself might be a minimum element or it can be somewhere on the left side of the middle element. Time complexity - O(logn) Space complexity - O(1)

Given an array nums of n integers where n > 1, return an array output such that output[i] is equal to the product of all the elements of nums except nums[i]. Example: Input: [1,2,3,4] Output: [24,12,8,6] Note: Please solve it without division and in O(n). Follow up: Could you solve it with constant space complexity? (The output array does not count as extra space for the purpose of space complexity analysis.)

1. Brute Force Find product of all numbers using a nested loop. Time complexity - O(n^2) Space complexity - O(1) 2. Optimal with extra space Find left and right poduct for each element. Multiple the left and right product for each element. 'Left' array represents left products. The element's value is a product of all the elements on the left side of this element in the input array. 'Right' array represents right products. The element's values is a product of all the elements on the right side of this element in the input array. Time complexity - O(n) Space complexity - O(n) 3. Tricky Based on the previous solution we can see that we need to know the product of all the elements on the left and the right side in order to calculate a product of all the elements except self. We can do it without extra space. First, we go from left ro right and calculate the left product for each element save this value in a new array. Then we go from right to left and multiply the value during iteration (left product of the elements on the left side) and the product of the right elements. We can save the product of the right elements in only one variable - multiplier. Time complexity - O(n) Space complexity - O(1)

Given a singly linked list, determine if it is a palindrome. Example 1: Input: 1->2 Output: false Example 2: Input: 1->2->2->1 Output: true Follow up: Could you do it in O(n) time and O(1) space?

1. Brute Force Iterate over a list and push each element onto a stack. Then do one mote pass over the list and check if the element is equal to the top element on the stack, if they are not return false, if they are then just pop the element and check the rest. Time complexity - O(n) Space complexity - O(n) 2. Reversing a half Return the second half of the list. Then iterate over the first and second halves and check the elements. Important point: if the length of the list is even, then the second part should start from the middle element, otherwise from the middle + 1 element. e.g [1,2,3,2,1] the length is odd, the second part is [... 2, 1] where middle is 3 [1,2,2,1] the length is event, the second part is [... 2, 1] where middle is 2 If we're not allowed to modify the input list, we need to reverse the second half back. Time complexity - O(n) Space complexity - O(1)

Given an array nums and a value val, remove all instances of that value in-place 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. The order of elements can be changed. It doesn't matter what you leave beyond the new length. Example 1: Given nums = [3,2,2,3], val = 3, Your function should return length = 2, with the first two elements of nums being 2. It doesn't matter what you leave beyond the returned length. Example 2: Given nums = [0,1,2,2,3,0,4,2], val = 2, Your function should return length = 5, with the first five elements of nums containing 0, 1, 3, 0, and 4. Note that the order of those five elements can be arbitrary. It doesn't matter what values are set beyond the returned length.

1. Brute Force Push all elements equal to val to the end of array in a bubble sort manner using a nested loop. Time complexity - O(n^2) Space complexity - O(1) 2. Efficient. Similar to Move zeros We can maintain an 'insert index' variable initially set to 'val'. Iterate over an array and if we encounter non 'val' value then insert it at the 'insert index' in the array and increment 'insert index' by one. Time complexity - O(n) Space complexity - O(1)

A peak element is an element that is greater than its neighbors. Given an input array nums, where nums[i] ≠ nums[i+1], find a peak element and return its index. The array may contain multiple peaks, in that case return the index to any one of the peaks is fine. You may imagine that nums[-1] = nums[n] = -∞. Example 1: Input: nums = [1,2,3,1] Output: 2 Explanation: 3 is a peak element and your function should return the index number 2. Example 2: Input: nums = [1,2,1,3,5,6,4] Output: 1 or 5 Explanation: Your function can return either index number 1 where the peak element is 2, or index number 5 where the peak element is 6. Note: Your solution should be in logarithmic complexity.

1. Brute Force Use a linear search. If element is greater than its right element then we found a peak. It might happen if peak is a first element or we've reached the peak somewhere after the first element. Time complexity - O(n) Space complexity - O(1) 2. Binary Search Each local maximum is a peak. Local maximum is an element greater than its left and right neighbor. If lo is equal to hi then we found a peak. Owtherwise we need to find a mid, if mid is less than the next element, then we need to make lo = mid + 1, if the mid is greater than the next element, then we need to make hi = mid Time complexity - O(logn) Space complexity - O(1)

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]). You are given a target value to search. If found in the array return its index, otherwise return -1. You may assume no duplicate exists in the array. Your algorithm's runtime complexity must be in the order of O(log n). Example 1: Input: nums = [4,5,6,7,0,1,2], target = 0 Output: 4 Example 2: Input: nums = [4,5,6,7,0,1,2], target = 3 Output: -1

1. Brute Force Use a simple linear search Time complexity - O(n) Space complexity - O(1) 2. Binary Search The idea: we know that at least one part of the array is always sorted ot the whole array is sorted if it's not rotated. Based on this we can use a binary search. The important part is that one part of the arary is always sorted!!! There are the following cases: 1. We find a middle element as usual - mid = (lo + hi) / 2. If this middle element is equal to target we return the mid. 2. If a sub array starting from the mid element till the end of array is sorted, then there are two cases: 2.1 target is greater than mid and less or equal to the high element, then we make low element = mid + 1 2.2 target element is not between mid and high element, then we make the high element = mid - 1 3. This case will be executed if the sub array from the mid element till the high element of the array is not sorted, then the **left part of the array will be sorted**. There are also two cases: 3.1 If the target is less than mid element and equal or greater than low element, then we make high element mid - 1 3.2 If the target element is not between the low and mid element, then we make low element = mid + 1 Time complexity - O(logn) Space complexity - O(1) Info: https://www.youtube.com/watch?v=uufaK2uLnSI

Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum. Example: Input: [-2,1,-3,4,-1,2,1,-5,4], Output: 6 Explanation: [4,-1,2,1] has the largest sum = 6. Follow up: If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

1. Brute Force We may check all possible sub-arrays using a nested loop. Time complexity - O(n^2) Space complexity - O(1) 2. Kadane's algorithm We need to have two variable: sum and curr. Let's say that initially our maximum sub-array is the first element. Then iterate over an array starting from the second element. For each element we have a choice. If the value of the current element is greater then the value of this element plus the value of the previous max sub-array, then we add it upp to the previous max sub-array, otherwise we start a new max sub-array from the current element. max = Math.max(nums[i], nums[i] + prevMaxSubArray) Time complexity - O(n) Space complexity - O(1) Info: https://www.youtube.com/watch?v=86CQq3pKSUw

Implement a MyCalendar class to store your events. A new event can be added if adding the event will not cause a double booking. Your class will have the method, book(int start, int end). Formally, this represents a booking on the half open interval [start, end), the range of real numbers x such that start <= x < end. A double booking happens when two events have some non-empty intersection (ie., there is some time that is common to both events.) For each call to the method MyCalendar.book, return true if the event can be added to the calendar successfully without causing a double booking. Otherwise, return false and do not add the event to the calendar. Your class will be called like this: MyCalendar cal = new MyCalendar(); MyCalendar.book(start, end) Example 1: MyCalendar(); MyCalendar.book(10, 20); // returns true MyCalendar.book(15, 25); // returns false MyCalendar.book(20, 30); // returns true Explanation: The first event can be booked. The second can't because time 15 is already booked by another event. The third event can be booked, as the first event takes every time less than 20, but not including 20. Note: The number of calls to MyCalendar.book per test case will be at most 1000. In calls to MyCalendar.book(start, end), start and end are integers in the range [0, 10^9].

1. Brute Force While adding a new booking we can check if there's overlapping or not. We can save booking as an array with 2 elements. Important: If existing.start < new.end && existing.end > new.start then we the bookings overlap. This is called the De Morgan's laws Time complexity - O(n^2), it takes O(n) to add a booking, we will do it n times, so the complexity is O(n^2) Space complexity - O(n) where n is a number of bookings 2. Efficient TreeMap-based solution We can store booking in a map where key is 'start' and value is 'end'. This will allow us to check for overlapping in logn time. Info: The floorKey(K key) method is used to return the greatest key less than or equal to the given key, or null if there is no such key. The ceilingKey(K key) method is used to return the least key greater than or equal to the given key, or null if there is no such key. Concept explained well here - leetcode.com/problems/my-calendar-i/discuss/109462/Java-8-liner-TreeMap/111343 Time complexity - O(nlogn) where n is a number of bookings and logn is time to check for overlapping for each element Space complexity - O(n) - for all bookings 3. Custom BST TBI

Given an array of integers nums sorted in ascending order, find the starting and ending position of a given target value. Your algorithm's runtime complexity must be in the order of O(log n). If the target is not found in the array, return [-1, -1]. Example 1: Input: nums = [5,7,7,8,8,10], target = 8 Output: [3,4] Example 2: Input: nums = [5,7,7,8,8,10], target = 6 Output: [-1,-1]

1. Brute Force ​ Use a linear search. ​ Time complexity - O(n) Space complexity - O(1) 2. Expanding Find a target element using a binary search. The expand the range around the found index. Time complexity - O(n) in worst case if all elements are the same, in average O(logn + k) where k is a number of occurrences Space complexity - O(1) 3. Two binary searches TBI Info: https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/discuss/14699/Clean-iterative-solution-with-two-binary-searches-(with-explanation)

Given a sorted array nums, 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 1: 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 returned length. Example 2: Given nums = [0,0,1,1,1,2,2,3,3,4], Your function should return length = 5, with the first five elements of nums being modified to 0, 1, 2, 3, and 4 respectively. It doesn't matter what values are set beyond the returned length.

1. Brute Force using extra space Set can help us to get rid of duplicate elements. We need to use LinkedHashSet to preserver the sorted order of the elements. Add all elements to the set. Then iterate over the set and override elements in the array. Return set's length. Time complexity - O(n) Space complexity - O(n) 2. Efficient slow/fast pointers Using slow and fast pointer. If values are the same then fast pointer goes one step forward. Otherwise, write fast value to slow value. Time complexity - O(n) Space complexity - O(n)

Given an array of 2n integers, your task is to group these integers into n pairs of integer, say (a1, b1), (a2, b2), ..., (an, bn) which makes sum of min(ai, bi) for all i from 1 to n as large as possible. Example 1: Input: [1,4,3,2] Output: 4 Explanation: n is 2, and the maximum sum of pairs is 4 = min(1, 2) + min(3, 4). Note: n is a positive integer, which is in the range of [1, 10000]. All the integers in the array will be in the range of [-10000, 10000].

1. Brute force Sort the array first. Then calculate a sum of each even element in the array (even by index). Time complexity - O(nlogn) Space complexity - O(1) 2. Efficient https://leetcode.com/problems/array-partition-i/discuss/102180/Java-O(n)-beats-100

Given a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original BST is changed to the original key plus sum of all keys greater than the original key in BST. Example: Input: The root of a Binary Search Tree like this: 5 / \ 2 13 Output: The root of a Greater Tree like this: 18 / \ 20 13

1. Brute force Add elements to a list according to a in-order sequence. Traverse the list from the end, and the sum from the right to the current element. Time complexity - O(n) Space complexity - O(n) 2. Reversed in-order without extra space The trick is to reverse the in-order traversal. Since the tree is BST and the reversed in-order will produce an array sorted in decreasing order, we can track and sum up all the elements that we've seen so far and add this sum to a current node. Time complexity - O(n) Space complexity - O(1) Drawback - requires global variable, as a workaround we can pass an array with only one element, and update its value

Given an array of integers, find if the array contains any duplicates. Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct. Example 1: Input: [1,2,3,1] Output: true Example 2: Input: [1,2,3,4] Output: false Example 3: Input: [1,1,1,3,3,4,3,2,4,2] Output: true

1. Brute force Check every possible pair of elements, it the values are equals then we have duplicates and we return true; Time complexity - O(n^2) Space complexity - O(1) 2. Using sorting Sort the array. Iterate over it, and if two consecutive elements are equals then we have duplicates and we return true. Time complexity - O(nlogn) Space complexity - O(1) 3. Optimal using extra space Add each element from the array to a set. Set's add method return true if it didn't contain the added element before, otherwise returns false. Return true if set's method add returns false, which means that we found a duplicate. Time complexity - O(n) Space complexity - O(n) Info: https://leetcode.com/problems/contains-duplicate/discuss/60858/Possible-solutions.

Given an array of integers and an integer k, find out whether there are two distinct indices i and j in the array such that nums[i] = nums[j] and the absolute difference between i and j is at most k. Example 1: Input: nums = [1,2,3,1], k = 3 Output: true Example 2: Input: nums = [1,0,1,1], k = 1 Output: true Example 3: Input: nums = [1,2,3,1,2,3], k = 2 Output: false

1. Brute force Consider all possible pairs using a nested loop. Time complexity - O(n^2) Space complexity - O(1) 2. Efficient Remember the 'last seen' index of the element. Next time when you encounter this element again check its 'last seen' index. If the absolute difference is greater than K then override its 'last seen' index with the current index. Hint: You can always override the current index using Map#put method, put will return the previous value if it existed. Time complexity - O(n) Space complexity - O(n)

Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as follows: The left subtree of a node contains only nodes with keys less than the node's key. The right subtree of a node contains only nodes with keys greater than the node's key. Both the left and right subtrees must also be binary search trees. Example 1: Input: 2 / \ 1 3 Output: true Example 2: 5 / \ 1 4 / \ 3 6 Output: false Explanation: The input is: [5,1,4,null,null,3,6]. The root node's value is 5 but its right child's value is 4.

1. Brute force Create an array of in-order traversal. Then check if each element in the array is greater then the previous one. It works well only if we don't have duplicates. The algorithm fails one the following example: 20 20 20 20 The in-order array will have the following element [20, 20] and it's impossible to define if BST is valid or not. Time complexity - O(n) Space complexity - O(n) 2. Efficient DFS. In order traversal (CTCI solution) Based on the previous example we see that we need array only to get the previous value. We can save value as 'the previous' once we visited it. If 'the previous' is not null and the current node's value is less or equals to the previous one then BST is invalid. Time complexity - O(n) Space complexity - O(n)

Given an integer array, find three numbers whose product is maximum and output the maximum product. Example 1: Input: [1,2,3] Output: 6 Example 2: Input: [1,2,3,4] Output: 24 Note: The length of the given array will be in range [3,104] and all elements are in the range [-1000, 1000]. Multiplication of any three numbers in the input won't exceed the range of 32-bit signed integer.

1. Brute force If the array contains only positive numbers then we can sort it and find the product of the last 3 elements. But if there are not only positive numbers, then the product of the maximum 3 elements won't always be the result. e.g consider the following array [-10,-5,0,1,2,3]. The array is sorted, and the product of the 3 maximum values is 1 * 2 * 3 = 6 but the result will be -10 * -5 * 3 = 150. Time complexity - O(nlogn) Space complexity - O(1) 2. Efficient solution Based on the previous example we know that we need to find 3 maximum elements and 2 minimum elements. We can do it linearly without sorting. The comparison will be the same as in the previous solution. Time complexity - O(n) Space complexity - O(1)

Given string S and a dictionary of words words, find the number of words[i] that is a subsequence of S. Example : Input: S = "abcde" words = ["a", "bb", "acd", "ace"] Output: 3 Explanation: There are three words in words that are a subsequence of S: "a", "acd", "ace". Note: All words in words and S will only consists of lowercase letters. The length of S will be in the range of [1, 50000]. The length of words will be in the range of [1, 5000]. The length of words[i] will be in the range of [1, 50].

1. Brute force Iterate over an array, and check if each word is a sub-sequence of the 's' word. Time complexity - O(n*m) where n is a number of words and m is length of the longest word Space complexity - O(1) 2. Tricky https://leetcode.com/problems/number-of-matching-subsequences/discuss/117634/Efficient-and-simple-go-through-words-in-parallel-with-explanation public int numMatchingSubseq(String s, String[] words) { Map<Character, Deque<String>> map = new HashMap<>(); int count = 0; for (char i = 'a'; i <= 'z'; i++) { map.put(i, new LinkedList<>()); } for (String w: words) { map.get(w.charAt(0)).addLast(w); } for(char c: s.toCharArray()) { Deque<String> queue = map.get(c); int size = queue.size(); for (int i = 0; i < size; i++) { String str = queue.pollFirst(); if (str.length() == 1) { count++; } else { map.get(str.charAt(1)).addLast(str.substring(1)); } } } return count; } Time complexity - ? Space complexity - ?

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. Example: Input: 1->2->4, 1->3->4 Output: 1->1->2->3->4->4

1. Iterative This is a second part of the Merge Sort. Time complexity - O(n) where n is a length of the shortest linked list Space complexity - O(1) 2. Recursive Compare two nodes and find the node with a minimum value. This node will be a head. Find the next node recursively. Time complexity - O(n) Space complexity - O(n) for recursion stack

Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements. Example: Input: [0,1,0,3,12] Output: [1,3,12,0,0] Note: You must do this in-place without making a copy of the array. Minimize the total number of operations.

1. Brute force The idea is to push all 0 to the end of the array in a bubble sort manner. Maintain two loops, one loop goes from right to left, nested loop goes from left to right. If we encounter a 0 in the nested loop, then we swap it with the next element. Eventually all 0's will be at the end of the array. Time complexity - O(n^2) Space complexity - O(1) 2. Optimal with extra space Add all non zero values to a list. Then iterate over an array, if index is less then the list's size then override the element in the array by the element from the list, otherwise set zero in the array. Time complexity - O(n) Space complexity - O(n) 3. Efficient tricky We can maintain an 'insert index' variable initially set to 0. Iterate over an array and if we encounter non zero value then insert it at the 'insert index' in the array and increment 'insert index' by one. Time complexity - O(n) Space complexity - O(1)

Given an unsorted array of integers, find the length of longest continuous increasing subsequence (subarray). Example 1: Input: [1,3,5,4,7] Output: 3 Explanation: The longest continuous increasing subsequence is [1,3,5], its length is 3. Even though [1,3,5,7] is also an increasing subsequence, it's not a continuous one where 5 and 7 are separated by 4. Example 2: Input: [2,2,2,2,2] Output: 1 Explanation: The longest continuous increasing subsequence is [2], its length is 1. Note: Length of the array will not exceed 10,000.

1. Brute force Traverse over an array. For each element check if the next element is greater then previous one in a nested loop. Time complexity - O(n^2) Space complexity - O(1) 2. Efficient Maintain two variables max and current. If the current element is greater then previous one then increment current and set its values to max if it is greater, otherwise reset count to 1. Time complexity - O(n) Space complexity - O(1)

Given an array consisting of n integers, find the contiguous subarray of given length k that has the maximum average value. And you need to output the maximum average value. Example 1: Input: [1,12,-5,-6,50,3], k = 4 Output: 12.75 Explanation: Maximum average is (12-5-6+50)/4 = 51/4 = 12.75 Note: 1 <= k <= n <= 30,000. Elements of the given array will be in the range [-10,000, 10,000].

1. Brute force Check all possible contiguous sub arrays with the length of k. Caveat: Double.MIN_VALUE is actually a positive value, we need to use Double.NEGATIVE_INFINITY or -Double.MIN_VALUE Time complexity - O(n^2) Space complexity - O(1) 2. Sliding window Find ths sum of k first elements which is called a "window". Then slide this window by one element till the end of array extracting the first element of window 'i - k' and adding the current element 'i' during iteration. Time complexity - O(n) Space complexity - O(1)

Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once. Find all the elements of [1, n] inclusive that do not appear in this array. Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space. Example: Input: [4,3,2,7,8,2,3,1] Output: [5,6]

1. Brute force. Add all elements to a set. Then iterate 1..n and try to add each element to the set. If the element is added successfully, then it was absent in the input array. Time complexity - O(n) Space complexity - O(n) 2. Optional solution using 'negating' We can take advantage of the following - 1 >= arr[i] <= arr.length Use the value of each element as index and then negate the value for this index. Eventually, all the indices for positive values can be used as a result. Note: We need to modify the input array by negating its elements, but we can bring it back to the initial state using one more loop. Time complexity - O(n) Space complexity - O(1)

Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum equals to k. Example 1: Input:nums = [1,1,1], k = 2 Output: 2 Note: The length of the array is in range [1, 20,000]. The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7].

1. Brute force. Check every possible sub-array using a nested loop Time complexity - O(n^2) Space complexity - O(1) 2. Using pre sum - optimal solution with extra space Use a map to store a sum on each index. Algorithm: - Loop over an array - Calculate sum for each index (0...i) and store the value with the number of times this sum has been seen in a Map - Having a sum for a current index check whether there's a 'k - currentSum' key in the Map. If there is then the value will be the number of sub-arrays Time complexity - O(n) Space complexity - O(n) (in the worst case we have a different sum for every index)

Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times. You may assume that the array is non-empty and the majority element always exist in the array. Example 1: Input: [3,2,3] Output: 3 Example 2: Input: [2,2,1,1,1,2,2] Output: 2 Solution: 1. Brute force. Use map to count the number for each element. Loop over the map and check if the count is > length / 2 Time complexity - O(n) Space complexity - O(n) 2. Without extra space using sorting. Sort the input array. The middle element will be the one. Time complexity - O(nlogn) Space complexity - O(1) (depends on the sorting) 3. Boyer-Moore vote algorithm Time complexity - O(n) Space complexity - O(1)

1. Brute force. Use map to count the number for each element. Loop over the map and check if the count is > length / 2 Time complexity - O(n) Space complexity - O(n) 2. Without extra space using sorting. Sort the input array. The middle element will be the one. Time complexity - O(nlogn) Space complexity - O(1) (depends on the sorting) 3. Boyer-Moore vote algorithm Time complexity - O(n) Space complexity - O(1)

Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *next; } Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL. Initially, all next pointers are set to NULL. Note: You may only use constant extra space. Recursive approach is fine, implicit stack space does not count as extra space for this problem. You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children). Example: Given the following perfect binary tree, 1 / \ 2 3 / \ / \ 4 5 6 7 After calling your function, the tree should look like: 1 -> NULL / \ 2 -> 3 -> NULL / \ / \ 4->5->6->7 -> NULL

1. Iteratively. Using BFS. Do level order traversal and point next to the next element in a queue if queue size is greater then 0 Time complexity - O(n) Space complexity - O(n) 2. Recursively Do pre-order traversal. If node has left and right childs, then set left's next child to right child. And if node itself has next element, then set right's next to node's next's left. Time complexity - O(n) Space complexity - O(logn) - tree is perfect

Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According to the definition of LCA on Wikipedia: "The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself)." Given the following binary tree: root = [3,5,1,6,2,0,8,null,null,7,4] _______3______ / \ ___5__ ___1__ / \ / \ 6 _2 0 8 / \ 7 4 Example 1: Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 Output: 3 Explanation: The LCA of of nodes 5 and 1 is 3. Example 2: Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 Output: 5 Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition. Note: All of the nodes' values will be unique. p and q are different and both values will exist in the binary tree.

1. Building a path. Build a path from root to p node and from root to q node. Traverse both paths from the beginning, once we found two nodes with different values then the previous node is a LCA. Time complexity - O(n) Space complexity - O(n) 2. Recursively The idea is to traverse the tree starting from the root. If any of the given keys (q and p) match with root, then root is LCA (assuming that both keys are present). If root doesn't match with any of the keys, we recur for left and right subtree. The node which has one key present in its left subtree and the other key present in right subtree is the LCA. If both keys lie in left subtree, then left subtree has LCA also, otherwise LCA lies in right subtree. Note: this algorithms only works if q and p both exist. If one of them might be absent we can maintain two boolean variables, pFound and qFound. Time complexity - O(n) Space complexity - O(n) 3. Optimized version of the previous solution One we found that the result of the left sub-tree is not null, it may happend that we found a LCA in the left side. If the returned value is not equals to P or Q then it's a LCA. If the return values if either equal to P or Q then we found that left sub-tree cointains either P and Q. Therefore, we can check if the returned left result is not equals to P and Q then we can skip searching in the right sub-tree and just return the left result. Time complexity - O(n) Space complexity - O(n)

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. Example: board = [ ['A','B','C','E'], ['S','F','C','S'], ['A','D','E','E'] ] Given word = "ABCCED", return true. Given word = "SEE", return true. Given word = "ABCB", return false.

1. DFS with backtracking and extra space ​ Iterate over the matrix and check if the word starts with a letter at a specific cell. If so, then we need to check 4 possible directions for second letter of this word. We also need to mark already visited cells, that's why we need to have an extra matrix with boolean values. ​ Time complexity - O(n*m*k) where n is a height of a matrix, m is a width and k is a length of a word Space complexity - O(n*m) ​ 2. DFS with backtracking without extra space We can use the same matrix to mark the visited cell via '!' or '?'. In case of backtracking we need to revert the value to the initial one. Time complexity - O(n*m*k) where n is a height of a matrix, m is a width and k is a length of a word Space complexity - O(1)

Given an array of integers nums, write a method that returns the "pivot" index of this array. We define the pivot index as the index where the sum of the numbers to the left of the index is equal to the sum of the numbers to the right of the index. If no such index exists, we should return -1. If there are multiple pivot indexes, you should return the left-most pivot index. Example 1: Input: nums = [1, 7, 3, 6, 5, 6] Output: 3 Explanation: The sum of the numbers to the left of index 3 (nums[3] = 6) is equal to the sum of numbers to the right of index 3. Also, 3 is the first index where this occurs. Example 2: Input: nums = [1, 2, 3] Output: -1 Explanation: There is no index that satisfies the conditions in the problem statement. Note: The length of nums will be in the range [0, 10000]. Each element nums[i] will be an integer in the range [-1000, 1000].

1. Efficient Calculate the sum of all elements. Iterate over an array and keep tracking of the left sum. The left sum is a sum of all elements prior to the current element during iteration. If sum - leftSum - current element is equals to leftSum then we found the left most index. Time complexity - O(n) Space complexity - O(1)

Given a sorted integer array without duplicates, return the summary of its ranges. Example 1: Input: [0,1,2,4,5,7] Output: ["0->2","4->5","7"] Explanation: 0,1,2 form a continuous range; 4,5 form a continuous range. Example 2: Input: [0,2,3,4,6,8,9] Output: ["0","2->4","6","8->9"] Explanation: 2,3,4 form a continuous range; 8,9 form a continuous range.

1. Efficient Use two pointers. Time complexity - O(n) Space complexity - O(1)

S and T are strings composed of lowercase letters. In S, no letter occurs more than once. S was sorted in some custom order previously. We want to permute the characters of T so that they match the order that S was sorted. More specifically, if x occurs before y in S, then x should occur before y in the returned string. Return any permutation of T (as a string) that satisfies this property. Example Input: S = "cba" T = "abcd" Output: "cbad" Explanation: "a", "b", "c" appear in S, so the order of "a", "b", "c" should be "c", "b", and "a". Since "d" does not appear in S, it can be at any position in T. "dcba", "cdba", "cbda" are also valid outputs.

1. Iterate over all characters of a string "T", calculate their count and store in the array 2. Iterate over all characters of a string "S" and add each character to a new string while its count is not 0 in the array. 3. Iterate over the array and add each character to a string while it's count is not zero. Time Complexity: O(m + n) Space Complexity: O(m)

Given a binary array, find the maximum number of consecutive 1s in this array. Example 1: Input: [1,1,0,1,1,1] Output: 3 Explanation: The first two digits or the last three digits are consecutive 1s. The maximum number of consecutive 1s is 3. Note: The input array will only contain 0 and 1. The length of input array is a positive integer and will not exceed 10,000

1. Iterative The idea is to have global max and current max variables initially set to 0. When we encounter 0 we reset current max, other wise we increment it and update global max if it less then current max. Time complexity - O(n) Space complexity - O(1)

Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. You may assume no duplicates in the array. Example 1: Input: [1,3,5,6], 5 Output: 2 Example 2: Input: [1,3,5,6], 2 Output: 1 Example 3: Input: [1,3,5,6], 7 Output: 4 Example 4: Input: [1,3,5,6], 0 Output: 0

1. Linear Iterate over an array. If we found a value greater OR equal to the target then return its index. If no such value is found then return the length of the array, which means that the element should be added to the tail of the array. Time complexity - O(n) Space complexity - O(1) 2. Binary search We know that the array is sorted and there are no duplicates. The desired index can be found using a binary search. Time complexity - O(logn) Space complexity - O(1)

Given a binary matrix A, we want to flip the image horizontally, then invert it, and return the resulting image. To flip an image horizontally means that each row of the image is reversed. For example, flipping [1, 1, 0] horizontally results in [0, 1, 1]. To invert an image means that each 0 is replaced by 1, and each 1 is replaced by 0. For example, inverting [0, 1, 1] results in [1, 0, 0]. Example 1: Input: [[1,1,0],[1,0,1],[0,0,0]] Output: [[1,0,0],[0,1,0],[1,1,1]] Explanation: First reverse each row: [[0,1,1],[1,0,1],[0,0,0]]. Then, invert the image: [[1,0,0],[0,1,0],[1,1,1]] Example 2: Input: [[1,1,0,0],[1,0,0,1],[0,1,1,1],[1,0,1,0]] Output: [[1,1,0,0],[0,1,1,0],[0,0,0,1],[1,0,1,0]] Explanation: First reverse each row: [[0,0,1,1],[1,0,0,1],[1,1,1,0],[0,1,0,1]]. Then invert the image: [[1,1,0,0],[0,1,1,0],[0,0,0,1],[1,0,1,0]] Notes: 1 <= A.length = A[0].length <= 20 0 <= A[i][j] <= 1

1. One pass Iterate over the matrix, reverse each row and flip the cell at the same time. Time complexity - O(n*m) Space complexity - O(1)

In a given integer array nums, there is always exactly one largest element. Find whether the largest element in the array is at least twice as much as every other number in the array. If it is, return the index of the largest element, otherwise return -1. Example 1: Input: nums = [3, 6, 1, 0] Output: 1 Explanation: 6 is the largest integer, and for every other number in the array x, 6 is more than twice as big as x. The index of value 6 is 1, so we return 1. Example 2: Input: nums = [1, 2, 3, 4] Output: -1 Explanation: 4 isn't at least as big as twice the value of 3, so we return -1. Note: nums will have a length in the range [1, 50]. Every nums[i] will be an integer in the range [0, 99].

1. One pass Maintain max and second max variable while iterating over an array. If the max is twice more than second max then we have a result, otherwise return - 1; Time complexity - O(n) Space complexity - O(1)

Suppose you have a long flowerbed in which some of the plots are planted and some are not. However, flowers cannot be planted in adjacent plots - they would compete for water and both would die. Given a flowerbed (represented as an array containing 0 and 1, where 0 means empty and 1 means not empty), and a number n, return if n new flowers can be planted in it without violating the no-adjacent-flowers rule. Example 1: Input: flowerbed = [1,0,0,0,1], n = 1 Output: True Example 2: Input: flowerbed = [1,0,0,0,1], n = 2 Output: False Note: The input array won't violate no-adjacent-flowers rule. The input array size is in the range of [1, 20000]. n is a non-negative integer which won't exceed the input array size.

1. One scan Find the count of places where the flower can be planted. The place is free if its left and right neighbor is also free, of if it is a first place then the next place is free, or if this is a last place, then the previous place is free. Once we found a free place, set its value to 1. Time complexity - O(n) Space complexity - O(1) 2. Optimized Use the same approach mentioned above until the number of free spaces is less then the number of flowers. Once we reached the number of free spaces we can't break the loop. Time complexity - O(n) Space complexity - O(1)

Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. Note: A leaf is a node with no children. Example: Given binary tree [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 return its depth = 3.

1. Recursive If node is null return 0. Otherwise, return 1 + the max result either from left or right subtree. Time complexity - O(n) Space complexity - O(1) not counting the recursive stack 2. Iterative (BFS, DFS) TBI

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.

1. Recursive If t1 and t2 are null then return null. If either t1 or t2 is null, return the opposite non-null node. If both are not null then create a new node with the sum of the two nodes, and recur for the left subtree and right subtree in a pre-order fashion. The same solution could be used without creating a new node, we can use either t1 or t2 as a new root. Time complexity - O(n), where n is a number of nodes from the largest tree Space complexity - O(1) not counting the recursion stack 2. Iterative TBI

Given an array where elements are sorted in ascending order, convert it to a height balanced BST. For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1. Example: Given the sorted array: [-10,-3,0,5,9], One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST: 0 / \ -3 9 / / -10 5

1. Recursive Since the array is sorted we can make a middle element a root. All element to left of this root should belong to a left subtree, on the right side - to a right subtree. Do the same recursively for left and right parts. Time complexity - O(n) Space complexity - O(1)

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

1. Recursive Two tree are equals if they root nodes are and left/right sub-trees are equal as well. Apply this logic recursively for each node. Time complexity - O(n) Space complexity - O(1) not counting the recursion stack

Given a binary tree, return all duplicate subtrees. For each kind of duplicate subtrees, you only need to return the root node of any one of them. Two trees are duplicate if they have the same structure with same node values. Example 1: 1 / \ 2 3 / / \ 4 2 4 / 4 The following are two duplicate subtrees: 2 / 4 and 4 Therefore, you need to return above trees' root in the form of a list.

1. Recursive DFS. Post-order traversal. The idea is to serialize each sub-tree starting from the bottom of the tree. Store each serialized tree in hash map and evey time when we have a new serialized sub-tree check if we already have the same sub-tree in the hashmap. Every sub-tree can be represented as 123#### where # is a null value. Time complexity - ? Space complexity - ?

Given a root node reference of a BST and a key, delete the node with the given key in the BST. Return the root node reference (possibly updated) of the BST. Basically, the deletion can be divided into two stages: Search for a node to remove. If the node is found, delete the node. Note: Time complexity should be O(height of tree). Example: root = [5,3,6,2,4,null,7] key = 3 5 / \ 3 6 / \ \ 2 4 7 Given key to delete is 3. So we find the node with value 3 and delete it. One valid answer is [5,4,6,2,null,null,7], shown in the following BST. 5 / \ 4 6 / \ 2 7 Another valid answer is [5,2,6,null,4,null,7]. 5 / \ 2 6 \ \ 4 7

1. Recursive. - Recursively find the node that has the same value as the key, while setting the left/right nodes equal to the returned subtree - Once the node is found, have to handle the below 4 cases 1. node doesn't have left or right - return null 2. node only has left subtree- return the left subtree 3. node only has right subtree- return the right subtree 4. node has both left and right - find the minimum value in the right subtree, set that value to the currently found node, then recursively delete the minimum value in the right subtree Time complexity - O(h), worst cast - O(n) when the tree is degraded Space complexity - O(1)

Given the root of a tree, you are asked to find the most frequent subtree sum. The subtree sum of a node is defined as the sum of all the node values formed by the subtree rooted at that node (including the node itself). So what is the most frequent subtree sum value? If there is a tie, return all the values with the highest frequency in any order. Examples 1 Input: 5 / \ 2 -3 return [2, -3, 4], since all the values happen only once, return all of them in any order. Examples 2 Input: 5 / \ 2 -5 return [2], since 2 happens twice, however -5 only occur once. Note: You may assume the sum of values in any subtree is in the range of 32-bit signed integer.

1. Recursively DFS. Post-order traversal. Find the sum of each sub-tree and store it in a map [sum - frequency]. Time complexity - O(n) Space complexity - O(n)

Given an n-ary tree, return the preorder traversal of its nodes' values. For example, given a 3-ary tree: Return its preorder traversal as: [1,3,5,6,2,4]. Note: Recursive solution is trivial, could you do it iteratively?

1. Recursively DFS. Same as for binary tree. Time complexity - O(n) Space complexity - O(n) 2. Iteratively Using stack. The same algorithm as for binary tree. Time complexity - O(n) Space complexity - O(n)

You need to find the largest value in each row of a binary tree. Example: Input: 1 / \ 3 2 / \ \ 5 3 9 Output: [1, 3, 9]

1. Recursively DFS. Use additional level variable to determine the index of the element in the array. Time complexity - O(n) Space complexity - O(n) 2. Iteratively BFS. Using queue. Time complexity - O(n) Space complexity - O(n)

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] ]

1. Recursively DFS. Using pre-order traversal. If level is even then add element to the end of the list, otherwise to the beginning. The trick is to use LinkedList as an inner list. Add to the beginning will cost O(1) time. Time complexity - O(n) Space complexity - O(n) 2. Iteratively BFS. Use level order traversal and linked list as an internal list. Time complexity - O(n) Space complexity - O(n)

Given an integer array with no duplicates. A maximum tree building on this array is defined as follow: The root is the maximum number in the array. The left subtree is the maximum tree constructed from left part subarray divided by the maximum number. The right subtree is the maximum tree constructed from right part subarray divided by the maximum number. Construct the maximum tree by the given array and output the root node of this tree. Example 1: Input: [3,2,1,6,0,5] Output: return the tree root node representing the following tree: 6 / \ 3 5 \ / 2 0 \ 1 Note: The size of the given array will be in the range [1,1000].

1. Recursively Find the max element a make it a root. Do the same for left part of the max element and right part recursively. Time complexity - O(n) Space complexity - O(n)

Given a binary tree, return the postorder traversal of its nodes' values. Example: Input: [1,null,2,3] 1 \ 2 / 3 Output: [3,2,1] Follow up: Recursive solution is trivial, could you do it iteratively?

1. Recursively First visit left sub-tree, then right sub-tree, then current node. Time complexity - O(n) Space complexity - O(h) 2. Iteratively with one Stack - Create an empty stack - Initialize current node as root - While current is not null OR stack is not empty - If current is not null push it onto the stack and set current = current.left - Else check if the last element's right in the stack is not null - If null, then we have a leaf and we can add it to the result list - Check if this element is the right element of the last element on the stack and while it is true and stack is not empty add the last element on the stack to the result list - Else set current = right of the last element on the stack Time complexity - O(n) Space complexity - O(h) 3. Iteratively using two stacks - Create two empty stacks - Push root onto the first stack - While the first stack is not empty - Pop the element from the stack and push it onto the second stack - if the popped element contains left element, then push it onto the first stack - if the popped element contains right element, then push it onto the first stack - Finally the second stack will contain all elements in the post-order traversal order Time complexity - O(n) Space complexity - O(n) 4. Iteratively using one stack with list reversal - Create an empty stack and push root onto it - While stack is not empty - Pop the element, and the value to the result list and push its left and right elements (if they exist) onto the stack - Reverse the result list

Given a binary tree, find the length of the longest path where each node in the path has the same value. This path may or may not pass through the root. Note: The length of path between two nodes is represented by the number of edges between them. Example 1: Input: 5 / \ 4 5 / \ \ 1 1 5 Output: 2 Example 2: Input: 1 / \ 4 5 / \ \ 4 4 5 Output: 2 Note: The given binary tree has not more than 10000 nodes. The height of the tree is not more than 1000.

1. Recursively Idea: Bottom-up solution using recursion. If node is null then the result is 0. If node's value is equal to left's value then we have 1 + result from left subtree. If node's value is equal to right's value then we have 1 + result from right subtree. Their sum might be our result. Otherwise return the max (left or right) result up to parent. Time complexity - O(n) Space complexity - O(1)

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 p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself)." Given binary search tree: root = [6,2,8,0,4,7,9,null,null,3,5] _______6______ / \ ___2__ ___8__ / \ / \ 0 _4 7 9 / \ 3 5 Example 1: Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8 Output: 6 Explanation: The LCA of nodes 2 and 8 is 6. Example 2: Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4 Output: 2 Explanation: The LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition. Note: All of the nodes' values will be unique. p and q are different and both values will exist in the BST.

1. Recursively If root's values is greater or equal than minimum value of q and p AND root's value is less or equal than maximum value of q and p then this node is the lowest common ancestor. If root's value is less than minimum value of q and p then thy to look for LCA in the right sub-tree, otherwise in the left sub-tree. Time complexity - O(h) Space complexity - O(h)

Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number. An example is the root-to-leaf path 1->2->3 which represents the number 123. Find the total sum of all root-to-leaf numbers. Note: A leaf is a node with no children. Example: Input: [1,2,3] 1 / \ 2 3 Output: 25 Explanation: The root-to-leaf path 1->2 represents the number 12. The root-to-leaf path 1->3 represents the number 13. Therefore, sum = 12 + 13 = 25. Example 2: Input: [4,9,0,5,1] 4 / \ 9 0 / \ 5 1 Output: 1026 Explanation: The root-to-leaf path 4->9->5 represents the number 495. The root-to-leaf path 4->9->1 represents the number 491. The root-to-leaf path 4->0 represents the number 40. Therefore, sum = 495 + 491 + 40 = 1026.

1. Recursively Pre-order traversal using string. If node is null then return 0. If node's left and right elements are null then parse the string as an integer. Do it recursively for each node Time complexity - O(n) Space complexity - O(n) Pre-order traversal using pre sum. Keep track of the value calculated till the current node. For every node update the value as val * 10 + node's data Time complexity - O(n) Space complexity - O(n)

Given the root node of a binary search tree (BST) and a value. You need to find the node in the BST that the node's value equals the given value. Return the subtree rooted with that node. If such node doesn't exist, you should return NULL. For example, Given the tree: 4 / \ 2 7 / \ 1 3 And the value to search: 2 You should return this subtree: 2 / \ 1 3 In the example above, if we want to search the value 5, since there is no node with value 5, we should return NULL. Note that an empty tree is represented by NULL, therefore you would see the expected output (serialized tree format) as [], not null.

1. Recursively Similar to binary search. If node's value is equals to target then the result is found. If the node's value is greater than the target - then recur to left subtree, otherwise - right subtree. Time complexity - O(logn) if tree is balanced, otherwise O(n) for degraded tree Space complexity - O(1) not counting the recursion stack 2. Iterative TBI

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] ]

1. Recursively Simple depth first search using auxiliary level variable Time complexity - O(n) Space complexity - O(n) - recursion stack 2. Iteratively Using auxiliary data structure - queue Time complexity - O(n) Space complexity - O(n)

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

1. Recursively The tree is BST. If the node's value is less then L, then we know that all elements to the left of this node can be trimmed as well, that's why we need to return the recursive call of the right node. If node's value is greater then R, that means that all elements to the right of this node are also greater than R and can be trimmed, in this case we return the recursive call for the left node. Time complexity - O(n) Space complexity - O(n)

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.

1. Recursively Two trees are symmetric if the left element of the first node is equal to the right element of the second node, right element of the first node is equal to left element of the second node and both node are equal. Apply this logic recursively for each node. Time complexity - O(n) Space complexity - O(1) not counting the recursion stack 2. Iteratively Using queue/stack. The logic is the same. Add two root nodes to queue/stack, then poll/pop them, compare and add their children in an appropriate order: left.left, right.right, left.right, right.left Time complexity - O(n) Space complexity - O(n)

Given a binary tree, return the tilt of the whole tree. The tilt of a tree node is defined as the absolute difference between the sum of all left subtree node values and the sum of all right subtree node values. Null node has tilt 0. The tilt of the whole tree is defined as the sum of all nodes' tilt. Example: Input: 1 / \ 2 3 Output: 1 Explanation: Tilt of node 2 : 0 Tilt of node 3 : 0 Tilt of node 1 : |2-3| = 1 Tilt of binary tree : 0 + 0 + 1 = 1 Note: The sum of node values in any subtree won't exceed the range of 32-bit integer. All the tilt values won't exceed the range of 32-bit integer.

1. Recursively Use post order traversal. iF the node is null then the tilt is 0, if not null - calculate the sum of the left sub-tree and the right sub tree and find the abs between them. Do it recursively for each node in a bottom up fashion. Time complexity - O(n) Space complexity - O(1) not counting the recursion stack

You need to construct a string consists of parenthesis and integers from a binary tree with the preorder traversing way. The null node needs to be represented by empty parenthesis pair "()". And you need to omit all the empty parenthesis pairs that don't affect the one-to-one mapping relationship between the string and the original binary tree. Example 1: Input: Binary tree: [1,2,3,4] 1 / \ 2 3 / 4 Output: "1(2(4))(3)" Explanation: Originallay it needs to be "1(2(4)())(3()())", but you need to omit all the unnecessary empty parenthesis pairs. And it will be "1(2(4))(3)". Example 2: Input: Binary tree: [1,2,3,null,4] 1 / \ 2 3 \ 4 Output: "1(2()(4))(3)" Explanation: Almost the same as the first example, except we can't omit the first parenthesis pair to break the one-to-one mapping relationship between the input and the output.

1. Recursively We need to consider 4 cases: 1. If root is null then we return empty string 2. If left and right subtrees are absent then we just return the node's value 3. If left is null but right exists then we add empty parenthesis instead of left and recur for right subtree. 4. If right is null we simply ignore the empty parenthesis Time complexity - O(n) Space complexity - O(1) 2. Iteratively

Given a binary tree, return the preorder traversal of its nodes' values. Example: Input: [1,null,2,3] 1 \ 2 / 3 Output: [1,2,3] Follow up: Recursive solution is trivial, could you do it iteratively?

1. Recursively Add current node to the result list. Do it recursively for the left sub-tree and then right sub-tree. Time complexity - O(n) Space complexity - O(n) 2. Iteratively Using stack. - Create an empty stack - Push the root node onto the stack - While stack is not empty - Add node's value to the result list - If right node is not null, then push it onto the stack - If left node is not null, then push it onto the stack The idea is to push right node onto stack before left node, to make sure that the right sub-tree will be visited after the left sub-tree. Time complexity - O(n) Space complexity - O(h) 3. Iteratively using Morris algorithm - Initialize current as root - While current is not NULL If left child is null a) Print current's data b) Go to the right, i.e., current = current->right Else a) Find the rightmost predecessor node in current's left subtree b) If its right is equal to the current then set its right to null and set current = current->right, otherwise print current's data, set predecessor's right to current and current = current->left Time complexity - O(n) Space complexity - O(1)

Given a binary tree, return the inorder traversal of its nodes' values. Example: Input: [1,null,2,3] 1 \ 2 / 3 Output: [1,3,2] Follow up: Recursive solution is trivial, could you do it iteratively?

1. Recursively First visit left sub-tree, then add the node's value to the list and then visit the right sub-tree. Time complexity - O(n) Space complexity - O(n) 2. Iteratively - Create an empty stack. - Initialize current node as root - Push the current node onto stack and set current = current->left until current is NULL - If current is NULL and stack is not empty then a) Pop the top item from stack. b) Add the popped item to the result list and set current = popped_item->right c) Go to step 3. - If current is NULL and stack is empty then we are done. Time complexity - O(n) Space complexity - O(h) 3. Iteratively using Morris algorithm - Initialize current as root - While current is not NULL If current does not have left child a) Print current's data b) Go to the right, i.e., current = current->right Else a) Make current as right child of the rightmost node in current's left subtree b) Go to this left child, i.e., current = current->left Time complexity - O(n) Space complexity - O(1)

Given a binary tree, find the leftmost value in the last row of the tree. Example 1: Input: 2 / \ 1 3 Output: 1 Example 2: Input: 1 / \ 2 3 / / \ 4 5 6 / 7 Output: 7 Note: You may assume the tree (i.e., the given root node) is not NULL.

1. Recursively DFS. Use pre-order traversal and depth global variable. If local depth is greater than global depth then we found a solution so far. Then recur for left and right subtree and add 1 to a local depth. Time complexity - O(n) Space complexity - O(1) not counting the recursion stack 2. Iteratively BFS. Do level order traversal. First, add right child to queue, then left child. Every time when you poll an item from the queue it might be the result. In the end result will left most element from the last level. Time complexity - O(n) Space complexity - O(n)

Given a collection of intervals, merge all overlapping intervals. Example 1: Input: [[1,3],[2,6],[8,10],[15,18]] Output: [[1,6],[8,10],[15,18]] Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6]. Example 2: Input: [[1,4],[4,5]] Output: [[1,5]] Explanation: Intervals [1,4] and [4,5] are considerred overlapping.

1. Sorting Sort the input intervals by a starting point. Add the first interval to the result list. Iterate over the rest intervals and check if the starting point is less or equal than the ending point of the last interval in the result list then we need to merge them, otherwise we need to add a new interval to the result list. Merge strategy: While merging we need to choose the maximum end point among two intervals. e.g [1, 3], [2,6] should be merged into [1,6] Time complexity - O(nlogn) + O(n) -> O(nlogn) Space complexity - O(n) the result merged list

Given a non-empty array of integers, return the third maximum number in this array. If it does not exist, return the maximum number. The time complexity must be in O(n). Example 1: Input: [3, 2, 1] Output: 1 Explanation: The third maximum is 1. Example 2: Input: [1, 2] Output: 2 Explanation: The third maximum does not exist, so the maximum (2) is returned instead. Example 3: Input: [2, 2, 3, 1] Output: 1 Explanation: Note that the third maximum here means the third maximum distinct number. Both numbers with value 2 are both considered as second maximum.

1. The idea is to use Integer and not int for initialization. Then during one pass we can find all the three values. Time complexity - O(n) Space complexity - O(1)

Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missing from the array. Example 1: Input: [3,0,1] Output: 2 Example 2: Input: [9,6,4,2,3,5,7,0,1] Output: 8 Note: Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity?

1. Using HashSet Add all elements from the array to a set. Then iterate from 0...n and and check if the element in the set. If the element in the set is absent then we found a missing number. Time complexity - O(n) Space complexity - O(n) 2. Using Gauss formula. We can find a sum of a sequnce from 1 ... n using the following formula - sum = n(n + 1)/2 We can calculate the original sum of the array in one loop. Then the difference between the expected and original sum will be an answer. Time complexity - O(n) Space complexity - O(1)

Given a string, sort it in decreasing order based on the frequency of characters. Example 1: Input: "tree" Output: "eert" Explanation: 'e' appears twice while 'r' and 't' both appear once. So 'e' must appear before both 'r' and 't'. Therefore "eetr" is also a valid answer. Example 2: Input: "cccaaa" Output: "cccaaa" Explanation: Both 'c' and 'a' appear three times, so "aaaccc" is also a valid answer. Note that "cacaca" is incorrect, as the same characters must be together. Example 3: Input: "Aabb" Output: "bbAa" Explanation: "bbaA" is also a valid answer, but "Aabb" is incorrect. Note that 'A' and 'a' are treated as two different characters.

1. Using heap Count the frequency for each letter in a string. Add each element to a heap according to its frequency. Elements with more frequency will be on top of the heap. Poll the elements from the heap one by one and append them to a result string according to its frequency. Time complexity - O(nlogn) Space complexity - O(n) 2. Using bucket sorting Count the frequency for each letter in a string. Create a 'buckets' array where index represents the frequency of a character and value is a list of characters with this frequency. Loop over the 'buckets' array from the end and append all the characters to the result string index times. Time complexity - O(n) Space Complexity - O(n)

Given a Binary Search Tree and a target number, return true if there exist two elements in the BST such that their sum is equal to the given target. Example 1: Input: 5 / \ 3 6 / \ \ 2 4 7 Target = 9 Output: True Example 2: Input: 5 / \ 3 6 / \ \ 2 4 7 Target = 28

1. Using set (this solution is good since it might be applied not only to BST) Traverse over the tree and check if there's a k - node.val value in a set. Otherwise, add the current value to a set. Time complexity - O(n) Space complexity - O(n) 2. Using in-order traversal Get a sorted array by in-order traversing a BST. Solve Two Sum problem in a sorted array. Time complexity - O(n) Space complexity - O(n)

Given a non-empty binary tree, return the average value of the nodes on each level in the form of an array. Example 1: Input: 3 / \ 9 20 / \ 15 7 Output: [3, 14.5, 11] Explanation: The average value of nodes on level 0 is 3, on level 1 is 14.5, and on level 2 is 11. Hence return [3, 14.5, 11]. Note: The range of node's value is in the range of 32-bit signed integer.

Caveat: Sum for a given level might be greater then 32-bit integer. 1. Recursively DFS. Use pre-order traversal and additional space to save count and sum for a current level. Time complexity - O(n) Space complexity - O(n) 2. Iteratively BFS. Use level order traversal via queue. Time complexity - O(n) Space complexity - O(n)

Given a non-empty binary tree, find the maximum path sum. For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path must contain at least one node and does not need to go through the root. Example 1: Input: [1,2,3] 1 / \ 2 3 Output: 6 Example 2: Input: [-10,9,20,null,null,15,7] -10 / \ 9 20 / \ 15 7 Output: 42

DFS. Post-order traversal. Find the sum of the left sub-tree and the right sub-tree. The max value can be the following: 1. Just the current node's value (in case if the sum for left and right sub-tree is 0) 2. Current node's value plus the sum of the left sub-tree 3. Current node's value plus the sum of the right sub-tree 4. Current node's value plus the sum of both left and right sub-tree Compare the values with the global variable (max so far). Return up to the caller the max value of: 1. Just node's value 2. Node's value plus the sum of the left sub-tree 3. Node's value plus the sum of the right sub-tree Time complexity - O(n) Space complexity - O(h)

Given a non-empty array of non-negative integers nums, the degree of this array is defined as the maximum frequency of any one of its elements. Your task is to find the smallest possible length of a (contiguous) subarray of nums, that has the same degree as nums. Example 1: Input: [1, 2, 2, 3, 1] Output: 2 Explanation: The input array has a degree of 2 because both elements 1 and 2 appear twice. Of the subarrays that have the same degree: [1, 2, 2, 3, 1], [1, 2, 2, 3], [2, 2, 3, 1], [1, 2, 2], [2, 2, 3], [2, 2] The shortest length is 2. So return 2. Example 2: Input: [1,2,2,3,1,4,2] Output: 6 Note: nums.length will be between 1 and 50,000. nums[i] will be an integer between 0 and 49,999.

First we need to find all degree integers in the array. Then we need to find most-left and most-right border of each degree. The smalles right border - left border + 1 will be the result. Time complexity - O(n) Space complexity - O(n)

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

Idea: We can take advantage of the fact, that all the elements are distinct. We know that the first element in the 'pre-order' sequence will be always root. We need to find this value in the 'in-order' sequence. Once we found it, we can say that all the elements before the found index should be located on the left side of a tree, all the elements after the found one - right side of the tree. Do it recursively for each local root node taken from the 'pre-order' sequence. Time complexity - TBD Space complexity - TBD

Given inorder and postorder traversal of a tree, construct the binary tree. Note: You may assume that duplicates do not exist in the tree. For example, given inorder = [9,3,15,20,7] postorder = [9,15,7,20,3] Return the following binary tree: 3 / \ 9 20 / \ 15 7

Idea: The idea is similar to the 105. Construct Binary Tree from Preorder and Inorder Traversal. The difference is that the root of the tree will be always the last element of the 'post-order' sequence. Find this value in the 'in-order' sequence. All the elements before this value in the 'in-order' sequence will be the left part of the tree, all the element after this value - right part of the tree. Time complexity - TBD Space complexity - TBD

Given a binary tree, determine if it is height-balanced. For this problem, a height-balanced binary tree is defined as: a binary tree in which the depth of the two subtrees of every node never differ by more than 1. Example 1: Given the following tree [3,9,20,null,null,15,7]: 3 / \ 9 20 / \ 15 7 Return true. Example 2: Given the following tree [1,2,2,3,3,null,null,4,4]: 1 / \ 2 2 / \ 3 3 / \ 4 4 Return false.

Idea: The tree is balanced if the absolute difference between left and right height is less than or equal to 1. This logic can be applied for all nodes. The naive solution could be to check only root node but this is gonna fail for the following tree 2 1 1 1 1 1 1 1 1 It can be seen, that the diff between max left height and max right height is 0 but the tree is not balanced. 1. Brute force Top-down solution. The tree is balanced if the roor is balanced AND left subtree is balanced AND right subtree is balanced. Checking it for every node will node to a O(n^2) time complexity cause we will recalculate height many times. Time complexity - O(n^2) Space complexity - O(1) not counting the recursion stack 2. Efficient solution Bottom-up solution. Calculate height for left subtree and right subtree starting from the bottom of a tree. If the difference between them is more than 1 then the tree is not balanced. Return the max height (left or right) up to the parent call. Time complexity - O(n) Space complexity - O(1) not counting the recursion stack

A zero-indexed array A of length N contains all integers from 0 to N-1. Find and return the longest length of set S, where S[i] = {A[i], A[A[i]], A[A[A[i]]], ... } subjected to the rule below. Suppose the first element in S starts with the selection of element A[i] of index = i, the next element in S should be A[A[i]], and then A[A[A[i]]]... By that analogy, we stop adding right before a duplicate element occurs in S. Example 1: Input: A = [5,4,0,3,1,6,2] Output: 4 Explanation: A[0] = 5, A[1] = 4, A[2] = 0, A[3] = 3, A[4] = 1, A[5] = 6, A[6] = 2. One of the longest S[K]: S[0] = {A[0], A[5], A[6], A[2]} = {5, 6, 2, 0} Note: N is an integer within the range [1, 20,000]. The elements of A are all distinct. Each element of A is an integer within the range [0, N-1].

Idea: since 'each element of A is an integer within the range [0, N-1]' and all elements are distinct, then we're going to have a cycle traversing from every index. [5,4,0,3,1,6,2] if we start from 5 then the cycle will look like this: {5 6 2 0 5} 1. Brute force Loop over an array and for each index do DFS until the first element is met again. Will end up with TLE. Time complexity - O(n^2) Space complexity - O(1) 2. Optimal solution with extra space. Mark every element as visited using an extra array. {5 6 2 0}. We can skip 6,2 and 0 visisted elements since they will form a cycle with the same length as if we start iterating from the 5th element. Time complexity - O(n) Space complexity - O(n) 3. Better solution without extra space. If we're allowed to modify the input array, then we can take an advantage of the following note - N is an integer within the range [1, 20,000]. It means that the max value in the array will be 20000. Then we don't really need to use an extra array to track visited elements, we can simply mark the element as visited by changing its value to negative in the input array. Time complexity - O(n) Space complexity - O(1)

Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum. Note: A leaf is a node with no children. Example: Given the below binary tree and sum = 22, 5 / \ 4 8 / / \ 11 13 4 / \ \ 7 2 1 return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.

Idea: the key point is that the sum should be a path FROM root TO leaf. 1. Recursively If node is a leaf (left and right elements are null) and the difference between node's value and sum is equal to 0 then we found a path. Otherwise, check the left and right subtree with the sum - current node's value; Time complexity - O(n) Space complexity - O(1) not counting the recursion stack

Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. You may assume that each input would have exactly one solution. Example: Given array nums = [-1, 2, 1, -4], and target = 1. The sum that is closest to the target is 2. (-1 + 2 + 1 = 2)

Idea: the problem is similar to 3Sum problem but we don't need to handle duplicate combinations. 1. Brute Force Maintain 3 loops and check if the absolute difference between 3 elements during iteration and the target is less then the absolute difference between the optimal result and the target, then override the optimal result. Time complexity - O(n^3) Space complexity - O(1) 2. Efficient Sort the array first. Then iterate over the array and use a nested loop to check all possible combinations. Time complexity - O(n^2) Space complexity - O(1)

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. The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49. Example: Input: [1,8,6,2,5,4,8,3,7] Output: 49

Idea: we need to find the maximum area between two walls. The area will be the product of the absolute difference between two walls and the height of the minimum wall. 1. Brute Force Check the area between all possible walls using a nested loop. Time complexity - O(n^2) Space complexity - O(1) 2. Efficient Use two pointers. We have left and right walls. Check the area between these walls, then if the height of the left wall is less then the height of the right wall then increment the left point, otherwise increment the right pointer. Time complexity - O(n) Space complexity - O(1) Info: https://leetcode.com/problems/container-with-most-water/solution/

Given a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom. Example: Input: [1,2,3,null,5,null,4] Output: [1, 3, 4] Explanation: 1 <--- / \ 2 3 <--- \ \ 5 4 <---

Idea: we need to visit right node first, then left node 1. Recursively Visit right node, then left node. Keep track of the last maximum level seen so far. If the current level is greater then previous maximum level then we can add this node's value to the result. We can avoid using a global variable by just check if level is equal to list's size. Time complexity - O(n) Space complexity - O(n) 2. Iteratively Do level order traversal. Either add right first node and then left node to a queue. Check if it is the beginning of the level, then add the value to result. We could add left node first, then right node to a queue. Then when the level's size is 1, then we found a value to be added to result. Time complexity - O(n) Space complexity - O(n)

Given a non-empty array of digits representing a non-negative integer, plus one to the integer. The digits are stored such that the most significant digit is at the head of the list, and each element in the array contain a single digit. You may assume the integer does not contain any leading zero, except the number 0 itself. Example 1: Input: [1,2,3] Output: [1,2,4] Explanation: The array represents the integer 123. Example 2: Input: [4,3,2,1] Output: [4,3,2,2] Explanation: The array represents the integer 4321.

Iterate over an array, if element is less than 9 then increment its value and return the array, otherwise set its value to 0. e.g if input array is [1,2,4] then we need to return [1,2,5] If we exited the loop it means that the first element was also 9, and we need to return a new array with a new length. e.g if input array is [9,9] then we need to return [1,0,0] Time complexity - O(n) Space complexity - O(1)

Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number. The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Note: Your returned answers (both index1 and index2) are not zero-based. You may assume that each input would have exactly one solution and you may not use the same element twice. Example: Input: numbers = [2,7,11,15], target = 9 Output: [1,2] Explanation: The sum of 2 and 7 is 9. Therefore index1 = 1, index2 = 2.

Solution: 1. Brute force. Check all elements using a nested loop. Time complexity - O(n^2) Space complexity - O(1) 2. Optional. Take advantage of a sorted array. Maintain two pointers, one starts from the beginning, another one from the end. If the sum is equals to target then we found the indices. If the sum is less then target, then increment the left pointer, otherwise increment the right one. Time complexity - O(n) Space complexity - O(1)

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 from left to right. The first integer of each row is greater than the last integer of the previous row. Example 1: Input: matrix = [ [1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50] ] target = 3 Output: true Example 2: Input: matrix = [ [1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50] ] target = 13 Output: false

Solution: The idea is to treat the matrix as a sorted list. Initially the 'lo' index will be 0 and 'hi' matrix.length * matrix.width - 1. We can find the middle element as usual mid = (lo + hi) / 2. Then we need to find the correct row and column in the matrix. midValue = matrix[mid / width][mid % width] Time complexity - O(log(n*m)) Space complexity - O(1)

Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below. For example, given the following triangle [ [2], [3,4], [6,5,7], [4,1,8,3] ] The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11). Note: Bonus point if you are able to do this using only O(n) extra space, where n is the total number of rows in the triangle.

The idea is to represent the triangle as a tree and do DFS. 1. Brute Force Recursive DFS. And find the minimum value from left and right branch. Will result in a TLE. Time complexity - O(2^n) Space complexity - O(n) 2. Top down with memoization If we draw a recursive calls for the previous solution we can see that we have a lof ot overlapping problems. We can get rid of them if we save an already calculated sum for a specific level and index. Time complexity - ? Space complexity - O(n * m) 3. Bottom-up Dynamic Programming We can use dynamic programmin with O(n) extra space. Create an empty array with a length equal to the length of the last layer in the triangle. Then iterate from the pre-last layer up to the top. For each element in the layer the minimum value will be the value itself + the minimum value from the left or right child. Time complexity - O(n*m) where n is a number of layers and m is a number of elements in the last layer Space complexity - O(m) where m is a number of elements in the last layer 4. Optimized bottom-up without extra space If we're allowed to modify the input triangle, we can store the dynamic states in the triangle itself. The idea is the same as in the 3rd solution but we don't ne to have an extra space. Time complexity - O(n * m) Space complexity - O(1)

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. Note: The solution set must not contain duplicate triplets. Example: Given array nums = [-1, 0, 1, 2, -1, -4], A solution set is: [ [-1, 0, 1], [-1, -1, 2] ]

The idea is to sort the array first. Then use a loop with a nested loop to find a sum of the elements. Time complexity - O(n^2) Space complexity - O(1)

Given a matrix A, return the transpose of A. The transpose of a matrix is the matrix flipped over it's main diagonal, switching the row and column indices of the matrix. Example 1: Input: [[1,2,3],[4,5,6],[7,8,9]] Output: [[1,4,7],[2,5,8],[3,6,9]] Example 2: Input: [[1,2,3],[4,5,6]] Output: [[1,4],[2,5],[3,6]] Note: 1 <= A.length <= 1000 1 <= A[0].length <= 1000

The idea that the height of the input array will be the width of the result array and the width of the input array will be the height of the result array. Time complexity - O(n * m) Space complexity - O(1)

Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) connected 4-directionally (horizontal or vertical.) You may assume all four edges of the grid are surrounded by water. Find the maximum area of an island in the given 2D array. (If there is no island, the maximum area is 0.) Example 1: [[0,0,1,0,0,0,0,1,0,0,0,0,0], [0,0,0,0,0,0,0,1,1,1,0,0,0], [0,1,1,0,1,0,0,0,0,0,0,0,0], [0,1,0,0,1,1,0,0,1,0,1,0,0], [0,1,0,0,1,1,0,0,1,1,1,0,0], [0,0,0,0,0,0,0,0,0,0,1,0,0], [0,0,0,0,0,0,0,1,1,1,0,0,0], [0,0,0,0,0,0,0,1,1,0,0,0,0]] Given the above grid, return 6. Note the answer is not 11, because the island must be connected 4-directionally. Example 2: [[0,0,0,0,0,0,0,0]] Given the above grid, return 0. Note: The length of each dimension in the given grid does not exceed 50.

The idea: if the cell's value is equal to 1 then we need to explore 4 possible directions. Besides that we need to track all cells that we've visited so far 1. DFS with extra space Iterate over a matrix and if we encounter 1 then mark this cell as visited and do dfs exploring 4 neighbor cells. Time complexity - O(n*m) Space complexity - O(n*m) 2. DFS without extra space Since the input matrix contains only 0 and 1 and if we're allowed to modify the input matrix, then we can change 1 to 0 once visited a cell with 1 value. Time complexity - O(n*m) Space complexity - O(1)

Given n, how many structurally unique BST's (binary search trees) that store values 1 ... n? Example: Input: 3 Output: 5 Explanation: Given n = 3, there are a total of 5 unique BST's: 1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3

The key to solution is that the tree is binary search. The idea is simple. We know that for n = 2 we can have at most 2 unique combinations, for n = 3 -> 5 and for n = 1 -> 1. If n is equal to 4, then we may have a combination when the root is 1 or 2 or 3 or 4. When the root is 1, then we don't have any elements on the left side, but we have 3 elements on the right side. We know that the number of unique combinations for 3 elements is equal to 5, which means that when the root is 1 we will have only 5 unique combinations. When the root is 2, then we have only 1 node on the left side and two nodes on the right side, which means that we need to find a product of unique combinations on both sides. The number of unique combinations on the left side is 1, on the right side is - 2 and the product will be 1 * 2. Based on this logic we can calculate the number of any 'n' combinations in a bottom-up fashion. Time complexity - O(n^2) Space complexity - O(n) Info: - https://leetcode.com/problems/unique-binary-search-trees/discuss/31666/DP-Solution-in-6-lines-with-explanation.-F(i-n)-G(i-1)-*-G(n-i) - https://www.youtube.com/watch?v=YDf982Lb84o

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). 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. Note: m and n will be at most 100. Example 1: Input: [ [0,0,0], [0,1,0], [0,0,0] ] Output: 2 Explanation: There is one obstacle in the middle of the 3x3 grid above. There are two ways to reach the bottom-right corner: 1. Right -> Right -> Down -> Down 2. Down -> Down -> Right -> Right

The problem is similar to 62. Unique Path 1. Brute Force Recursive solution. Starting from [0, 0] point calculate how many ways to reach the end of the grid using recurrent calls. If we encountered cell with 1 value then return 0. Time complexity - O(2^n) Space complexity - O(1) 2. Top-down recursion with memoization Based on the previous solution we can see that there are multiple overlapping problems occur. We can use another 2d array to solve the intermediate solution and check it in the recursive calls. Time complexity - O(n*m) Space complexity - O(n*m) 3. Bottom-up dynamic programming We can use the same input array to build the solution using dynamic programming. First we need to check if the very first cell contains 1, if so then we can return 0 immediately cause there won't be any ways how to reach the end of matrix. Then we need to traverse the matrix and if we encounter 1 in a specific cell, we need to change it's value to 0, meaning that there will be only 0 ways to reach to a neighbor cell from that 'obstacle' cell. Time complexity - O(n*m) Space complexity - O(1)

Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path. Note: You can only move either down or right at any point in time. Example: Input: [ [1,3,1], [1,5,1], [4,2,1] ] Output: 7 Explanation: Because the path 1→3→1→1→1 minimizes the sum.

The problem is similar to Unique Paths and Unique Paths II problems. 1. Brute Force Recursion with overlapping problems. Time complexity - O(2^n) Space complexity - O(1) 2. Top-down recursion with memoization Use recursion but remember the intermediate results in order to get rid of solving the same problems over and over again. Time complexity - O(n*m) Space complexity - O(n*m) 3. Bottom-up dynamic programming We can use the input array (if we're allowed to modify it) in order to build the final solution using bottom-up DP approach. Time complexity - O(n*m) Space complexity - O(1)

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? Above is a 7 x 3 grid. How many possible unique paths are there? Note: m and n will be at most 100. Example 1: Input: m = 3, n = 2 Output: 3 Explanation: From the top-left corner, there are a total of 3 ways to reach the bottom-right corner: 1. Right -> Right -> Down 2. Right -> Down -> Right 3. Down -> Right -> Right Example 2: Input: m = 7, n = 3 Output: 28

This is a fundamental Dynamic Programming problem. 1. Brute Force Recursive solution. Starting from [0, 0] point calculate how many ways to reach the end of the grid using recurrent calls. Time complexity - O(2^n) Space complexity - O(1) 2. Top-down recursion with memoization Based on the previous solution we can see that there are multiple overlapping problems occur. We can use another 2d array to solve the intermediate solution and check it in the recursive calls. Time complexity - O(n*m) Space complexity - O(n*m) 3. Bottom-up dynamic programming We can reach at any cell either from top or from left cell. Therefore the number of ways to reach the [i,j] cell will be the sum of number of ways to reach the [i - 1, j] and [i, j - 1] cells. The only difference is for the first row, where there is only one way to reach every cell (from the left side) and for the first column. There's also only one way to reach any cell in the first column - from the top cell. Time complexity - O(n*m) Space complexity - O(n*m)

On a staircase, the i-th step has some non-negative cost cost[i] assigned (0 indexed). Once you pay the cost, you can either climb one or two steps. You need to find minimum cost to reach the top of the floor, and you can either start from the step with index 0, or the step with index 1. Example 1: Input: cost = [10, 15, 20] Output: 15 Explanation: Cheapest is start on cost[1], pay that cost and go to the top. Example 2: Input: cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1] Output: 6 Explanation: Cheapest is start on cost[0], and only step on 1s, skipping cost[3]. Note: cost will have a length in the range [2, 1000]. Every cost[i] will be an integer in the range [0, 999].

This is a fundamental amd must-understand DP problem. 1. Brute Force Recursive solution. We either start from 0 or 1 point. Then we need to find the minimum result if we go +1 or +2 steps from 0 and 1 step. The same rule can be applied for each step. Time complexity - O(2^n) Space complexity - O(1) 2. Top-down with memoization Let's draw a recursion tree of the previous solution cost = [10, 15, 20, 10] 0:10 1:15 1:15 2:20 2:20 3:10 2:20 3:10 3:20 3:10 This is only the part of the recursion tree but we already see that we have overlapping problems. The more elements we have the more overlapping problems we need to solve again. We can remember the result of the intermediate problems and save it into a temporary array. Time complexity - O(n) Space complexity - O(n) 3. Bottom-up using dynamic programming approach For any step we know that the minimum cost to reach this step will be current step's cost + min(current - 1, current - 2). Hence we build a final solution by solving the sub-problems. In the end we need to choose the minimum value of the last or second last elements. DP formula: dp[i]=cost[i]+min(dp[i-1],dp[i-2]) Base cases: dp[0]=cost[0] dp[1]=cost[1] Time complexity - O(n) Space complexity - O(n) 4. Bottom-up using dynamic programming without extra space If we're allowed to change the input array, we can build the final solution using the input array. Time complexity - O(n) Space complexity - O(1)

This is a fundamental amd must-understand DP problem. 1. Brute Force Recursive solution. We either start from 0 or 1 point. Then we need to find the minimum result if we go +1 or +2 steps from 0 and 1 step. The same rule can be applied for each step. Time complexity - O(2^n) Space complexity - O(1) 2. Top-down with memoization Let's draw a recursion tree of the previous solution cost = [10, 15, 20, 10] 0:10 1:15 1:15 2:20 2:20 3:10 2:20 3:10 3:20 3:10 This is only the part of the recursion tree but we already see that we have overlapping problems. The more elements we have the more overlapping problems we need to solve again. We can remember the result of the intermediate problems and save it into a temporary array. Time complexity - O(n) Space complexity - O(n) 3. Bottom-up using dynamic programming approach For any step we know that the minimum cost to reach this step will be current step's cost + min(current - 1, current - 2). Hence we build a final solution by solving the sub-problems. In the end we need to choose the minimum value of the last or second last elements. DP formula: dp[i]=cost[i]+min(dp[i-1],dp[i-2]) Base cases: dp[0]=cost[0] dp[1]=cost[1] Time complexity - O(n) Space complexity - O(n) 4. Bottom-up using dynamic programming without extra space If we're allowed to change the input array, we can build the final solution using the input array. Time complexity - O(n) Space complexity - O(1)

This is a really really shitty problem. 1. One pass and hash map Just store the counts in a hash map. Then iterate over the hash map entries. If k is equal to 0 and the count of entries for a given key is equal or greater than 2 then we increment a result counter by one. Otherwise if the map contains a key equal to entry.getKey() + k then we also increment the result counter by one. Time complexity - O(n) Space complexity - O(n)

A matrix is Toeplitz if every diagonal from top-left to bottom-right has the same element. Now given an M x N matrix, return True if and only if the matrix is Toeplitz. Example 1: Input: matrix = [ [1,2,3,4], [5,1,2,3], [9,5,1,2] ] Output: True Explanation: In the above grid, the diagonals are: "[9]", "[5, 5]", "[1, 1, 1]", "[2, 2, 2]", "[3, 3]", "[4]". In each diagonal all elements are the same, so the answer is True. Example 2: Input: matrix = [ [1,2], [2,2] ] Output: False Explanation: The diagonal "[1, 2]" has different elements. Note: matrix will be a 2D array of integers. matrix will have a number of rows and columns in range [1, 20]. matrix[i][j] will be integers in range [0, 99]. Follow up: What if the matrix is stored on disk, and the memory is limited such that you can only load at most one row of the matrix into the memory at once? What if the matrix is so large that you can only load up a partial row into the memory at once?

Traverse the matrix skipping the last column and the last row. We need to compare each element at matrix[n][m] with another element at matrix[n+1][m+1], if they differ then matrix is not toeplitz. Time complexity - O(n*m) Space complexity - O(1)


Set pelajaran terkait

chemistry chapter 14; acids and bases

View Set

chapter four honors mastering biology

View Set

Spanish 1 Homework Due Wed. March 28th

View Set

Nutrition, fitness, & wellness: ch. 1,2,3,4

View Set