├── .editorconfig ├── .github └── FUNDING.yml ├── .prettierrc.json ├── LICENSE ├── README.md ├── algorithms-analysis └── README.md ├── bigocheatsheet.png ├── linkedlist ├── README.md ├── circular-linked-list.md ├── doubly-linked-list.md ├── images │ ├── circular-linked-list.png │ ├── doubly-linked-list.png │ └── singly-linked-list.png ├── singly-linked-list.md └── singly_linked_list.js ├── problems ├── cracking-coding-interview │ ├── README.md │ ├── chapter-1 │ │ ├── 1.unique_chars.js │ │ ├── 2.permutation_of_two_strings.js │ │ ├── 3.permutation_of_palindrome.js │ │ ├── 4.rotate_mxn_matrix.js │ │ └── README.md │ └── chapter-2 │ │ ├── 1.remove_duplicates_linked_list.js │ │ ├── 2.sum_of_two_linked_list.js │ │ └── README.md ├── leetcode │ ├── README.md │ ├── array │ │ ├── 1.rearrange_array.js │ │ ├── 10.area_of_island.js │ │ ├── 11.missing_number.js │ │ ├── 12.distribute_candies.js │ │ ├── 13.max_consecutives_ones.js │ │ ├── 14.where_do_i_belong.js │ │ ├── 15.water_container.js │ │ ├── 16.reverse_words.js │ │ ├── 17.flower_bed.js │ │ ├── 18.rotate_array.js │ │ ├── 19.intersection_of_numbers.js │ │ ├── 2.largest_number.js │ │ ├── 20.sort_by_parity.js │ │ ├── 21.find_duplicate_number.js │ │ ├── 22.subsets.js │ │ ├── 23.longest_vowel_chain.js │ │ ├── 24.keyboard_row.js │ │ ├── 25.sum_of_consecutive_integers.js │ │ ├── 26.first_duplicate.js │ │ ├── 27.direction_reduction.js │ │ ├── 28.max_of_sub_arrays.js │ │ ├── 3.flatten_array.js │ │ ├── 4.wave_array.js │ │ ├── 5.remove_element.js │ │ ├── 6.find_relative_winners.js │ │ ├── 7.reshape_matrix.js │ │ ├── 8.max_k_elements_in_array.js │ │ ├── 9.single_number.js │ │ └── README.md │ ├── back tracking │ │ ├── 1.word_search.js │ │ ├── 2.surrounded_area.js │ │ ├── 3.paint_house.js │ │ └── README.md │ ├── bit manipulation │ │ ├── 1.number_of_1_bits.js │ │ ├── 2.sum_of_two_number.js │ │ └── README.md │ ├── cache │ │ ├── 1.lru_cache.js │ │ └── README.md │ ├── hashing │ │ ├── 1.array_of_anagrams.js │ │ ├── 2.unique_morse_codes.js │ │ ├── 3.set_matrix_zeros.js │ │ ├── 4.two_sum.js │ │ ├── 5.distribute_candies.js │ │ ├── 6.set_mismatch.js │ │ └── README.md │ ├── in place │ │ ├── 1.sort_colours.js │ │ └── README.md │ ├── linked list │ │ ├── 1.reverse_a_linked_list.js │ │ ├── 2.merge_two_linked_list_without_duplicates.js │ │ ├── 3.merge_two_linked_list_with_duplicates.js │ │ ├── 4.find_circular_linked_list.js │ │ ├── 5.intersection_of_two_inked_lists.js │ │ ├── 6.sort_linked_list.js │ │ ├── 7.remove_val_linked_list.js │ │ ├── 8.remove_duplicates.js │ │ ├── 9.binary_tree_to_linked_list.js │ │ └── README.md │ ├── numbers │ │ ├── 1.plus_one.js │ │ ├── 10.find_original_price.js │ │ ├── 11.multiple_string.js │ │ ├── 12.valid_ip.js │ │ ├── 2.integer_replacement.js │ │ ├── 3.majority_elements.js │ │ ├── 4.power_of_3.js │ │ ├── 5.count_primes.js │ │ ├── 6.string_to_integer.js │ │ ├── 7.happy_numbers.js │ │ ├── 8.find_disappearing_numbers.js │ │ ├── 9.self_dividing_numbers.js │ │ └── README.md │ ├── one pass │ │ ├── 1.max_profit.js │ │ └── README.md │ ├── recursion │ │ ├── 1.frog_jump.js │ │ └── README.md │ ├── search │ │ ├── 1.count_element_occurence.js │ │ ├── 2.search_insert_position.js │ │ ├── 3.trailing_factorial_zeros.js │ │ └── README.md │ ├── stack and queue │ │ ├── 1.evaluate_reverse_polish_notation.js │ │ ├── 2.min_stack.js │ │ ├── 3.valid_parentheses.js │ │ ├── 4.daily_temperature.js │ │ ├── 5.push_dominoes.js │ │ └── README.md │ ├── strings │ │ ├── 1.longest_common_prefix.js │ │ ├── 10.first_uniq_char.js │ │ ├── 11.strStr.js │ │ ├── 12.check_if_two_string_are_anagram.js │ │ ├── 13.first_non_repeating_char.js │ │ ├── 14.subsequence_of_given_string.js │ │ ├── 15.numbers_to_words.js │ │ ├── 16.capitalize_first_and_last_char.js │ │ ├── 17.isograms.js │ │ ├── 18.rotate_string.js │ │ ├── 2.power_of_2.js │ │ ├── 3.excel_sheet_column_title.js │ │ ├── 4.group_of_anagrams.js │ │ ├── 5.number_to_words.js │ │ ├── 6.students_attendance.js │ │ ├── 7.string_reversal_without_changing_special.js │ │ ├── 8.length_of_last_word.js │ │ ├── 9.longest_substr.js │ │ └── README.md │ ├── template_problem.js │ ├── trees │ │ ├── 1.max_depth_of_tree.js │ │ ├── 10.symmetric_tree.js │ │ ├── 11.path_sum.js │ │ ├── 12.level_order_traversal.js │ │ ├── 2.min_depth_of_tree.js │ │ ├── 3.find_second_minimum_node.js │ │ ├── 4.is_balanced_tree.js │ │ ├── 5.check_tree_is_bst.js │ │ ├── 6.lowest_common_ancestor_bst.js │ │ ├── 7.lowest_common_ancestor_bt.js │ │ ├── 8.same_tree.js │ │ ├── 9.invert_binary_tree.js │ │ └── README.md │ ├── trie │ │ ├── 1.implement_trie_ds.js │ │ └── README.md │ └── two pointers │ │ ├── 1.intersection_of_sorted_arrays.js │ │ ├── 2.remove_duplicate_from_array-2.js │ │ ├── 3.intersection_of_unsorted_arrays.js │ │ ├── 4.shortest_distance_to_char.js │ │ └── README.md └── others │ └── 1.plant_in_garden.js ├── search ├── README.md └── binary_search.js ├── sorting ├── 1.insertion_sort.js ├── 2.selection_sort.js ├── 3.bubble_sort.js ├── 4.merge_sort.js └── README.md └── tree ├── README.md └── images ├── binary-tree.png └── tree.jpg /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = tab 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.json] 12 | indent_style = space 13 | indent_size = 2 14 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [gokulkrishh] 2 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": false, 3 | "printWidth": 140 4 | } 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Gokulakrishnan Kalaikovan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # data-structures-and-algorithms 2 | 3 | > Basics for learning data structures and algorithms. 4 | 5 | ![Big O Cheet Sheet](./bigocheatsheet.png) 6 | 7 | ## Table of Contents 8 | 9 | - [Algorithms Analysis](./algorithms-analysis/README.md) 10 | - [Linked List](./linkedlist/README.md) 11 | - [Sorting](./sorting/README.md) 12 | - [Search](./search/README.md) 13 | - [Tree](./tree/README.md) 14 | 15 | ### [Problems](./problems) 16 | 17 | - [leetcode](./problems/leetcode/README.md) 18 | - [cracking coding interview](./problems/cracking-coding-interview/README.md) 19 | 20 | ##### MIT Licensed 21 | 22 | by [@gokulkrishh](https://github.com/gokulkrishh) 23 | -------------------------------------------------------------------------------- /algorithms-analysis/README.md: -------------------------------------------------------------------------------- 1 | ## Table of Contents 2 | 3 | - [Analysis of an algorithm](#analysis-of-an-algorithm) 4 | - [Asymptotic analysis](#asymptotic-analysis) 5 | - [Best case](#1-best-case) 6 | - [Average case](#2-average-case) 7 | - [Worst case](#3-worst-case) 8 | - [Asymptotic notations](#asymptotic-notations) 9 | - [Theta notation](#1-theta-notation-θ---best-case) 10 | - [Omega notation](#2-omega-notation-ω---average-case) 11 | - [BigO notation](#3-bigo-notation-o---worst-case) 12 | - [Time complexity](#time-complexity) 13 | - [Time complexity table](#time=complexity-table) 14 | - [Space complexity](#space-complexity) 15 | 16 | ### Analysis of an algorithm 17 | 18 | To measure the efficiency of an algorithm that doesn’t depend on machine specific constants like single/multiple processor, architecture like 32bit or 64bit etc,. 19 | 20 | **How do you analyse it then ?** 21 | 22 | Using `asymptotic analysis`. 23 | 24 | ### Asymptotic Analysis 25 | 26 | The process of finding the computational complexity of an algorithm -- the amount of time, storage, or other resources needed to execute the solution. 27 | 28 | ##### There are 3 cases in algorithm analysis: 29 | 30 | 1. Best case 31 | 2. Average case 32 | 3. Worst case 33 | 34 | #### 1. Best case 35 | 36 | For best case analysis, we calculate the lower bound on the running time of an algorithm. 37 | 38 | To explain the above cases, let us see an example. 39 | 40 | ##### Example: 41 | 42 | ```js 43 | function linearSearch(list, target) { 44 | for (var i = 0; i < list.length; i++) { 45 | if (list[i] === target) { 46 | return i; // if found return index `i` 47 | } 48 | } 49 | 50 | return -1; // if not found return `-1` 51 | } 52 | 53 | linearSearch([1, 5, 6, 7, 8, 9, 10, 11], 10); 54 | ``` 55 | 56 | ###### For linear search problem, best case occurs when the target is found at the first location of the list. 57 | 58 | ##### Time Complexity: **`Θ(1)`** 59 | 60 | > Note: **`Θ`** is pronounced as Theta. More on this later. 61 | 62 | #### 2. Average case 63 | 64 | For average case analysis, we calculate by taking all inputs and computing the time for all inputs. 65 | 66 | ###### For linear search problem, worst case occurs when the target is not present in the given the list. 67 | 68 | ##### Time Complexity: **`Ω(N)`** 69 | 70 | > Note: **`Ω`** is pronounced as Omega. 71 | 72 | #### 3. Worst case 73 | 74 | For worst case analysis, we calculate the upper bound on the running time of an algorithm. Sum all the calculated values and divide the sum by total number of inputs. 75 | 76 | ###### For linear search problem, let us assume we are considering all the cases including the element not present. 77 | 78 | ##### Time Complexity: **`O(N)`** 79 | 80 | > Note: **`O`** is pronounced as BigO. 81 | 82 | ##### What is time complexity? How do you represent it? - Using **`Asymptotic notations`**. 83 | 84 | ### Asymptotic notations 85 | 86 | Asymptotic notations are mathematical tools to represent the **time complexity** of algorithms for asymptotic analysis. 87 | 88 | There are 3 types of asymptotic notations: 89 | 90 | 1. Theta notation (Θ) 91 | 2. Omega notation (Ω) 92 | 3. BigO notation (O) 93 | 94 | #### 1. Theta notation (Θ) - (**Best Case**) 95 | 96 | Theta notation bounds the function above and below and can be deduced by dropping the lower order terms and ignoring leading constants. This is least used notation among all three. Since best case of an algorithm is generally not useful. 97 | 98 | ##### Example: 99 | 100 | **`3(N^2) + 2(N^3) + 1`** = **`Θ(N^3)`** (Lower bound is N^2 and constants are the whole numbers in the equation) 101 | 102 | #### 2. Omega notation (Ω) - (**Average Case**) 103 | 104 | Omega notation defines the lower bound of an algorithm. Similar to the best case, average case is not very useful. We should be more interested in **worst case**. 105 | 106 | #### 3. BigO notation (O) - (**Worst Case**) 107 | 108 | BigO notation defines the upper bound of an algorithm. It bounds the function only from above unlike `Theta notation` which takes both above and below. 109 | 110 | ##### Example: 111 | 112 | **`5(N^2) + 2(N) + 1`** = **`O(N^2)`** 113 | 114 | Lets say, 115 | 116 | **`O(g(n))`** = { **`f(n): there exists constants c and n0, f(n) <= c times g(n), for all n >= n0`** } 117 | 118 | ##### Example: 119 | 120 | If **`f(n)`** = **`5(N^2) + 2(N) + 1`** is equivalent to **`O(N^2)`** 121 | 122 | then **`g(n)`** = **`(N^2)`** 123 | 124 | where 125 | 126 | **`c`** = **`8`** which is (5 + 2 + 1), **`f(n) <= 8(N^2), n >= 1`** 127 | 128 | **`n0`** = **`1`** 129 | 130 | ### Time complexity 131 | 132 | Time complexity is **rate of growth of time with respect to the inputs** taken during the execution time. 133 | 134 | ##### Example 1: 135 | 136 | ```js 137 | function sumOfTwoNumbers(a, b) { 138 | return a + b; 139 | } 140 | ``` 141 | 142 | When I run the above example 1 problem's the complexity is `O(1)`. Because no matter how big you inputs are it will take constant time to return the sum. 143 | 144 | ##### Example 2: 145 | 146 | ```js 147 | function sumOfList(list) { 148 | var total = 0; 149 | for (var i = 0; i < list.length; i++>) { 150 | total += list[i] ; 151 | } 152 | 153 | return total; 154 | } 155 | ``` 156 | 157 | When I run the above example 2, the problem is gone take `N` times to get the total where `N` is number of items. So the time complexity is `O(N)`. 158 | 159 | ### Time complexity table: 160 | 161 | | Big O | Run Time | 🤔 | 162 | | -------------- | ----------- | --- | 163 | | `O(1)` | Constant | 😃 | 164 | | `O(log n)` | Logarithmic | 😀 | 165 | | `O(n)` | Linear | 🥺 | 166 | | `O(n * log n)` | Log Linear | 😣 | 167 | | `O(n ^ 2)` | Quadratic | 😖 | 168 | | `O(n ^ 3)` | Cubic | 😫 | 169 | | `O(2 ^ n)` | Exponential | 😷 | 170 | | `O(n!)` | Factorial | 😭 | 171 | 172 | ### Space complexity 173 | 174 | Space complexity is measure of how efficient your code is in terms of memory usage when it runs. 175 | 176 | > We can measure it by finding the largest memory used by the solution. 177 | 178 | ##### Example 1: 179 | 180 | ```js 181 | function sumOfList(list) { 182 | var total = 0; 183 | for (var i = 0; i < list.length; i++>) { 184 | total += list[i] ; 185 | } 186 | 187 | return total; 188 | } 189 | ``` 190 | 191 | When I run the above example 1, space complexity is `O(N)` because your solution is going to store `N` times total in a variable. 192 | 193 | ##### References: 194 | 195 | - [Analysis of algorithms - Part 1](https://www.geeksforgeeks.org/analysis-of-algorithms-set-1-asymptotic-analysis/) 196 | - [Analysis of Algorithms - Part 2](https://www.geeksforgeeks.org/analysis-of-algorithms-set-2-asymptotic-analysis/) 197 | - [Analysis of Algorithms - Part 3](https://www.geeksforgeeks.org/analysis-of-algorithms-set-3asymptotic-notations/) 198 | - [Time Complexity](https://www.interviewbit.com/courses/programming/topics/time-complexity/) 199 | - [Space Complexity](https://www.interviewbit.com/tutorial/space-complexity/) 200 | -------------------------------------------------------------------------------- /bigocheatsheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokulkrishh/data-structures-and-algorithms/372961215d642c055e3ec831f19ba7e4265844e3/bigocheatsheet.png -------------------------------------------------------------------------------- /linkedlist/README.md: -------------------------------------------------------------------------------- 1 | # Linked List 2 | 3 | > Linked list are linear data structure (Like Array) but not stored at continuous fashion rather nodes are linked using pointers. 4 | 5 | ### Advantages 6 | 7 | - Not fixed size like array (Dynamic in size). 8 | - Insertion/Deletion is not expensive. 9 | 10 | ### Disadvantages 11 | 12 | - Access is slower than array (To access a node, have go through from first node). 13 | - Pointer uses extra memory. 14 | 15 | ### Types 16 | 17 | 1. Singly Linked List 18 | 1. Doubly Linked List 19 | 1. Circular Linked List 20 | -------------------------------------------------------------------------------- /linkedlist/circular-linked-list.md: -------------------------------------------------------------------------------- 1 | # Circular Linked List 2 | 3 | > Circular linked list stores data in nodes 4 | 5 | ![circular linked list](./images/circular-linked-list.png) 6 | 7 | ### Node contains 8 | 9 | 1. Data 10 | 1. Pointer reference to next node 11 | 1. last node will point to head 12 | 13 | ### Points to remember 14 | 15 | - First node is called head (head is always starts with null). 16 | - From head, each node has a value and a pointer reference to next node. 17 | - Last node will point to head again to make it circular. 18 | -------------------------------------------------------------------------------- /linkedlist/doubly-linked-list.md: -------------------------------------------------------------------------------- 1 | # Doubly Linked List 2 | 3 | > Doubly linked list stores data in nodes 4 | 5 | ![doubly linked list](./images/doubly-linked-list.png) 6 | 7 | ### Node contains 8 | 9 | 1. Pointer reference to previous node 10 | 1. Data 11 | 1. Pointer reference to next node 12 | 13 | ### Points to remember 14 | 15 | - First node is called head (head is always starts with null). 16 | - From head, each node has a value and a pointer reference to the prev and next node. 17 | - Last node will always be null. 18 | 19 | ### Time Complexity 20 | 21 | - Access `O(N)` 22 | - Search `O(N)` 23 | - Insertion `O(1)` 24 | - Deletion `O(1)` 25 | 26 | ### Space Complexity 27 | 28 | `O(N)` 29 | -------------------------------------------------------------------------------- /linkedlist/images/circular-linked-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokulkrishh/data-structures-and-algorithms/372961215d642c055e3ec831f19ba7e4265844e3/linkedlist/images/circular-linked-list.png -------------------------------------------------------------------------------- /linkedlist/images/doubly-linked-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokulkrishh/data-structures-and-algorithms/372961215d642c055e3ec831f19ba7e4265844e3/linkedlist/images/doubly-linked-list.png -------------------------------------------------------------------------------- /linkedlist/images/singly-linked-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokulkrishh/data-structures-and-algorithms/372961215d642c055e3ec831f19ba7e4265844e3/linkedlist/images/singly-linked-list.png -------------------------------------------------------------------------------- /linkedlist/singly-linked-list.md: -------------------------------------------------------------------------------- 1 | # Singly Linked List 2 | 3 | > Linked list stores data in nodes 4 | 5 | ![singly linked list](./images/singly-linked-list.png) 6 | 7 | ### Node contains 8 | 9 | 1. Data 10 | 2. Pointer reference to next node 11 | 12 | ### Points to remember 13 | 14 | - First node is called head (A linked list is empty, if its head is null). 15 | - From head, each node has a value and a pointer reference to the next node. 16 | - Last node will always be null. 17 | 18 | ### Time Complexity 19 | 20 | - Access `O(N)` 21 | - Search `O(N)` 22 | - Insertion `O(1)` 23 | - Deletion `O(1)` 24 | 25 | ### Space Complexity 26 | 27 | `O(N)` 28 | 29 | #### Implementation in js 30 | -------------------------------------------------------------------------------- /linkedlist/singly_linked_list.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | ## Implementation Of Singly Linked List 4 | 5 | _Using arrays_ 6 | 7 | ### Methods 8 | 9 | 1. Add a node 10 | 11 | 1. Remove a node 12 | 13 | 1. Search a node 14 | 15 | */ 16 | 17 | // 1. Add a node 18 | 19 | function singlyLinkedList() { 20 | this.length = 0; //Default value 21 | this.head = null; 22 | } 23 | 24 | //To store in a new node 25 | function storeNode(data) { 26 | this.data = data; 27 | this.next = null; 28 | } 29 | 30 | //To add a node 31 | singlyLinkedList.prototype.add = function(value) { 32 | var node = new storeNode(value); 33 | var currentNode = this.head; 34 | 35 | //If current node is null, then its a new list 36 | if (!currentNode) { 37 | this.head = node; //Set new node as current node 38 | 39 | this.length++; //Increment length of list 40 | 41 | return node; 42 | } 43 | 44 | //If next presents, then set current node to next node 45 | while (currentNode.next) { 46 | currentNode = currentNode.next; 47 | } 48 | 49 | currentNode.next = node; //Set next node as newly created node 50 | 51 | this.length++; 52 | 53 | return node; 54 | }; 55 | 56 | var list = new singlyLinkedList(); 57 | list.add(1); //Head 58 | list.add(2); //1st node has ref of this node, this node ref = null 59 | 60 | // 2. Remove a node 61 | 62 | singlyLinkedList.prototype.remove = function(position) { 63 | var currentNode = this.head; 64 | var deletedNode = null; 65 | var nextToDelete = null; 66 | var beforeToDelete = null; 67 | var count = 0; 68 | 69 | //If position not present 70 | if (position < 0 || position > list.length) { 71 | throw new Error("Invalid position"); 72 | } 73 | 74 | //If position is head's position 75 | if (position === 1) { 76 | this.head = currentNode.next; //Set next node to head 77 | deletedNode = currentNode; //To return deleted node 78 | this.length--; //Decrement the length 79 | 80 | return deletedNode; 81 | } 82 | 83 | //If any other position 84 | while (count < position) { 85 | beforeToDelete = currentNode; 86 | nextToDelete = currentNode.next; 87 | count++; 88 | } 89 | 90 | beforeToDelete.next = nextToDelete.next; //Before removing node 91 | deletedNode = nextToDelete; 92 | nextToDelete = null; 93 | this.length--; //Decrement length after deleting 94 | return deletedNode; 95 | }; 96 | 97 | // 3. Search a node 98 | singlyLinkedList.prototype.search = function(position) { 99 | var currentNode = this.head; 100 | var count = 1; 101 | 102 | //If list is empty or position invalid or position not present 103 | if (this.length < 0 || position > this.length || position < 0) { 104 | throw new Error("Invalid position"); 105 | } 106 | 107 | //If position present, return its node 108 | while (count < position) { 109 | currentNode = currentNode.next; //Set currentNode to next node 110 | count++; 111 | } 112 | 113 | return currentNode; 114 | }; 115 | 116 | 120 | Full Example 121 | ; 122 | -------------------------------------------------------------------------------- /problems/cracking-coding-interview/README.md: -------------------------------------------------------------------------------- 1 | # Cracking coding interview 2 | 3 | > At least one problem a day, keeps your lazy brain away (Mostly weekdays) :P 4 | 5 | | Total Problems | 6 | | :------------: | 7 | | 6 | 8 | 9 | ## Table of Contents 10 | 11 | - [Chapter 1 - Arrays & Strings](./chapter-1/README.md) 12 | - [Chapter 2 - Linked List](./chapter-2/README.md) 13 | -------------------------------------------------------------------------------- /problems/cracking-coding-interview/chapter-1/1.unique_chars.js: -------------------------------------------------------------------------------- 1 | /* Problem: Determine if a string has all Unique Characters 2 | 3 | Example: 4 | Input : abcd10jk 5 | Output : true 6 | 7 | Input : hutg9mnd!nk9 8 | Output : false 9 | 10 | Note: Check if the string is ASCII or unicode 11 | */ 12 | 13 | // Solution 1: Brute force 14 | function uniqueChars(str) { 15 | if (str.length === 0) { 16 | return false; 17 | } 18 | 19 | for (var i = 0; i < str.length; i++) { 20 | for (var j = i + 1; j < str.length; j++) { 21 | if (str[i] === str[j]) { 22 | return false; 23 | } 24 | } 25 | } 26 | 27 | return true; 28 | } 29 | 30 | uniqueChars("abcd10jk"); // true 31 | uniqueChars("hutg9mnd!nk9"); // false 32 | 33 | // Time Complexity: O(N^2) 34 | // Space Complexity: O(1) 35 | 36 | // Solution 2: Hashmap 37 | function uniqueChars(str) { 38 | if (str.length === 0) { 39 | return false; 40 | } 41 | 42 | var hash = {}; 43 | 44 | for (var i = 0; i < str.length; i++) { 45 | if (!hash[str[i]]) { 46 | hash[str[i]] = 1; 47 | } else { 48 | return false; 49 | } 50 | } 51 | 52 | return true; 53 | } 54 | 55 | uniqueChars("abcd10jk"); // true 56 | uniqueChars("hutg9mnd!nk9"); // false 57 | 58 | // Time Complexity: O(S), S is length of the string 59 | // Space Complexity: O(S) 60 | -------------------------------------------------------------------------------- /problems/cracking-coding-interview/chapter-1/2.permutation_of_two_strings.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given two string, find out if one string is permutation of other. 2 | 3 | Example: 4 | Input: "abcd" "dcab" 5 | Output: true 6 | 7 | Input: "abcde" "dcab" 8 | Output: false 9 | 10 | Input: "dcfg" "cdfg!" 11 | Output: false 12 | 13 | Note: 14 | - Is the given strings are case-sensitive? 15 | - Does white space with string is considered to be different (Eg: "god" different from " god ") 16 | */ 17 | 18 | // Solution 1: Sorting 19 | function isPermutation(str1, str2) { 20 | if (str1.length !== str2.length) { 21 | return false; 22 | } 23 | 24 | var str1 = str1 25 | .split("") 26 | .sort() 27 | .join(""); 28 | 29 | var str2 = str2 30 | .split("") 31 | .sort() 32 | .join(""); 33 | 34 | return str1 === str2; 35 | } 36 | 37 | isPermutation("abcd", "dcab"); // True 38 | isPermutation("abcde", "dcab"); // False 39 | isPermutation("dcfg", "cdfg"); // True 40 | 41 | // Time Complexity: O(N LOG N), due to storing complexity is increased 42 | // Space Complexity: O(S), S is length of strings 43 | 44 | // Solution 2: Hash map 45 | function isPermutation(str1, str2) { 46 | if (str1.length !== str2.length) { 47 | return false; 48 | } 49 | 50 | var hash = {}; 51 | 52 | for (var i = 0; i < str1.length; i++) { 53 | if (!hash[str1[i]]) { 54 | hash[str1[i]] = 1; 55 | } else { 56 | hash[str1[i]] += 1; 57 | } 58 | } 59 | 60 | for (var i = 0; i < str2.length; i++) { 61 | var char = str2[i]; 62 | 63 | if (hash[char]) { 64 | hash[char]--; 65 | } 66 | } 67 | 68 | for (var i in hash) { 69 | if (hash[i] > 0) { 70 | return false; 71 | } 72 | } 73 | 74 | return true; 75 | } 76 | 77 | isPermutation("abcd", "dcab"); // True 78 | isPermutation("abcde", "dcab"); // False 79 | isPermutation("dcfg", "cdfg"); // True 80 | 81 | // Time Complexity: O(N), N is length of str1 & str2 82 | // Space Complexity: O(N), N is length of str1 83 | -------------------------------------------------------------------------------- /problems/cracking-coding-interview/chapter-1/3.permutation_of_palindrome.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a string, write a function to find out if the string is permutation of palindrome. 2 | 3 | Note: 4 | - Palindrome is a word or phrase which is same in front and backwards 5 | Example: "madam" has characters appears same from front and the back 6 | - Permutation is re-arrangement of characters 7 | Example: "abc" and "bac" and "cab" are same 8 | 9 | Example: 10 | Input: "tact coa" 11 | Output: true 12 | 13 | Explanation: the permutation combinations are { "taco cat", "atco cta" etc } 14 | */ 15 | 16 | // Hint from question is palindrome occurs when we have all the characters as even except 1 char which is odd 17 | // i.e: even + odd = odd means we have permutation of palindrome 18 | // i.e: old + old = false 19 | // i.e: even + even = false 20 | 21 | // Solution 1 - using hash map 22 | function isPermutationOfPalindrome(str) { 23 | var hashMap = {}; 24 | 25 | for (var i = 0; i < str.length; i++) { 26 | var char = str[i]; 27 | if (char === " ") { 28 | continue; 29 | } 30 | 31 | if (!hashMap[char]) { 32 | hashMap[char] = 1; 33 | } else { 34 | hashMap[char] += 1; 35 | } 36 | } 37 | 38 | var oddCount = 0; 39 | 40 | for (var i in hashMap) { 41 | oddCount += hashMap[i] % 2; 42 | } 43 | 44 | return oddCount === 1; 45 | } 46 | 47 | isPermutationOfPalindrome("tact coa"); // true 48 | isPermutationOfPalindrome("nurses run"); // true 49 | isPermutationOfPalindrome("aab"); // true 50 | isPermutationOfPalindrome("abca"); // false 51 | 52 | // Time Complexity: O(N), as we have to iterate all the chars in the given string 53 | // Space Complexity: O(S), S is number of chars in string as we are storing all the chars in hash map 54 | 55 | // Solution 2: Using array of 128 ASC11 characters length and same even odd count 56 | 57 | function isPermutationOfPalindrome(str) { 58 | var arrMap = new Array(128).fill(0); 59 | 60 | for (var i = 0; i < str.length; i++) { 61 | if (str[i] === " ") { 62 | continue; 63 | } 64 | arrMap[str.charCodeAt(i)]++; 65 | } 66 | 67 | var oddCount = 0; 68 | 69 | for (var i = 0; i < arrMap.length; i++) { 70 | oddCount += arrMap[i] % 2; 71 | } 72 | 73 | return oddCount === 1; 74 | } 75 | 76 | isPermutationOfPalindrome("tact coa"); // true 77 | isPermutationOfPalindrome("nurses run"); // true 78 | isPermutationOfPalindrome("aab"); // true 79 | isPermutationOfPalindrome("abca"); // false 80 | 81 | // Time Complexity: O(N), as we have to iterate all the chars in the given string 82 | // Space Complexity: O(1) 83 | -------------------------------------------------------------------------------- /problems/cracking-coding-interview/chapter-1/4.rotate_mxn_matrix.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a NxM matrix by rotate it by 90 deg. 2 | 3 | Example: 4 | Input: [[1,2,3], [4,5,6], [7,8,9]] 5 | Output: [[7,4,1], [8,5,2], [9,6,3]] 6 | 7 | */ 8 | 9 | // Solution 1 - In place rotating by moving the items in edges and go towards inside 10 | 11 | function rotateMatrix(matrix) { 12 | for (var i = 0; i < matrix.length / 2; i++) { 13 | var last = matrix.length - 1 - i; 14 | for (var j = i; j < last; j++) { 15 | var offset = j - i; 16 | var top = matrix[i][j]; 17 | matrix[i][j] = matrix[last - offset][i]; 18 | matrix[last - offset][i] = matrix[last][last - offset]; 19 | matrix[last][last - offset] = matrix[j][last]; 20 | matrix[j][last] = top; 21 | } 22 | } 23 | 24 | return matrix; 25 | } 26 | 27 | rotateMatrix([ 28 | [1, 2, 3], 29 | [4, 5, 6], 30 | [7, 8, 9] 31 | ]); 32 | 33 | /* 34 | Output: [ 35 | [7, 4, 1], 36 | [8, 5, 2], 37 | [9, 6, 3] 38 | ] 39 | */ 40 | 41 | // Time Complexity: O(N*M) 42 | // Space Complexity: O(1) 43 | -------------------------------------------------------------------------------- /problems/cracking-coding-interview/chapter-1/README.md: -------------------------------------------------------------------------------- 1 | # chapter-1 2 | 3 | > Array & Strings 4 | 5 | 1. [Unique characters](./1.unique_chars.js) 6 | 1. [Permutation of two strings](./2.permutation_of_two_strings.js) 7 | 1. [Permutation of palindrome](./3.permutation_of_palindrome.js) 8 | 1. [Rotate mxn matrix by 90deg](./4.rotate_mxn_matrix.js) 9 | -------------------------------------------------------------------------------- /problems/cracking-coding-interview/chapter-2/1.remove_duplicates_linked_list.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a linked list which is unsorted, remove the duplicates 2 | 3 | Example: 4 | Input: 10->5->3-10->3-4-null 5 | Output: 10->5->3->4-null 6 | 7 | Follow up: 8 | - If suppose addition buffer is not allowed. 9 | 10 | */ 11 | 12 | // Solution 1 - Hashmap & Two pointers (current and previous node) 13 | 14 | function removeDuplicateList(head) { 15 | if (!head) { 16 | return null; 17 | } 18 | 19 | var hashMap = {}; 20 | var current = head; 21 | var previous = null; 22 | 23 | while (current !== null) { 24 | if (hashMap[current.data]) { 25 | previous.next = current.next; 26 | } else { 27 | hashMap[current.data] = 1; 28 | previous = current; 29 | } 30 | 31 | current = current.next; 32 | } 33 | 34 | return head; 35 | } 36 | 37 | var list = { 38 | data: 10, 39 | next: { 40 | data: 5, 41 | next: { 42 | data: 3, 43 | next: { 44 | data: 10, 45 | next: { 46 | data: 3, 47 | next: { 48 | data: 4, 49 | next: null 50 | } 51 | } 52 | } 53 | } 54 | } 55 | }; 56 | 57 | removeDuplicateList(head); 58 | 59 | // Time complexity: O(N) 60 | // Space complexity: O(N) 61 | 62 | // Solution 2 - No buffer allowed, so check the each node against every next node to null 63 | 64 | // Time complexity: O(N^2) 65 | // Space complexity: O(1) 66 | -------------------------------------------------------------------------------- /problems/cracking-coding-interview/chapter-2/2.sum_of_two_linked_list.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given two numbers represented by two lists, write a function that returns the sum list. 2 | The sum list is list representation of the addition of two input numbers. 3 | 4 | Example: 5 | 6 | Input: 7 | List1: 5->6->3 // represents number 365 8 | List2: 8->4->2 // represents number 248 9 | Output: 10 | list: 3->1->6 // represents number 613 11 | 12 | 13 | Input: 14 | List1: 7->5->9->4->6 // represents number 64957 15 | List2: 8->4 // represents number 48 16 | Output: 17 | list: 5->0->0->5->6 // represents number 65005 18 | */ 19 | // Solution 1 - Iteration of two lists and carry forward the reminder for addition 20 | 21 | function sumTwoList(l1, l2) { 22 | if (!l1 && !l2) { 23 | return null; 24 | } 25 | 26 | var result = null; 27 | var prev = null; 28 | var carry = 0; 29 | var sum = 0; 30 | 31 | while (l1 !== null || l2 !== null) { 32 | sum = carry + l1.data + l2.data; 33 | carry = sum >= 10 ? 1 : 0; 34 | sum %= 10; 35 | 36 | var temp = { data: sum, next: null }; 37 | 38 | if (!result) { 39 | result = temp; 40 | } else { 41 | prev.next = temp; 42 | } 43 | 44 | prev = temp; 45 | 46 | l1 = l1.next; 47 | l2 = l2.next; 48 | } 49 | 50 | if (carry > 0) { 51 | result.next = { data: carry, next: null }; 52 | } 53 | 54 | return result; 55 | } 56 | 57 | var l1 = { 58 | data: 7, 59 | next: { 60 | data: 1, 61 | next: { 62 | data: 6, 63 | next: null 64 | } 65 | } 66 | }; 67 | 68 | var l2 = { 69 | data: 5, 70 | next: { 71 | data: 9, 72 | next: { 73 | data: 2, 74 | next: null 75 | } 76 | } 77 | }; 78 | 79 | sumTwoList(l1, l2); 80 | 81 | // Time Complexity: O(L1 + L2), L1 is list one and L2 is list two 82 | // Space Complexity: O(L3), L3 is new list 83 | -------------------------------------------------------------------------------- /problems/cracking-coding-interview/chapter-2/README.md: -------------------------------------------------------------------------------- 1 | # chapter-2 2 | 3 | > Linked list 4 | 5 | 1. [Remove duplicated from unsorted linked list](./1.remove_duplicates_linked_list.js) 6 | 1. [Sum of two linked list](./2.sum_of_two_linked_list.js) 7 | -------------------------------------------------------------------------------- /problems/leetcode/README.md: -------------------------------------------------------------------------------- 1 | # Leetcode 2 | 3 | > At least one problem a day, keeps your lazy brain away (Mostly weekdays) :P 4 | 5 | | Total Problems | 6 | | :------------: | 7 | | 108 | 8 | 9 | ## Table of Contents 10 | 11 | - [Array](./array/README.md) 12 | - [Back Tracking](./back%20tracking/README.md) 13 | - [Bit Manipulation](./bit%20manipulation/README.md) 14 | - [Cache](./cache/README.md) 15 | - [Hashing](./hashing/README.md) 16 | - [In Place](./in%20place/README.md) 17 | - [Linked List](./linked%20list/README.md) 18 | - [Numbers](./numbers/README.md) 19 | - [One Pass](./one%20pass/README.md) 20 | - [Recursion](./recursion/README.md) 21 | - [Search](./search/README.md) 22 | - [Stack & Queue](./stack%20and%20queue/README.md) 23 | - [Strings](./strings/README.md) 24 | - [Trees](./trees/README.md) 25 | - [Trie](./trie/README.md) 26 | - [Two Pointers](./two%20pointers//README.md) 27 | -------------------------------------------------------------------------------- /problems/leetcode/array/1.rearrange_array.js: -------------------------------------------------------------------------------- 1 | /* Problem: Rearrange an array so that arr[i] becomes arr[arr[i]] with O(1) extra space 2 | 3 | Given an array arr[] of size n where every element is in range from 0 to n-1. 4 | Rearrange the given array so that arr[i] becomes arr[arr[i]]. This should be done with O(1) extra space. 5 | 6 | Example: 7 | 8 | Input: arr[] = {3, 2, 0, 1} 9 | Output: arr[] = {1, 0, 3, 2} 10 | 11 | Input: arr[] = {4, 0, 2, 1, 3} 12 | Output: arr[] = {3, 4, 2, 0, 1} 13 | 14 | Input: arr[] = {0, 1, 2, 3} 15 | Output: arr[] = {0, 1, 2, 3} 16 | 17 | */ 18 | 19 | // Solution #1 with extra O(N) space 20 | function rearrangeArray(arr) { 21 | var temp = []; 22 | 23 | arr.forEach((e, i) => { 24 | temp[i] = arr[e]; 25 | }); 26 | 27 | return temp; 28 | } 29 | 30 | rearrangeArray([3, 2, 0, 1]); // [1, 0, 3, 2] 31 | 32 | /* Complexity: 33 | Time Complexity: O(n) 34 | Space Complexity; O(n) 35 | */ 36 | 37 | // Solution #2 38 | function rearrangeArray(arr) { 39 | if (arr.length === 0) return arr; 40 | 41 | var n = arr.length; 42 | 43 | for (var i = 0; i < n; i++) { 44 | arr[i] += (arr[arr[i]] % n) * n; // % by n and * by n will give me a new value. 45 | } 46 | 47 | for (var i = 0; i < n; i++) { 48 | arr[i] = parseInt(arr[i] / n); // dividing by n will be the ans and % by n will the old value. 49 | } 50 | 51 | return arr; 52 | } 53 | 54 | rearrangeArray([3, 2, 0, 1]); // [1, 0, 3, 2] 55 | 56 | /* Complexity: 57 | Time Complexity: O(n) 58 | Auxiliary Space: O(1) 59 | Space Complexity; O(n) 60 | */ 61 | -------------------------------------------------------------------------------- /problems/leetcode/array/10.area_of_island.js: -------------------------------------------------------------------------------- 1 | /* Problem: 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. 2 | 3 | Note: Find the maximum area of an island in the given 2D array. (If there is no island, the maximum area is 0.) 4 | 5 | Example 1: 6 | Input: [[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]] 7 | Output: 6 8 | 9 | Explanation: Given the above grid, return 6. Note the answer is not 11, because the island must be connected 4-directionally. 10 | 11 | Example 2: 12 | Input: [[0,0,0,0,0,0,0,0]] 13 | Output: 0; 14 | 15 | Explanation: Given the above grid, return 0. 16 | */ 17 | 18 | // Using Depth First Search (Recursion) 19 | var maxAreaOfIsland = function (grid) { 20 | var result = 0; 21 | 22 | function dfs(i, j) { 23 | if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == 0 || grid[i][j] == -1) return 0; 24 | grid[i][j] = -1; // To keep track of the squares we visited 25 | // i - 1 to go up 26 | // i + 1 to go down 27 | // j - 1 to go backward 28 | // j + 1 to go forward 29 | return (1 + dfs(i - 1, j) + dfs(i + 1, j) + dfs(i, j - 1) + dfs(i, j + 1)); 30 | } 31 | 32 | for (var i = 0; i < grid.length; i++) { 33 | for (var j = 0; j < grid[i].length; j++) { 34 | if (grid[i] && grid[i][j] === 1) { 35 | result = Math.max(result, dfs(i, j)); 36 | } 37 | } 38 | } 39 | 40 | return result; 41 | }; 42 | 43 | // Time Complexity: O(N * M), N is number of rows and M is number of columns 44 | // Space Complexity: O(N * M) 45 | -------------------------------------------------------------------------------- /problems/leetcode/array/11.missing_number.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missing from the array. 2 | 3 | Note: Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity? 4 | 5 | Example 1: 6 | Input: [3,0,1] 7 | Output: 2 8 | 9 | Example 2: 10 | Input: [9,6,4,2,3,5,7,0,1] 11 | Output: 8 12 | 13 | */ 14 | 15 | // Solution 1 - Sorting & Finding the number 16 | var missingNumber = function (arr) { 17 | if (arr.length === 1 && arr[0] === 0) return 1; 18 | 19 | arr = arr.sort(function (a, b) { 20 | return a - b; 21 | }); 22 | 23 | if (arr.length === 1 && arr[0] === 1) return 0; 24 | 25 | for (var i = arr[0]; i <= arr[arr.length - 1]; i++) { 26 | if (i !== arr[i]) return i; 27 | else continue; 28 | } 29 | 30 | return i; 31 | }; 32 | 33 | missingNumber([3, 0, 1]); // 2 34 | 35 | // Time Complexity: O(N LOG N) 36 | // Space Complexity: O(N) 37 | 38 | // Solution 2 - Hashmaps 39 | 40 | var missingNumber = function (arr) { 41 | if (arr.length === 1 && arr[0] === 0) return 1; 42 | 43 | var obj = {}; 44 | 45 | for (var i = 0; i < arr.length; i++) { 46 | obj[arr[i]] = 1; 47 | } 48 | 49 | for (var i = 0; i < arr.length + 1; i++) { 50 | if (!obj[i]) { 51 | return i; 52 | } 53 | } 54 | 55 | return -1; 56 | }; 57 | 58 | missingNumber([3, 0, 1]); // 2 59 | missingNumber([9, 6, 4, 2, 3, 5, 7, 0, 1]); // 8 60 | 61 | // Time Complexity: O(N) 62 | // Space Complexity: O(N) 63 | 64 | // Solution - 3 - Using XOR Operation, as number ^ number equal 0 65 | var missingNumber = function (arr) { 66 | var missing = arr.length; 67 | 68 | for (var i = 0; i < arr.length; i++) { 69 | missing = i ^ arr[i] ^ missing; 70 | } 71 | 72 | return missing; 73 | }; 74 | 75 | missingNumber([3, 0, 1]); // 2 76 | missingNumber([9, 6, 4, 2, 3, 5, 7, 0, 1]); // 8 77 | 78 | // Time Complexity: O(N) 79 | // Space Complexity: O(1) 80 | -------------------------------------------------------------------------------- /problems/leetcode/array/12.distribute_candies.js: -------------------------------------------------------------------------------- 1 | /* Problem: 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. 2 | 3 | Example 1: 4 | Input: candies = [1,1,2,2,3,3] 5 | Output: 3 6 | Explanation: There are three different kinds of candies (1, 2 and 3), and two candies for each kind. 7 | Optimal distribution: The sister has candies [1,2,3] and the brother has candies [1,2,3], too. 8 | The sister has three different kinds of candies. 9 | 10 | Example 2: 11 | Input: candies = [1,1,2,3] 12 | Output: 2 13 | Explanation: For example, the sister has candies [2,3] and the brother has candies [1,1]. 14 | The sister has two different kinds of candies, the brother has only one kind of candies. 15 | 16 | */ 17 | 18 | // Using sorting and we know that arr will always be even so change of sister getting unique is 50% of candies 19 | var distributeCandies = function (candies) { 20 | var sister = 1; // lets start by giving one candty to sister 21 | 22 | candies.sort(function (a, b) { return a - b }); // Soring 23 | 24 | for (var i = 1; i < candies.length && sister < candies.length / 2; i++) { 25 | if (candies[i] > candies[i - 1]) { 26 | sister++; 27 | } 28 | } 29 | 30 | return sister; 31 | }; 32 | 33 | distributeCandies([1, 1, 2, 2, 3, 3]); // 3 34 | distributeCandies([1, 1, 2, 3]); // 2 35 | 36 | // Time Complexity: O(N LOG N) 37 | // Space complexity : O(1) 38 | 39 | // Using hash maps 40 | var distributeCandies = function (candies) { 41 | var obj = {}; 42 | var sister = 0; 43 | 44 | // As per the problem, arr will always be even so change of sister getting unique is 50% of candies 45 | for (var i = 0; i < candies.length && sister < candies.length / 2; i++) { 46 | // If unique, give it to sister 47 | if (!obj[candies[i]]) { 48 | sister++; 49 | obj[candies[i]] = 1; 50 | } 51 | } 52 | 53 | return sister; 54 | }; 55 | 56 | distributeCandies([1, 1, 2, 2, 3, 3]); // 3 57 | distributeCandies([1, 1, 2, 3]); // 2 58 | 59 | // Time Complexity: O(N) 60 | // Space complexity : O(N) 61 | -------------------------------------------------------------------------------- /problems/leetcode/array/13.max_consecutives_ones.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a binary array, find the maximum number of consecutive 1s in this array. 2 | 3 | Note: 4 | - The input array will only contain 0 and 1. 5 | - The length of input array is a positive integer and will not exceed 10,000 6 | 7 | Example 1: 8 | Input: [1,1,0,1,1,1] 9 | Output: 3 10 | Explanation: The first two digits or the last three digits are consecutive 1s. The maximum number of consecutive 1s is 3. 11 | */ 12 | 13 | var findMaxConsecutiveOnes = function (nums) { 14 | var count = 0; 15 | var max = 0; 16 | 17 | for (var i = 0; i < nums.length; i++) { 18 | if (nums[i] ^ 1 === 0) { 19 | count++; 20 | max = Math.max(max, count); // update max 21 | } 22 | else { 23 | count = 0; 24 | } 25 | } 26 | 27 | return max; 28 | }; 29 | 30 | findMaxConsecutiveOnes([1, 1, 0, 1, 1, 1]); // 3 31 | 32 | // Time Complexity: O(N) 33 | // Space Complexity: O(1) 34 | -------------------------------------------------------------------------------- /problems/leetcode/array/14.where_do_i_belong.js: -------------------------------------------------------------------------------- 1 | /* Problem: Return the lowest index at which a value (second argument) i.e **num** should be inserted into an array (first argument) 2 | i.e **arr** once it has been sorted. The returned value should be a number. 3 | 4 | E.g: whereIBelong([1,2,3,4], 1.5) // should return 1 because it is greater than 1(index 0), but less than 2(index 1). 5 | 6 | */ 7 | 8 | var whereIBelong = function(arr, num) { 9 | arr = arr.sort(function(a, b) { 10 | return a - b; 11 | }); 12 | 13 | for (var i = 0; i < arr.length; i++) { 14 | if (arr[i] > num) return i - 1; 15 | } 16 | 17 | return -1; 18 | }; 19 | 20 | whereIBelong([1, 2, 3, 4], 1.5); // 1 21 | 22 | // Time Complexity: O(N) 23 | -------------------------------------------------------------------------------- /problems/leetcode/array/15.water_container.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given n non-negative integers a1, a2, ..., an , where each represents a point at coordinate (i, ai). 2 | n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). 3 | Find two lines, which together with x-axis forms a container, such that the container contains the most water. 4 | 5 | Note: You may not slant the container and n is at least 2. 6 | 7 | Example: 8 | Input: [1,8,6,2,5,4,8,3,7] 9 | Output: 49 10 | 11 | */ 12 | 13 | var waterContainer = function(arr) { 14 | var water = 0; 15 | var start = 0; 16 | var end = arr.length - 1; 17 | 18 | while (start < end) { 19 | var currentContainer = Math.min(arr[start], arr[end]) * (end - start); 20 | water = Math.max(water, currentContainer); 21 | 22 | if (arr[start] <= arr[end]) start++; 23 | else end--; 24 | } 25 | 26 | return water; 27 | }; 28 | 29 | waterContainer([1, 8, 6, 2, 5, 4, 8, 3, 7]); // 49 30 | 31 | // Time Complexity: O(N) 32 | // Space Complexity: O(1) 33 | -------------------------------------------------------------------------------- /problems/leetcode/array/16.reverse_words.js: -------------------------------------------------------------------------------- 1 | /* Problem: Reverse Words in a String 2 | 3 | Given an input string, reverse the string word by word. 4 | 5 | Example 1: 6 | Input: "the sky is blue" 7 | Output: "blue is sky the" 8 | 9 | Example 2: 10 | Input: " hello world! " 11 | Output: "world! hello" 12 | Explanation: Your reversed string should not contain leading or trailing spaces. 13 | 14 | Example 3: 15 | Input: "a good example" 16 | Output: "example good a" 17 | Explanation: You need to reduce multiple spaces between two words to a single space in the reversed string. 18 | 19 | Note: 20 | - A word is defined as a sequence of non-space characters. 21 | - Input string may contain leading or trailing spaces. However, your reversed string should not contain leading or trailing spaces. 22 | - You need to reduce multiple spaces between two words to a single space in the reversed string. 23 | 24 | 25 | */ 26 | 27 | // Solution 1 using filter to remove "" string 28 | var reverseWords = function(s) { 29 | if (!s) return ""; 30 | var strArr = s.split(" "); 31 | strArr = strArr.filter(Boolean); 32 | var str = ""; 33 | for (var i = strArr.length - 1; i >= 0; i--) { 34 | if (!str) { 35 | str += strArr[i]; 36 | } else { 37 | str = str + " " + strArr[i]; 38 | } 39 | } 40 | 41 | return str; 42 | }; 43 | 44 | reverseWords("the sky is blue"); // "blue is sky the" 45 | reverseWords(" hello world! "); // "world! hello" 46 | 47 | // Time Complexity: O(N) 48 | // Space Complexity; O(N) 49 | 50 | // Solution 2 using replace, trim 51 | var reverseWords = function(s) { 52 | if (!s) return ""; 53 | var sArr = s 54 | .replace(/\s+/g, " ") 55 | .trim() 56 | .split(" "); 57 | return sArr.reverse().join(" "); 58 | }; 59 | 60 | reverseWords("the sky is blue"); // "blue is sky the" 61 | reverseWords(" hello world! "); // "world! hello" 62 | 63 | // Time Complexity: O(N) 64 | // Space Complexity; O(N) 65 | 66 | // Solution 3 using char reversal 67 | 68 | var reverseWords = function(s) { 69 | if (!s.length) return ""; 70 | 71 | function swap(s, start, end) { 72 | while (start < end) { 73 | var temp = str[start]; 74 | str[start] = str[end]; 75 | str[end] = temp; 76 | 77 | start++; 78 | end--; 79 | } 80 | } 81 | 82 | var start = 0; 83 | 84 | for (var end = 0; end < s.length; end++) { 85 | if (s[end] === " ") { 86 | swap(s, start, end); 87 | start = end + 1; 88 | } 89 | } 90 | 91 | // In above for - loop we would reversed all chars last word since (last word doesnt have space) 92 | // So we will do now 93 | swap(s, start, s.length - 1); // To swap last word chars 94 | 95 | swap(s, 0, s.length - 1); // To swap all reversed chars words 96 | 97 | return s.join(""); 98 | }; 99 | 100 | reverseWords(s.split("")); 101 | 102 | // Time Complexity: O(N) 103 | // Space Complexity; O(1) 104 | -------------------------------------------------------------------------------- /problems/leetcode/array/17.flower_bed.js: -------------------------------------------------------------------------------- 1 | /* Problem: Can Place Flowers 2 | 3 | Suppose you have a long flowerbed in which some of the plots are planted and some are not. 4 | However, flowers cannot be planted in adjacent plots - they would compete for water and both would die. 5 | 6 | Given a flowerbed (represented as an array containing 0 and 1, where 0 means empty and 1 means not empty), and a number n, 7 | return if n new flowers can be planted in it without violating the no-adjacent-flowers rule. 8 | 9 | Example 1: 10 | Input: flowerbed = [1,0,0,0,1], n = 1 11 | Output: True 12 | 13 | Example 2: 14 | Input: flowerbed = [1,0,0,0,1], n = 2 15 | Output: False 16 | 17 | Note: 18 | - The input array won't violate no-adjacent-flowers rule. 19 | - The input array size is in the range of [1, 20000]. 20 | - n is a non-negative integer which won't exceed the input array size. 21 | 22 | */ 23 | 24 | // Solution - Check prev & next step from current step + take care of start and end 25 | 26 | var flowerBed = function(flowerbed, n) { 27 | var count = 0; 28 | for (var i = 0; i < flowerbed.length; i++) { 29 | if (flowerbed[i] === 0 && (i == 0 || flowerbed[i - 1] === 0) && (i === flowerbed.length - 1 || flowerbed[i + 1] === 0)) { 30 | flowerbed[i] = 1; 31 | count++; 32 | } 33 | if (count >= n) return true; 34 | } 35 | 36 | return false; 37 | }; 38 | 39 | flowerBed([1, 0, 0, 0, 1], 1); // True 40 | flowerBed([1, 0, 0, 0, 1], 2); // False 41 | 42 | // Time Complexity: O(N) 43 | // Space Complexity: O(1) 44 | -------------------------------------------------------------------------------- /problems/leetcode/array/18.rotate_array.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given an array, rotate the array to the right by k steps, where k is non-negative. 2 | 3 | Example 1: 4 | Input: [1,2,3,4,5,6,7] and k = 3 5 | Output: [5,6,7,1,2,3,4] 6 | 7 | Explanation: 8 | rotate 1 steps to the right: [7,1,2,3,4,5,6] 9 | rotate 2 steps to the right: [6,7,1,2,3,4,5] 10 | rotate 3 steps to the right: [5,6,7,1,2,3,4] 11 | 12 | Example 2: 13 | 14 | Input: [-1,-100,3,99] and k = 2 15 | Output: [3,99,-1,-100] 16 | 17 | Explanation: 18 | rotate 1 steps to the right: [99,-1,-100,3] 19 | rotate 2 steps to the right: [3,99,-1,-100] 20 | 21 | Note: 22 | - Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem. 23 | - Could you do it in-place with O(1) extra space? 24 | 25 | */ 26 | 27 | var rotate = function(nums, k) { 28 | var temp = []; 29 | 30 | for (var i = 0; i < nums.length; i++) { 31 | temp[(i + k) % nums.length] = nums[i]; 32 | } 33 | 34 | for (var i = 0; i < nums.length; i++) { 35 | nums[i] = temp[i]; 36 | } 37 | 38 | return nums; 39 | }; 40 | 41 | rotate([1, 2, 3, 4, 5, 6, 7], 3); // [5,6,7,1,2,3,4] 42 | 43 | // Time Complexity: O(N) 44 | // Space Complexity: O(N), temp is of same size as nums.length 45 | 46 | // Solution 2 - Reversing numbers 47 | var rotate = function(nums, k) { 48 | function reverse(nums, i, j) { 49 | while (i < j) { 50 | var temp = nums[i]; 51 | nums[i] = nums[j]; 52 | nums[j] = temp; 53 | i++; 54 | j--; 55 | } 56 | } 57 | 58 | k %= nums.length; 59 | 60 | reverse(nums, 0, nums.length - 1); // Revering all the numbers first 61 | reverse(nums, 0, k - 1); // Revering first k numbers 62 | reverse(nums, k, nums.length - 1); // Revering the rest of the numbers (n - k) 63 | 64 | return nums; 65 | }; 66 | 67 | rotate([1, 2, 3, 4, 5, 6, 7], 3); // [5,6,7,1,2,3,4] 68 | 69 | // Time Complexity: O(N) 70 | // Space Complexity: O(1) 71 | 72 | // Solution 3 - ES6 way 73 | var rotate = function(nums, k) { 74 | nums.unshift(...nums.splice(nums.length - k, nums.length)); 75 | }; 76 | 77 | rotate([1, 2, 3, 4, 5, 6, 7], 3); // [5,6,7,1,2,3,4] 78 | 79 | // Time Complexity: O(N) 80 | // Space Complexity: O(1) 81 | -------------------------------------------------------------------------------- /problems/leetcode/array/19.intersection_of_numbers.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given two arrays, write a function to compute their intersection. 2 | 3 | Example 1: 4 | Input: nums1 = [1,2,2,1], nums2 = [2,2] 5 | Output: [2] 6 | Example 2: 7 | Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4] 8 | Output: [9,4] 9 | 10 | Note: 11 | 12 | Each element in the result must be unique. 13 | The result can be in any order. 14 | */ 15 | 16 | function intersection(nums1, nums2) { 17 | var hash = {}; 18 | 19 | for (var num of nums1) { 20 | if (!hash[num]) { 21 | hash[num] = true; 22 | } 23 | } 24 | 25 | var result = []; 26 | 27 | for (var num of nums2) { 28 | if (hash[num]) { 29 | delete hash[num]; 30 | arr.push(num); 31 | } 32 | } 33 | 34 | return result; 35 | } 36 | 37 | intersection([1, 2, 2, 1], [2, 2]); 38 | 39 | // Time Complexity: O(N * M) 40 | // Space Complexity: O(N + M) 41 | -------------------------------------------------------------------------------- /problems/leetcode/array/2.largest_number.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a list of non negative integers, arrange them such that they form the largest number. 2 | 3 | Note: The result may be very large, so you need to return a string instead of an integer. 4 | 5 | Example: 6 | 7 | Input: arr[] = [3, 30, 34, 5, 9] 8 | Output: string = "9534330" 9 | 10 | Input: arr[] = [1, 2, 4] 11 | Output: string = "421" 12 | 13 | */ 14 | 15 | function largestNumber(arr) { 16 | if (arr.length === 0) return arr[0]; 17 | arr = arr.map(x => x.toString()); 18 | 19 | arr.sort(function (a, b) { 20 | var left = a + b; 21 | var right = b + a; 22 | if (left < right) return 1; 23 | else if (left > right) return -1; 24 | return 0; 25 | }); 26 | 27 | return arr.join(""); 28 | } 29 | 30 | largestNumber([3, 30, 34, 5, 9]); // "9534330" 31 | 32 | /* Complexity: 33 | 34 | Time Complexity: O(n) 35 | 36 | */ 37 | -------------------------------------------------------------------------------- /problems/leetcode/array/20.sort_by_parity.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given an array A of non-negative integers, return an array consisting of all the even elements of A, followed by all the odd elements of A. 2 | 3 | Note: You may return any answer array that satisfies this condition. 4 | 5 | 6 | Example 1: 7 | Input: [3,1,2,4] 8 | Output: [2,4,3,1] 9 | The outputs [4,2,3,1], [2,4,1,3], and [4,2,1,3] would also be accepted 10 | 11 | */ 12 | 13 | // Solution 1 - Having two temp array (oddResult, evenResult) and concat it in end 14 | 15 | var sortArrayByParity = function(arr) { 16 | var evenResult = []; 17 | var oddResult = []; 18 | 19 | for (var i = 0; i < arr.length; i++) { 20 | if (arr[i] % 2 === 0) { 21 | evenResult.push(arr[i]); 22 | } else { 23 | oddResult.push(arr[i]); 24 | } 25 | } 26 | 27 | return evenResult.concat(oddResult); 28 | }; 29 | 30 | sortArrayByParity([3, 1, 2, 4]); // [2, 4, 3, 1] 31 | 32 | // Time Complexity: O(N) 33 | // Space Complexity: O(N) 34 | 35 | // Solution 2 - using one temp array 36 | 37 | var sortArrayByParity = function(arr) { 38 | var result = []; 39 | 40 | for (var i = 0; i < arr.length; i++) { 41 | if (arr[i] % 2 === 0) { 42 | result.unshift(arr[i]); 43 | } else { 44 | result.push(arr[i]); 45 | } 46 | } 47 | 48 | return result; 49 | }; 50 | 51 | sortArrayByParity([3, 1, 2, 4]); // [4, 2, 3, 1] 52 | 53 | // Time Complexity: O(N) 54 | // Space Complexity: O(N) 55 | 56 | // Solution 3 - In Place 57 | 58 | var sortArrayByParity = function(arr) { 59 | var tempIndex = 0; 60 | for (var i = 0; i < arr.length; i++) { 61 | if (arr[i] % 2 === 0) { 62 | var temp = arr[i]; 63 | arr[i] = arr[tempIndex]; 64 | arr[tempIndex] = temp; 65 | tempIndex++; 66 | } 67 | } 68 | 69 | return arr; 70 | }; 71 | 72 | sortArrayByParity([3, 1, 2, 4]); // [4, 2, 3, 1] 73 | 74 | // Time Complexity: O(N) 75 | // Space Complexity: O(1) 76 | -------------------------------------------------------------------------------- /problems/leetcode/array/21.find_duplicate_number.js: -------------------------------------------------------------------------------- 1 | /* Problem: Find the Duplicate Number 2 | 3 | Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. 4 | Assume that there is only one duplicate number, find the duplicate one. 5 | 6 | Example 1: 7 | Input: [1,3,4,2,2] 8 | Output: 2 9 | 10 | Example 2: 11 | Input: [3,1,3,4,2] 12 | Output: 3 13 | 14 | Note: 15 | 1. You must not modify the array (assume the array is read only). 16 | 2. You must use only constant, O(1) extra space. 17 | 3. Your runtime complexity should be less than O(n2). 18 | 4. There is only one duplicate number in the array, but it could be repeated more than once. 19 | */ 20 | 21 | // Solution 1 - HashMap 22 | 23 | var findDuplicate = function (nums) { 24 | var hash = {}; 25 | 26 | for (var i = 0; i < nums.length; i++) { 27 | if (!hash[nums[i]]) { 28 | hash[nums[i]] = 1; 29 | } else { 30 | return nums[i]; 31 | } 32 | } 33 | }; 34 | 35 | findDuplicate([3, 1, 3, 4, 2]); // 3 36 | findDuplicate([1, 3, 4, 2, 2]); // 2 37 | 38 | // Time Complexity: O(N) 39 | // Space Complexity: O(N) 40 | 41 | // Solution 2 - Pointers (fast and slow) 42 | // When fast is running faster than slow, then they must meet at some point. That point is the intersection of cycle 43 | // Again start from slow form begining, fast and slow will meet at some point where there cycle is detected and we can find the duplicate 44 | 45 | var findDuplicate = function (nums) { 46 | var slowPointer = nums[0]; 47 | var fastPointer = nums[0]; 48 | 49 | do { 50 | slowPointer = nums[slowPointer]; 51 | fastPointer = nums[nums[fastPointer]]; 52 | } while (slowPointer !== fastPointer); 53 | 54 | // Intersection 55 | slowPointer = nums[0]; 56 | 57 | while (slowPointer !== fastPointer) { 58 | slowPointer = nums[slowPointer]; 59 | fastPointer = nums[fastPointer]; 60 | } 61 | 62 | return fastPointer; 63 | }; 64 | 65 | findDuplicate([3, 1, 3, 4, 2]); // 3 66 | findDuplicate([1, 3, 4, 2, 2]); // 2 67 | 68 | // Time Complexity: O(N) 69 | // Space Complexity: O(1) 70 | -------------------------------------------------------------------------------- /problems/leetcode/array/22.subsets.js: -------------------------------------------------------------------------------- 1 | /* Problem: 2 | 3 | Given a set of distinct integers, nums, return all possible subsets (the power set). 4 | 5 | Note: The solution set must not contain duplicate subsets. 6 | 7 | Example: 8 | 9 | Input: nums = [1,2,3] 10 | Output: 11 | [ 12 | [3], 13 | [1], 14 | [2], 15 | [1,2,3], 16 | [1,3], 17 | [2,3], 18 | [1,2], 19 | [] 20 | ] 21 | 22 | */ 23 | 24 | var subsets = function(nums) { 25 | var lists = []; 26 | 27 | for (var i = 0; i < nums.length; i++) { 28 | var num = nums[i]; 29 | 30 | var max = lists.length; 31 | 32 | lists.push([num]); 33 | 34 | for (var j = 0; j < max; j++) { 35 | var list = lists[j].slice(); 36 | list.push(num); 37 | lists.push(list); 38 | } 39 | } 40 | 41 | lists.push([]); 42 | 43 | return lists; 44 | }; 45 | 46 | subsets([1, 2, 3]); // [[3], [1], [2], [1, 2, 3], [1, 3], [2, 3], [1, 2], []]; 47 | 48 | // Time Complexity: O(N * 2^N), 2^N (2 power N) is total number of subsets for given array. 49 | -------------------------------------------------------------------------------- /problems/leetcode/array/23.longest_vowel_chain.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a lowercase string that has alphabetic characters only and no spaces, return the length of the longest vowel substring. 2 | 3 | Example 4 | Input: "codewarriors" 5 | Output: 2 6 | 7 | Explantion: "io" is continued substring as longest in the given string. 8 | */ 9 | 10 | // Solution 1: 11 | function longestVowelChain(str) { 12 | if (!str.length) return 0; 13 | var arr = []; 14 | var continued = false; 15 | var vowels = { a: 'a', e: 'e', i: 'i', o: 'o', u: 'u' }; 16 | for (var i = 0; i < str.length; i++) { 17 | if (vowels[str[i]]) { 18 | if (continued) { 19 | arr.push(arr.pop().concat(str[i])); 20 | } else { 21 | arr.push([str[i]]); 22 | } 23 | continued = true; 24 | } else { 25 | continued = false; 26 | } 27 | } 28 | 29 | return arr.reduce((a, b) => (a.length > b.length ? a : b), []).length; // To get the longest array in arr variable 30 | } 31 | 32 | longestVowelChain('codewarriors'); // 2 33 | longestVowelChain('ultrarevolutionariees'); // 3 34 | longestVowelChain('iiihoovaeaaaoougjyaw'); // 8 35 | 36 | // Time Complexity: O(N) 37 | // Space Complexity: O(N) 38 | 39 | // Solution 2: Pointers 40 | 41 | function longestVowelChain(str) { 42 | var current = 0; 43 | var max = 0; 44 | var vowels = { a: 'a', e: 'e', i: 'i', o: 'o', u: 'u' }; 45 | for (var i = 0; i < str.length; i++) { 46 | if (vowels[str[i]]) { 47 | current++; 48 | if (current > max) { 49 | max = current; 50 | } 51 | } else { 52 | current = 0; 53 | } 54 | } 55 | return max; 56 | } 57 | 58 | longestVowelChain('axexixxoxuaiuo'); // 5 59 | 60 | // Time Complexity: O(N) 61 | // Space Complexity: O(1) 62 | -------------------------------------------------------------------------------- /problems/leetcode/array/24.keyboard_row.js: -------------------------------------------------------------------------------- 1 | /* Problem: 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. 2 | 3 | Example: 4 | 5 | Input: ["Hello", "Alaska", "Dad", "Peace"] 6 | Output: ["Alaska", "Dad"] 7 | 8 | Note: 9 | - You may use one character in the keyboard more than once. 10 | - You may assume the input string will only contain letters of alphabet. 11 | 12 | */ 13 | 14 | // Solution 1: Dumb 15 | 16 | var findWords = function(words) { 17 | var hash = { 18 | 1: { 19 | q: "q", 20 | w: "w", 21 | e: "e", 22 | r: "r", 23 | t: "t", 24 | y: "y", 25 | u: "u", 26 | i: "i", 27 | o: "o", 28 | p: "p" 29 | }, 30 | 2: { 31 | a: "a", 32 | s: "s", 33 | d: "d", 34 | f: "f", 35 | g: "g", 36 | h: "h", 37 | j: "j", 38 | k: "k", 39 | l: "l" 40 | }, 41 | 3: { z: "z", x: "x", c: "c", v: "v", b: "b", n: "n", m: "m" } 42 | }; 43 | 44 | var result = []; 45 | 46 | // q to p 47 | for (var i = 0; i < words.length; i++) { 48 | var letter = words[i]; 49 | var has = 0; 50 | for (var j = 0; j < letter.length; j++) { 51 | var char = letter[j].toLowerCase(); 52 | if (hash[1][char] && !hash[2][char] && !hash[3][char]) { 53 | has++; 54 | } else { 55 | has--; 56 | } 57 | } 58 | 59 | if (has === letter.length) { 60 | result.push(letter); 61 | } 62 | } 63 | 64 | // a to l 65 | for (var i = 0; i < words.length; i++) { 66 | var letter = words[i]; 67 | var has = 0; 68 | for (var j = 0; j < letter.length; j++) { 69 | var char = letter[j].toLowerCase(); 70 | 71 | if (hash[2][char] && !hash[1][char] && !hash[3][char]) { 72 | has++; 73 | } else { 74 | has--; 75 | } 76 | } 77 | 78 | if (has === letter.length) { 79 | result.push(letter); 80 | } 81 | } 82 | 83 | // z to m 84 | for (var i = 0; i < words.length; i++) { 85 | var letter = words[i]; 86 | var has = 0; 87 | for (var j = 0; j < letter.length; j++) { 88 | var char = letter[j].toLowerCase(); 89 | if (hash[3][char] && !hash[2][char] && !hash[1][char]) { 90 | has++; 91 | } else { 92 | has--; 93 | } 94 | } 95 | 96 | if (has === letter.length) { 97 | result.push(letter); 98 | } 99 | } 100 | 101 | return result; 102 | }; 103 | 104 | // Time Complexity: O(M * N) 105 | // Space Complexity: O(1) 106 | 107 | // SOlution 2 - Regex 108 | 109 | function findWords(words) { 110 | var row1 = /^[qwertyuiop]+$/i; 111 | var row2 = /^[asdfghjkl]+$/i; 112 | var row3 = /^[zxcvbnm]+$/i; 113 | 114 | var keyboardRows = [row1, row2, row3]; 115 | 116 | return words.filter(word => 117 | keyboardRows.some(keyboardRow => keyboardRow.test(word)) 118 | ); 119 | } 120 | 121 | // Time Complexity: O(M * N) 122 | // Space Complexity: O(1) 123 | -------------------------------------------------------------------------------- /problems/leetcode/array/25.sum_of_consecutive_integers.js: -------------------------------------------------------------------------------- 1 | /* Problem: How to Sum Integers 1 to n 2 | 3 | Example: 4 | Input: [1,2,3,4,5,6,7,8,9,10] 5 | Output: 55 6 | 7 | */ 8 | 9 | // Solution 1 - Brute Force 10 | function sumNumbers(listOfIntegers) { 11 | var result = 0; 12 | 13 | for (var i = 0; i < listOfIntegers.length; i++) { 14 | result += listOfIntegers[i]; 15 | } 16 | 17 | return result; 18 | } 19 | 20 | sumNumbers([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); 21 | 22 | // Time Complexity: O(N) 23 | 24 | // Solution 2 - (N * (N + 1)) / 2 25 | function sumNumbers(listOfIntegers) { 26 | return (listOfIntegers.length * (listOfIntegers.length + 1)) / 2; 27 | } 28 | 29 | sumNumbers([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); 30 | 31 | // Time Complexity: O(1), no matter how big the list is, solution will always run in constant time 32 | -------------------------------------------------------------------------------- /problems/leetcode/array/26.first_duplicate.js: -------------------------------------------------------------------------------- 1 | /* Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), 2 | prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one. 3 | 4 | Example: 5 | Input: [2, 1, 3, 5, 3, 4] 6 | Output: 3 7 | 8 | Example: 9 | Input: [2, 1, 5, 3, 4, 4] 10 | Output: 4 11 | 12 | Note: 13 | 14 | - List of numbers will start from 1 - N 15 | - List of numbers cannot be greater than N (N is list length) 16 | - You cannot modify the array 17 | - There is only one duplicate number in the array, but it could be repeated more than once. 18 | */ 19 | 20 | // Solution 1 - Two Pointer 21 | function findDuplicate(nums) { 22 | var minIndex = nums.length; 23 | for (var i = 0; i < nums.length; i++) { 24 | for (var j = i + 1; j < nums.length; j++) { 25 | if (nums[i] === nums[j]) { 26 | minIndex = Math.min(minIndex, j); 27 | } 28 | } 29 | } 30 | 31 | if (minIndex === nums.length) return -1; 32 | return nums[minIndex]; 33 | } 34 | 35 | findDuplicate([2, 1, 3, 5, 3, 4]); // 3 36 | findDuplicate([2, 1, 5, 3, 4]); // -1 37 | 38 | // Time Complexity: O(N^2) 39 | // Space Complexity: O(1) 40 | 41 | // Solution 2 - HashMap 42 | function findDuplicate(nums) { 43 | var hash = {}; 44 | for (var i = 0; i < nums.length; i++) { 45 | if (hash[nums[i]]) { 46 | return nums[i]; 47 | } else { 48 | hash[nums[i]] = true; 49 | } 50 | } 51 | 52 | return -1; 53 | } 54 | 55 | findDuplicate([2, 1, 3, 5, 3, 4]); // 3 56 | findDuplicate([2, 1, 5, 3, 4]); // -1 57 | 58 | // Time Complexity: O(N) 59 | // Space Complexity: O(N) 60 | 61 | // Solution 3 - Using index of array from problem 1 - N as clue, we will store make the index of num[i] value as -1 62 | function findDuplicate(nums) { 63 | for (var i = 0; i < nums.length; i++) { 64 | if (nums[Math.abs(nums[i]) - 1] < 0) { 65 | return Math.abs(nums[i]); 66 | } else { 67 | nums[Math.abs(nums[i]) - 1] = -nums[Math.abs(nums[i]) - 1]; 68 | } 69 | } 70 | 71 | return -1; 72 | } 73 | 74 | // Time Complexity: O(N) 75 | // Space Complexity: O(1) 76 | -------------------------------------------------------------------------------- /problems/leetcode/array/27.direction_reduction.js: -------------------------------------------------------------------------------- 1 | /* Problem: Once upon a time, on a way through the old wild mountainous west,a man was given directions to go from one point to another. 2 | The directions were "NORTH", "SOUTH", "WEST", "EAST". Clearly "NORTH" and "SOUTH" are opposite, "WEST" and "EAST" too. 3 | Going to one direction and coming back the opposite direction right away is a needless effort. Since this is the wild west, with dreadfull weather 4 | and not much water, it's important to save yourself some energy, otherwise you might die of thirst! 5 | 6 | How I crossed a mountain desert the smart way. 7 | 8 | Example 1: 9 | Input: ["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"]. 10 | Output: ["WEST"] 11 | 12 | Example 2: 13 | 14 | In ["NORTH", "SOUTH", "EAST", "WEST"], the direction "NORTH" + "SOUTH" is going north and coming back right away. 15 | The path becomes ["EAST", "WEST"], now "EAST" and "WEST" annihilate each other, therefore, the final result is []. 16 | In ["NORTH", "EAST", "WEST", "SOUTH", "WEST", "WEST"], "NORTH" and "SOUTH" are not directly opposite but they become directly opposite after the reduction of "EAST" and "WEST" so the whole path is reducible to ["WEST", "WEST"]. 17 | 18 | Notes: 19 | - Not all paths can be made simpler. The path ["NORTH", "WEST", "SOUTH", "EAST"] is not reducible. "NORTH" and "WEST", "WEST" and "SOUTH", "SOUTH" and "EAST" are not directly opposite of each other and can't become such. Hence the result path is itself : ["NORTH", "WEST", "SOUTH", "EAST"]. 20 | - if you want to translate, please ask before translating. 21 | 22 | */ 23 | 24 | // Solution 1 - Two pointer 25 | 26 | function dirReduc(arr) { 27 | var result = []; 28 | var tempResult = []; 29 | 30 | if (!arr) return result; 31 | 32 | var hashMap = { NORTH: "SOUTH", SOUTH: "NORTH", EAST: "WEST", WEST: "EAST" }; 33 | 34 | var pointer1 = 0; 35 | var pointer2 = 1; 36 | 37 | while (pointer1 <= arr.length - 1) { 38 | var p1Val = arr[pointer1]; 39 | var p2Val = arr[pointer2]; 40 | 41 | if (hashMap[p1Val] === p2Val) { 42 | pointer1 += 2; 43 | pointer2 += 2; 44 | } else { 45 | tempResult.push(p1Val); 46 | pointer1 += 1; 47 | pointer2 += 1; 48 | } 49 | } 50 | 51 | for (var i = 0; i < tempResult.length; i++) { 52 | if (hashMap[tempResult[i]] === tempResult[i + 1]) { 53 | i += 1; 54 | } else { 55 | result.push(tempResult[i]); 56 | } 57 | } 58 | 59 | return result; 60 | } 61 | 62 | dirReduc(["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"]); // ["WEST"] 63 | 64 | // Time Complexity: O(N) 65 | // Space Complexity: O(N) 66 | 67 | // Solution 2 - Two pointer in one iteration 68 | 69 | function dirReduc(arr) { 70 | if (!arr) return []; 71 | 72 | var hashMap = { NORTH: "SOUTH", SOUTH: "NORTH", EAST: "WEST", WEST: "EAST" }; 73 | 74 | for (var i = 0; i < arr.length - 1; ) { 75 | if (hashMap[arr[i]] === arr[i + 1]) { 76 | arr.splice(i, 2); 77 | i = i === 0 ? 0 : i - 1; 78 | } else { 79 | i += 1; 80 | } 81 | } 82 | 83 | return arr; 84 | } 85 | 86 | dirReduc(["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"]); // ["WEST"] 87 | 88 | // Time Complexity: O(N) 89 | // Space Complexity: O(1) 90 | -------------------------------------------------------------------------------- /problems/leetcode/array/28.max_of_sub_arrays.js: -------------------------------------------------------------------------------- 1 | /* 2 | Problem: Given an array of integers and a number k, where 1 <= k <= length of the array, compute the maximum values of each subarray of length k. 3 | 4 | Example: Given array = [10, 5, 2, 7, 8, 7] and k = 3, we should get: [10, 7, 8, 8], 5 | 6 | Explanation: 7 | 10 = max(10, 5, 2) 8 | 7 = max(5, 2, 7) 9 | 8 = max(2, 7, 8) 10 | 8 = max(7, 8, 7) 11 | 12 | Note: 13 | Do this in O(n) time and O(k) space. You can modify the input array in-place and you do not need to store the results. 14 | You can simply print them out as you compute them. 15 | 16 | */ 17 | 18 | // Solution 1 - Two loops 19 | 20 | function findMax(arr, k) { 21 | for (var i = 0; i < arr.length - k; i++) { 22 | var max = arr[i]; 23 | 24 | for (var j = 1; j < k; j++) { 25 | if (arr[j + i] > max) { 26 | max = arr[j + i]; 27 | } 28 | } 29 | 30 | console.log(max); 31 | } 32 | } 33 | 34 | var arr = [10, 5, 2, 7, 8, 7]; 35 | var k = 2; 36 | 37 | findMax(arr, 2); // [10, 5, 7, 8] 38 | 39 | // Time Complexity: O(N * K), N is (length of array - k) and K is no of subarray times we find max 40 | 41 | // Solution 2 - Deque (https://www.geeksforgeeks.org/sliding-window-maximum-maximum-of-all-subarrays-of-size-k/) 42 | -------------------------------------------------------------------------------- /problems/leetcode/array/3.flatten_array.js: -------------------------------------------------------------------------------- 1 | /* Problem: Flatten the given array 2 | 3 | Note: Multiple level might be there in given input 4 | 5 | Example: 6 | Input: [1, 2, [3, 4, [5, [6]]], 7, 0] to [0, 1, 2, 3, 4, 5, 6, 7] 7 | 8 | Output: [1, 2, 3, 4, 5, 6, 7, 0] 9 | 10 | */ 11 | 12 | // Method 1: Using Just Recursion 13 | 14 | function flatten(arr) { 15 | var temp = []; 16 | 17 | arr.forEach(function(val) { 18 | if (Object.prototype.toString.call(val) === '[object Array]') { 19 | temp = temp.concat(flatten(val)); 20 | } else { 21 | temp.push(val); 22 | } 23 | }); 24 | 25 | return temp; 26 | } 27 | 28 | flatten([1, 2, [3, 4, [5, [6]]], 7, 0]); // [1, 2, 3, 4, 5, 6, 7, 0] 29 | 30 | // Time Complexity: O(N) 31 | // Space Complexity: O(N) 32 | 33 | // Method 2: Using ES6 Reduce & Recursion 34 | 35 | function flatten() { 36 | return this.reduce((acc, val) => { 37 | return acc.concat(Array.isArray(val) ? flatten(val) : val); 38 | }, []); 39 | } 40 | 41 | flatten([1, 2, [3, 4, [5, [6]]], 7, 0]); // [1, 2, 3, 4, 5, 6, 7, 0] 42 | 43 | // Time Complexity: O(N) 44 | // Space Complexity: O(N) 45 | 46 | // Method 3: Using Divide & Conquer 47 | function divide(arr) { 48 | if (!arr.length) return []; 49 | else if (arr.length === 1) { 50 | if (Array.isArray(arr[0])) { 51 | return divide(arr[0]); 52 | } 53 | return [arr[0]]; 54 | } else { 55 | var mid = Math.floor(arr.length / 2); 56 | var left = arr.slice(0, mid); 57 | var right = arr.slice(mid); 58 | return merge(divide(left), divide(right)); 59 | } 60 | } 61 | 62 | function merge(left, right) { 63 | return left.concat(right); 64 | } 65 | 66 | divide([1, 2, [3, 4, [5, [6]]], 7, 0]); // [1, 2, 3, 4, 5, 6, 7, 0] 67 | 68 | // Time Complexity: O(LOG N) 69 | // Space Complexity: O(N) 70 | -------------------------------------------------------------------------------- /problems/leetcode/array/4.wave_array.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given an array of integers, sort the array into a wave like array and return it, 2 | 3 | Note: In other words, arrange the elements into a sequence such that a1 >= a2 <= a3 >= a4 <= a5..... 4 | 5 | Example: 6 | 7 | Input: [1, 2, 3, 4] 8 | 9 | One possible Ouput : [2, 1, 4, 3] 10 | Another possible Ouput : [4, 1, 3, 2] 11 | 12 | */ 13 | 14 | function waveArray(A) { 15 | var sortedArr = A.slice().sort(function (a, b) { return a - b }); // .slice to make clone the array, just to avoid infinite loop 16 | 17 | for (var i = 0; i < A.length - 1; i++) { 18 | var temp = sortedArr[i]; 19 | sortedArr[i] = sortedArr[i + 1]; 20 | sortedArr[i + 1] = temp; 21 | } 22 | 23 | return sortedArr; 24 | } 25 | 26 | waveArray([1, 2, 3, 4]); // [2, 1, 4, 3] 27 | 28 | // Time Complexity: O(N) 29 | -------------------------------------------------------------------------------- /problems/leetcode/array/5.remove_element.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given an array and a value, remove all instances of that value in-place and return the new length. 2 | 3 | Note 1: Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory. 4 | Note 2: O(1) extra memory means I can use one variable to assign some data thats all. 5 | 6 | Example: 7 | 8 | Input 1: [3, 3] 9 | Input 2: 3 10 | 11 | Output: [] & length = 0 12 | 13 | Input 1: [3,2,2,3] 14 | Input 2: 3 15 | 16 | Output: [2, 2] & length = 2 17 | 18 | Reference: In Place Algorithm - https://en.wikipedia.org/wiki/In-place_algorithm 19 | */ 20 | 21 | // Method 1 with out extra memory 22 | 23 | var removeElement = function (arr, val) { 24 | if (arr.length === 0) return 0; 25 | for (var i = 0, l = arr.length; i < l; i++) { 26 | if (arr.length === 0) break; 27 | if (arr[i] === val) { 28 | arr.splice(i, 1); 29 | i--; 30 | } 31 | } 32 | 33 | return arr.length; 34 | }; 35 | 36 | removeElement([3, 2, 2, 3], 3); // [2, 2] & length = 2 37 | 38 | // Time Complexity: O(n) 39 | 40 | // Method 2 41 | 42 | var removeElement = function (arr, val) { 43 | if (arr.length === 0) return 0; 44 | var count = 0; 45 | for (var i = 0, l = arr.length; i < l; i++) { 46 | if (arr[i] != val) { 47 | arr[count++] = arr[i]; 48 | } 49 | } 50 | 51 | return count; 52 | }; 53 | 54 | removeElement([3, 2, 2, 3], 3); // [2, 2] & length = 2 55 | 56 | // Time Complexity: O(n) with O(1) extra memory 57 | -------------------------------------------------------------------------------- /problems/leetcode/array/6.find_relative_winners.js: -------------------------------------------------------------------------------- 1 | /* Problems: Given scores of N athletes, find their relative ranks and the people with the top three highest scores, who will be awarded medals: "Gold Medal", "Silver Medal" and "Bronze Medal". 2 | 3 | Note: 4 | 1. N is a positive integer and won't exceed 10,000. 5 | 2. All the scores of athletes are guaranteed to be unique. 6 | 7 | Example: 8 | 9 | Input: [5, 4, 3, 2, 1] 10 | 11 | Output: ["Gold Medal", "Silver Medal", "Bronze Medal", "4", "5"] 12 | 13 | Explanation: The first three athletes got the top three highest scores, so they got "Gold Medal", "Silver Medal" and "Bronze Medal". For the left two athletes, you just need to output their relative ranks according to their scores. 14 | 15 | */ 16 | 17 | var findRelativeRanks = function (nums) { 18 | var hash = {}; 19 | for (var i = 0; i < nums.length; i++) { 20 | hash[nums[i]] = i; 21 | } 22 | 23 | var arr = nums.slice(); // Shallow Clone 24 | arr.sort(function (a, b) { return b - a }); // Sort in reverse order 25 | 26 | for (var i = 0; i < arr.length; i++) { 27 | if (i === 0) { 28 | nums[hash[arr[i]]] = "Gold Medal"; 29 | } 30 | else if (i === 1) { 31 | nums[hash[arr[i]]] = "Silver Medal"; 32 | } 33 | else if (i === 2) { 34 | nums[hash[arr[i]]] = "Bronze Medal"; 35 | } 36 | else { 37 | nums[hash[arr[i]]] = (i + 1).toString(); 38 | } 39 | } 40 | 41 | return nums; 42 | }; 43 | 44 | 45 | findRelativeRanks([5, 4, 3, 2, 1]); // ["Gold Medal", "Silver Medal", "Bronze Medal", "4", "5"] 46 | 47 | // Time Complexity: O(N), exluding the sort complexity which browser takes care of it 48 | // Space Complexity: O(1) 49 | -------------------------------------------------------------------------------- /problems/leetcode/array/7.reshape_matrix.js: -------------------------------------------------------------------------------- 1 | /* Problem: In MATLAB, there is a very useful function called 'reshape', which can reshape a matrix into a new one with different size but keep its original data. 2 | 3 | Note: 4 | - You're given a matrix represented by a two-dimensional array, and two positive integers r and c representing the row number and column number of the wanted reshaped matrix, respectively. 5 | - The reshaped matrix need to be filled with all the elements of the original matrix in the same row-traversing order as they were. 6 | - If the 'reshape' operation with given parameters is possible and legal, output the new reshaped matrix; Otherwise, output the original matrix. 7 | 8 | Example 1: 9 | Input: [[1,2], [3,4]], r = 1, c = 4 10 | Output: [[1,2,3,4]] 11 | Explanation: The row-traversing of nums is [1,2,3,4]. The new reshaped matrix is a 1 * 4 matrix, fill it row by row by using the previous list. 12 | 13 | Example 2: 14 | Input: [[1,2], [3,4]] r = 2, c = 4 15 | Output: [[1,2], [3,4]] 16 | Explanation: There is no way to reshape a 2 * 2 matrix to a 2 * 4 matrix. So output the original matrix. 17 | 18 | */ 19 | 20 | var matrixReshape = function (nums, r, c) { 21 | if (nums.length == 0) return []; 22 | if (r * c != nums.length * nums[0].length) return nums; 23 | var arr = []; 24 | 25 | for (var i = 0; i < nums.length; i++) { 26 | for (var j = 0; j < nums[0].length; j++) { 27 | arr.push(nums[i][j]); 28 | } 29 | } 30 | 31 | var ans = []; 32 | for (var i = 0; i < r; i++) { 33 | ans[i] = arr.splice(0, c); // splice to cut the array based on number of columns 34 | } 35 | return ans; 36 | }; 37 | 38 | 39 | matrixReshape([[1, 2], [3, 4]], 1, 4); // [[1,2,3,4]] 40 | 41 | // Time Complexity: O(N*M) 42 | // Space Complexity: O(N*M), as we are storing in array according to no of N & M 43 | -------------------------------------------------------------------------------- /problems/leetcode/array/8.max_k_elements_in_array.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given an array of integers of size ‘n’. Calculate the maximum sum of ‘k’ consecutive elements in the array. 2 | 3 | Example 1: 4 | Input: [100, 200, 300, 400], k = 2 5 | Output : 700 6 | 7 | Example 2: 8 | Input: [1, 4, 2, 10, 23, 3, 1, 0, 20] k = 4 9 | Output : 39 10 | 11 | */ 12 | 13 | // Brute Force Approach using nested for-loops 14 | var maxSumOfKElements = function (arr, k) { 15 | var maxSum = 0; 16 | if (arr.length === 0 || k < 1) return maxSum; 17 | 18 | for (var i = 0; i < arr.length - k + 1; i++) { 19 | var tempSum = 0; 20 | for (var j = 0; j < k; j++) { 21 | tempSum += arr[i + j]; 22 | maxSum = Math.max(maxSum, tempSum); 23 | } 24 | } 25 | 26 | return maxSum; 27 | } 28 | 29 | maxSumOfKElements([100, 200, 300, 400], 2); // 700 30 | 31 | // Time Complexity: O(N*K), N is number of elements in Array 32 | 33 | // Optimized version below 34 | 35 | // Now using Window Sliding Technique, we can solve this in O(N) complexity 36 | // More - https://stackoverflow.com/questions/8269916/what-is-sliding-window-algorithm-examples 37 | 38 | var maxSumOfKElements = function (arr, k) { 39 | var maxSum = 0; 40 | if (arr.length === 0 || k < 1) return maxSum; 41 | 42 | // First find the max sum for 'K' elements in the given array 43 | for (var i = 0; i < k; i++) { 44 | maxSum += arr[i]; 45 | } 46 | 47 | // Move by one unit and calculate sum for 'K' elements in array 48 | // Compare current sum with max, if > replace max else move to next unit. 49 | // Repeat until the end. 50 | 51 | var currentSum = max; 52 | for (var i = k; i < arr.length; i++) { 53 | currentSum += arr[i] - arr[i - k]; // To get current sum of K elements, we are subtracting the previous element + adding new sum to current sum 54 | maxSum = Math.max(currentSum, max); 55 | } 56 | 57 | return maxSum; 58 | } 59 | 60 | maxSumOfKElements([100, 200, 300, 400], 2); // 700 61 | 62 | // Time Complexity: O(N) 63 | -------------------------------------------------------------------------------- /problems/leetcode/array/9.single_number.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given an array of integers, every element appears twice except for one. Find that single one. 2 | 3 | Note: Your algorithm should have a linear runtime complexity O(N). Could you implement it without using extra memory? 4 | 5 | Example: 6 | Input: [1, 2, 2, 4, 5, 3, 5, 3, 10, 4, 1, 8, 8] 7 | Output: 10; 8 | 9 | */ 10 | 11 | // Using Hash Table 12 | var findSingleNumber = function (nums) { 13 | if (nums.length === 1) return nums[0]; 14 | var obj = {}; 15 | for (var i = 0; i < nums.length; i++) { 16 | if (!obj[nums[i]]) { 17 | obj[nums[i]] = 1; 18 | } 19 | else obj[nums[i]]++; 20 | } 21 | 22 | for (var i in obj) { 23 | if (obj[i] === 1) return parseInt(i); 24 | } 25 | } 26 | 27 | findSingleNumber([1, 2, 2, 4, 5, 3, 5, 3, 10, 4, 1, 8, 8]); // 10 28 | 29 | // Time Complexity: O(N) 30 | // Space Complexity: O(N), as we are storing all the numbers in the array 31 | 32 | // Using XOR 33 | // This is how an XOR works 34 | // 1. num ^ 0 = num 35 | // 2. num ^ num = 0 36 | 37 | var findSingleNumber = function (nums) { 38 | if (nums.length === 1) return nums[0]; 39 | 40 | var xor = 0; 41 | for (var i = 0; i < nums.length; i++) { 42 | xor ^= nums[i]; 43 | } 44 | 45 | return xor; 46 | } 47 | 48 | findSingleNumber([1, 2, 2, 4, 5, 3, 5, 3, 10, 4, 1, 8, 8]); // 10 49 | 50 | // Time Complexity: O(N) 51 | // Space Complexity: O(1) 52 | 53 | -------------------------------------------------------------------------------- /problems/leetcode/array/README.md: -------------------------------------------------------------------------------- 1 | # Array 2 | 3 | 1. [Rearrange Array](./1.rearrange_array.js) 4 | 1. [Largest Formed Number](./2.largest_number.js) 5 | 1. [Flatten Multiple Level Array](./3.flatten_array.js) 6 | 1. [Wave Array](./4.wave_array.js) 7 | 1. [Remove Element](./5.remove_element.js) 8 | 1. [Find Relative Winners](./6.find_relative_winners.js) 9 | 1. [Reshape To Matrix](./7.reshape_matrix.js) 10 | 1. [Max Sum Of K Elements](./8.max_k_elements_in_array.js) 11 | 1. [Find Single Number](./9.single_number.js) 12 | 1. [Area of Island (2D Array)](./10.area_of_island.js) 13 | 1. [Find the Missing Number](./11.missing_number.js) 14 | 1. [Distribute Candies](./12.distribute_candies.js) 15 | 1. [Max Consecutive Ones](./13.max_consecutives_ones.js) 16 | 1. [Where do i belong](./14.where_do_i_belong.js) 17 | 1. [Water Container](./15.water_container.js) 18 | 1. [Reverse Words in a String](./16.reverse_words.js) 19 | 1. [Can Place Flowers](./17.flower_bed.js) 20 | 1. [Rotate Array](./18.rotate_array.js) 21 | 1. [Intersection of Two Arrays](./19.intersection_of_numbers.js) 22 | 1. [Sort Array By Parity](./20.sort_by_parity.js) 23 | 1. [Find Duplicate Numbers](./21.find_duplicate_number.js) 24 | 1. [Subsets](./22.subsets.js) 25 | 1. [Longest Vowel Chain](./23.longest_vowel_chain.js) 26 | 1. [Keyboard Row](./24.keyboard_row.js) 27 | 1. [Sum of Consecutive Integers](./25.sum_of_consecutive_integers.js) 28 | 1. [First Duplicate](./26.first_duplicate.js) 29 | 1. [Direction Reduction](./27.direction_reduction.js) 30 | 1. [Max of sub arrays](./28.max_of_sub_arrays.js) 31 | -------------------------------------------------------------------------------- /problems/leetcode/back tracking/1.word_search.js: -------------------------------------------------------------------------------- 1 | /* Problem: Word Search 2 | 3 | Given a 2D board and a word, find if the word exists in the grid. 4 | The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. 5 | The same letter cell may not be used more than once. 6 | 7 | Example: 8 | 9 | board = 10 | [ 11 | ['A','B','C','E'], 12 | ['S','F','C','S'], 13 | ['A','D','E','E'] 14 | ] 15 | 16 | Given word = "ABCCED", return true. 17 | Given word = "SEE", return true. 18 | Given word = "ABCB", return false. 19 | 20 | */ 21 | 22 | var wordSearch = function(board, word) { 23 | if (!word || !board.length || !board[0].length) { 24 | return false; 25 | } 26 | 27 | for (var i = 0; i < board.length; i++) { 28 | for (var j = 0; j < board[0].length; j++) { 29 | if (word[0] === board[i][j] && hasCharInAdjacent(i, j, 0, board, word)) { 30 | return true; 31 | } 32 | } 33 | } 34 | 35 | return false; 36 | }; 37 | 38 | function hasCharInAdjacent(i, j, index, board, word) { 39 | if (word.length === index) { 40 | // when word.length & index are same we found the word in adjacent of board 41 | return true; 42 | } 43 | 44 | if (i < 0 || j < 0 || i >= board.length || j >= board[0].length) { 45 | return false; 46 | } 47 | 48 | if (board[i][j] !== word[index]) { 49 | return false; 50 | } 51 | 52 | var temp = board[i][j]; 53 | board[i][j] = '*'; // Mark this char as visited, later we can restore it 54 | 55 | // Now lets move horizontally or vertically to find the word in adjacent 56 | 57 | // Move down 58 | if (hasCharInAdjacent(i + 1, j, index + 1, board, word)) { 59 | return true; 60 | } 61 | 62 | // Move up 63 | if (hasCharInAdjacent(i - 1, j, index + 1, board, word)) { 64 | return true; 65 | } 66 | 67 | // Move right 68 | if (hasCharInAdjacent(i, j + 1, index + 1, board, word)) { 69 | return true; 70 | } 71 | 72 | // Move left 73 | if (hasCharInAdjacent(i, j - 1, index + 1, board, word)) { 74 | return true; 75 | } 76 | 77 | board[i][j] = temp; // Restoring the char 78 | } 79 | 80 | wordSearch([['A', 'B', 'C', 'E'], ['S', 'F', 'C', 'S'], ['A', 'D', 'E', 'E']], 'ABCCED'); // True 81 | wordSearch([['A', 'B', 'C', 'E'], ['S', 'F', 'C', 'S'], ['A', 'D', 'E', 'E']], 'SEE'); // True 82 | wordSearch([['A', 'B', 'C', 'E'], ['S', 'F', 'C', 'S'], ['A', 'D', 'E', 'E']], 'ABCB'); // False 83 | 84 | // Time Complexity: O(N * M * K), N, M are 2D board length & K is word.length 85 | -------------------------------------------------------------------------------- /problems/leetcode/back tracking/2.surrounded_area.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by 'X'. 2 | 3 | A region is captured by flipping all 'O's into 'X's in that surrounded region. 4 | 5 | Example: 6 | X X X X 7 | X O O X 8 | X X O X 9 | X O X X 10 | 11 | After running your function, the board should be: 12 | 13 | X X X X 14 | X X X X 15 | X X X X 16 | X O X X 17 | 18 | Explanation: 19 | - Surrounded regions shouldn’t be on the border, which means that any 'O' on the border of the board are not flipped to 'X'. 20 | - Any 'O' that is not on the border and it is not connected to an 'O' on the border will be flipped to 'X'. 21 | - Two cells are connected if they are adjacent cells connected horizontally or vertically. 22 | 23 | 24 | Idea: Backtracking and start with starting and ending index of row and columns and find if there is any ajdecent O's, if there replace it temp var 25 | 26 | */ 27 | 28 | var solve = function(board) { 29 | for (var i = 0; i < board.length; i++) { 30 | for (var j = 0; j < board[0].length; j++) { 31 | if ((i == 0 || i == board.length - 1 || j == 0 || j == board[0].length - 1) && board[i][j] == 'O') { 32 | backTrack(i, j, board); 33 | } 34 | } 35 | } 36 | 37 | for (var i = 0; i < board.length; i++) { 38 | for (var j = 0; j < board[0].length; j++) { 39 | if (board[i][j] === 'O') { 40 | board[i][j] = 'X'; 41 | } 42 | 43 | if (board[i][j] === '*') { 44 | board[i][j] = 'O'; 45 | } 46 | } 47 | } 48 | 49 | function backTrack(i, j, board) { 50 | if (i < 0 || j < 0 || i > board.length - 1 || j > board[0].length - 1) return; 51 | if (board[i][j] == 'O') { 52 | board[i][j] = '*'; 53 | backTrack(i + 1, j, board); 54 | backTrack(i - 1, j, board); 55 | backTrack(i, j + 1, board); 56 | backTrack(i, j - 1, board); 57 | } 58 | } 59 | 60 | return board; 61 | }; 62 | 63 | solve([['X', 'X', 'X', 'X'], ['X', 'O', 'O', 'X'], ['X', 'X', 'O', 'X'], ['X', 'O', 'X', 'X']]); // [["X","X","X","X"],["X","X","X","X"],["X","X","X","X"],["X","O","X","X"]] 64 | 65 | // Time Complexity: O(N^2), as in worst case we will be visiting all rows and columns 66 | // Space Complexity: O(1) 67 | -------------------------------------------------------------------------------- /problems/leetcode/back tracking/3.paint_house.js: -------------------------------------------------------------------------------- 1 | /* Problem: Find the minimum cost to paint all houses. 2 | 3 | Note: 4 | - There are a row of n houses, each house can be painted with one of the three colors: red, blue or green. 5 | - The cost of painting each house with a certain color is different. 6 | - You have to paint all the houses such that no two adjacent houses have the same color. 7 | - The cost of painting each house with a certain color is represented by a n x 3 cost matrix. 8 | 9 | Example: [[17, 2, 17], [15, 1, 4], [18, 3, 19]] 10 | Output: 9 11 | 12 | Explanation: 13 | 1. Min cost of painting house 0 is 2 14 | 2. Min cost of painting house 1 is 4, we cannot pick 1 as the neighbors (house 0) has it. 15 | 3. Min cost of painting house 2 is 3; 16 | 17 | Ans: 2 + 4 + 3 = 9 18 | 19 | */ 20 | 21 | function minCostOfPainting(housesMatrix) { 22 | if (housesMatrix.length === 0) { 23 | return 0; 24 | } 25 | 26 | for (var i = 1; i < housesMatrix.length; i++) { 27 | housesMatrix[i][0] += Math.min(housesMatrix[i - 1][1], housesMatrix[i - 1][2]); 28 | housesMatrix[i][1] += Math.min(housesMatrix[i - 1][0], housesMatrix[i - 1][2]); 29 | housesMatrix[i][2] += Math.min(housesMatrix[i - 1][0], housesMatrix[i - 1][1]); 30 | } 31 | 32 | var n = housesMatrix.length - 1; 33 | return Math.min(housesMatrix[n][0], housesMatrix[n][1], housesMatrix[n][2]); 34 | } 35 | 36 | var housesMatrix = [ 37 | [17, 2, 17], 38 | [15, 1, 4], 39 | [18, 3, 19] 40 | ]; 41 | 42 | minCostOfPainting(housesMatrix); // 9 43 | 44 | // Time Complexity: O(N), N is number of houses 45 | // Space Complexity: O(1), as we changed the input matrix 46 | -------------------------------------------------------------------------------- /problems/leetcode/back tracking/README.md: -------------------------------------------------------------------------------- 1 | # Back Tracking 2 | 3 | 1. [Word Search in 2D](./1.word_search.js) 4 | 1. [Surrounded Area in 2D](./2.surrounded_area.js) 5 | 1. [Paint House](./3.paint_house.js) 6 | -------------------------------------------------------------------------------- /problems/leetcode/bit manipulation/1.number_of_1_bits.js: -------------------------------------------------------------------------------- 1 | /* Problem: Write a function that takes an unsigned integer and returns the number of 1 bits it has. 2 | 3 | Example: 4 | 5 | The 32-bit integer 11 has binary representation of = 00000000000000000000000000001011 6 | 7 | Input: 32-bit integer 11 8 | Output: 3 9 | 10 | Input: 1000000 11 | Output: 7 12 | 13 | */ 14 | 15 | // Unoptimized version: 16 | 17 | function findNoOneBits(A) { 18 | var binaryNo = A.toString(2); 19 | var count = 0; 20 | var total = 0; 21 | while (count < binaryNo.length) { 22 | if (binaryNo[count] === '1') { 23 | total += 1; 24 | } 25 | count++; 26 | } 27 | return total; 28 | } 29 | 30 | findNoOneBits(11); // 3 31 | findNoOneBits(1000000); // 7 32 | 33 | /* 34 | Time Complexity: O(n) 35 | */ 36 | 37 | // Optimized version below: 38 | 39 | function findNoOneBits(A) { 40 | var count = 0; 41 | while (A > 0) { 42 | A &= A - 1; // (A & A - 1) - unset the last set bit in A 43 | count++; 44 | } 45 | return count; 46 | } 47 | 48 | findNoOneBits(11); // 3 49 | findNoOneBits(1000000); // 7 50 | 51 | /* 52 | Time Complexity: O(number of ones in A) 53 | */ 54 | -------------------------------------------------------------------------------- /problems/leetcode/bit manipulation/2.sum_of_two_number.js: -------------------------------------------------------------------------------- 1 | /* Problems: Sum of Two Integers 2 | 3 | Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -. 4 | 5 | Example 1: 6 | Input: a = 1, b = 2 7 | Output: 3 8 | 9 | Example 2: 10 | Input: a = -2, b = 3 11 | Output: 1 12 | 13 | */ 14 | 15 | var sumOfTwoNumbers = function(a, b) { 16 | if (b === 0) return a; 17 | var sumOfTwoBits = a ^ b; // Will give sum of two bits 18 | var carryBits = a & b; // will give carry over bit 19 | return sumOfTwoNumbers(sumOfTwoBits, carryBits << 1); // << Will shift all bits to left by 1 20 | }; 21 | 22 | sumOfTwoNumbers(1, 2); // 3 23 | 24 | // Time Complexity: O(N) 25 | // Space Complexity: O(N) 26 | -------------------------------------------------------------------------------- /problems/leetcode/bit manipulation/README.md: -------------------------------------------------------------------------------- 1 | # Bit Manipulation 2 | 3 | 1. [Number of 1 BitsBookmark](./1.number_of_1_bits.js) 4 | 1. [Sum Of Two Numbers](./2.sum_of_two_number.js) 5 | -------------------------------------------------------------------------------- /problems/leetcode/cache/1.lru_cache.js: -------------------------------------------------------------------------------- 1 | /* Problem: LRU Cache 2 | 3 | Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put. 4 | - get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1. 5 | - put(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item. 6 | 7 | Follow up: 8 | - Could you do both operations in O(1) time complexity? 9 | 10 | Example: 11 | 12 | LRUCache cache = new LRUCache( 2 ); // capacity 13 | 14 | cache.put(1, 1); 15 | cache.put(2, 2); 16 | cache.get(1); // returns 1 17 | cache.put(3, 3); // evicts key 2 18 | cache.get(2); // returns -1 (not found) 19 | cache.put(4, 4); // evicts key 1 20 | cache.get(1); // returns -1 (not found) 21 | cache.get(3); // returns 3 22 | cache.get(4); // returns 4 23 | 24 | 25 | Reference: https://medium.com/dsinjs/implementing-lru-cache-in-javascript-94ba6755cda9 26 | 27 | */ 28 | 29 | function LRUCache(limit) { 30 | this.map = {}; 31 | this.storage = []; 32 | this.limit = limit; 33 | } 34 | 35 | LRUCache.prototype.get = function(key) { 36 | if (this.map[key]) { 37 | this.update(key); 38 | return this.map[key]; 39 | } 40 | 41 | return -1; 42 | }; 43 | 44 | LRUCache.prototype.put = function(key, value) { 45 | if (this.map[key]) { 46 | this.update(key); 47 | this.map[key] = value; 48 | return; 49 | } 50 | 51 | if (this.limit === this.storage.length) { 52 | delete this.map[this.storage.shift()]; 53 | } 54 | 55 | this.map[key] = value; 56 | this.storage.push(key); 57 | }; 58 | 59 | LRUCache.prototype.update = function(key) { 60 | this.storage.splice(this.storage.indexOf(key), 1); 61 | this.storage.push(key); 62 | }; 63 | 64 | var cache = new LRUCache(2); // capacity 65 | 66 | cache.put(1, 1); 67 | cache.put(2, 2); 68 | cache.get(1); // returns 1 69 | cache.put(3, 3); // evicts key 2 70 | cache.get(2); // returns -1 (not found) 71 | cache.put(4, 4); // evicts key 1 72 | cache.get(1); // returns -1 (not found) 73 | cache.get(3); // returns 3 74 | cache.get(4); // returns 4 75 | 76 | // Time Complexity: O(1), even better we could implement this using doubly linked list as read & write is O(1) 77 | -------------------------------------------------------------------------------- /problems/leetcode/cache/README.md: -------------------------------------------------------------------------------- 1 | # Cache 2 | 3 | 1. [Implement LRU cache](./1.lru_cache.js) 4 | -------------------------------------------------------------------------------- /problems/leetcode/hashing/1.array_of_anagrams.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given an array of strings, return all groups of strings that are anagrams. 2 | 3 | Note 1: Represent a group by a list of integers representing the index in the original list. Look at the sample case for clarification. 4 | Note 2: All inputs will be in lower-case. 5 | 6 | Example : 7 | 8 | Input : ["cat", "dog", "god", "tca"] 9 | 10 | Output : [[1, 4], [2, 3]] 11 | 12 | Explanation: 13 | 14 | - cat and tca are anagrams which correspond to index 1 and 4. 15 | - dog and god are another set of anagrams which correspond to index 2 and 3. 16 | - The indices are 1 based ( the first element has index 1 instead of index 0). 17 | 18 | */ 19 | 20 | function findAnagram(arr) { 21 | var temp = []; 22 | if (arr.length === 0) return temp; 23 | var obj = {}; 24 | 25 | arr.forEach((str, index) => { 26 | var sortedStr = str.split("").sort().join(""); 27 | 28 | if (obj[sortedStr]) { 29 | obj[sortedStr].push(index + 1); 30 | } else { 31 | obj[sortedStr] = [index + 1]; 32 | } 33 | }); 34 | 35 | for (var i in obj) { 36 | temp.push(obj[i]); 37 | } 38 | 39 | return temp; 40 | } 41 | 42 | findAnagram(["cat", "dog", "god", "tca"]); // [[1, 4], [2, 3]] 43 | findAnagram(["b"]); // [1]; 44 | 45 | // Time Complexity: O(N) 46 | -------------------------------------------------------------------------------- /problems/leetcode/hashing/2.unique_morse_codes.js: -------------------------------------------------------------------------------- 1 | /* Problem: International Morse Code defines a standard encoding where each letter is mapped to a series of dots and dashes, as follows: "a" maps to ".-", "b" maps to "-...", "c" maps to "-.-.", and so on. 2 | 3 | Note: For convenience, the full table for the 26 letters of the English alphabet is given below: 4 | 5 | [".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."]; 6 | 7 | Now, given a list of words, each word can be written as a concatenation of the Morse code of each letter. For example, "cab" can be written as "-.-.-....-", (which is the concatenation "-.-." + "-..." + ".-"). We'll call such a concatenation, the transformation of a word. 8 | 9 | Return the number of different transformations among all words we have. 10 | 11 | Example: 12 | Input: words = ["gin", "zen", "gig", "msg"] 13 | Output: 2 14 | Explanation: 15 | The transformation of each word is: 16 | "gin" -> "--...-." 17 | "zen" -> "--...-." 18 | "gig" -> "--...--." 19 | "msg" -> "--...--." 20 | 21 | There are 2 different transformations, "--...-." and "--...--.". 22 | 23 | Note: 24 | - The length of words will be at most 100. 25 | - Each words[i] will have length in range [1, 12]. 26 | - words[i] will only consist of lowercase letters. 27 | */ 28 | 29 | var uniqueMorseRepresentations = function (words) { 30 | var morseCode = [".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.."]; 31 | var strs = {}; 32 | 33 | for (var i = 0; i < words.length; i++) { 34 | strs[words[i]] = words[i].split(""); 35 | } 36 | 37 | var result = {}; 38 | 39 | for (var i in strs) { 40 | var str = "" 41 | for (var j = 0; j < strs[i].length; j++) { 42 | var char = strs[i][j]; 43 | var code = char.charCodeAt() - 97; 44 | str += morseCode[code]; 45 | } 46 | 47 | if (!result[str]) { 48 | result[str] = str; 49 | } 50 | } 51 | 52 | var count = 0; 53 | 54 | for (var i in result) { 55 | count++; 56 | } 57 | 58 | return count; 59 | }; 60 | 61 | // Time Complexity: O(N^2) 62 | // Space Complexity: O(N) 63 | -------------------------------------------------------------------------------- /problems/leetcode/hashing/3.set_matrix_zeros.js: -------------------------------------------------------------------------------- 1 | /* Problems: Set Matrix Zeroes 2 | 3 | Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in-place. 4 | 5 | Example 1: 6 | 7 | Input: 8 | [ 9 | [1,1,1], 10 | [1,0,1], 11 | [1,1,1] 12 | ] 13 | 14 | Output: 15 | [ 16 | [1,0,1], 17 | [0,0,0], 18 | [1,0,1] 19 | ] 20 | 21 | Example 2: 22 | 23 | Input: 24 | [ 25 | [0,1,2,0], 26 | [3,4,5,2], 27 | [1,3,1,5] 28 | ] 29 | 30 | Output: 31 | [ 32 | [0,0,0,0], 33 | [0,4,5,0], 34 | [0,3,1,0] 35 | ] 36 | 37 | Follow up: 38 | - A straight forward solution using O(mn) space is probably a bad idea. 39 | - A simple improvement uses O(m + n) space, but still not the best solution. 40 | - Could you devise a constant space solution? 41 | 42 | */ 43 | 44 | var setZeros = function(matrix) { 45 | if (!matrix.length) { 46 | return []; 47 | } 48 | 49 | var hashRows = {}; 50 | var hashCols = {}; 51 | 52 | var n = matrix.length; 53 | var m = matrix[0].length; 54 | 55 | for (var i = 0; i < n; i++) { 56 | for (var j = 0; j < m; j++) { 57 | if (matrix[i][j] == 0) { 58 | hashRows[i] = true; 59 | hashCols[j] = true; 60 | } 61 | } 62 | } 63 | 64 | for (var i = 0; i < n; i++) { 65 | for (var j = 0; j < m; j++) { 66 | if (hashRows[i] || hashCols[j]) { 67 | matrix[i][j] = 0; 68 | } 69 | } 70 | } 71 | 72 | return matrix; 73 | }; 74 | 75 | setZeros([[1, 1, 1], [1, 0, 1], [1, 1, 1]]); // [ [1,0,1], [0,0,0], [1,0,1] ] 76 | setZeros([[0, 1, 2, 0], [3, 4, 5, 2], [1, 3, 1, 5]]); // [ [0,0,0,0], [0,4,5,0], [0,3,1,0] ] 77 | 78 | // Time Complexity: O(M * N) where M, N is number rows in matrix. 79 | // Space Complexity: O(M + N) 80 | -------------------------------------------------------------------------------- /problems/leetcode/hashing/4.two_sum.js: -------------------------------------------------------------------------------- 1 | /* Problem: Two Sum 2 | 3 | Given an array of integers, return indices of the two numbers such that they add up to a specific target. 4 | 5 | Note: You may assume that each input would have exactly one solution, and you may not use the same element twice. 6 | 7 | Example: 8 | 9 | Given nums = [2, 7, 11, 15], target = 9, 10 | 11 | Because nums[0] + nums[1] = 2 + 7 = 9, 12 | return [0, 1]. 13 | 14 | */ 15 | 16 | // Solution 1 - Two-pass Hash Table 17 | 18 | var twoSum = function(nums, target) { 19 | var hash = {}; 20 | 21 | for (var i = 0; i < nums.length; i++) { 22 | var num = target - nums[i]; 23 | if (!hash[num]) { 24 | hash[num] = { i }; 25 | } 26 | } 27 | 28 | for (var i = 0; i < nums.length; i++) { 29 | if (hash[nums[i]] && hash[nums[i]].i !== i) return [hash[nums[i]].i, i]; 30 | } 31 | 32 | return [0, 0]; 33 | }; 34 | 35 | twoSum([2, 7, 11, 15], 9); //[0, 1] 36 | 37 | // Time Complexity: O(N) 38 | // Space Complexity: O(N) 39 | -------------------------------------------------------------------------------- /problems/leetcode/hashing/5.distribute_candies.js: -------------------------------------------------------------------------------- 1 | /* Problem: Alice has n candies, where the ith candy is of type candyType[i]. Alice noticed that she started to gain weight, so she visited a doctor. 2 | 3 | The doctor advised Alice to only eat n / 2 of the candies she has (n is always even). 4 | Alice likes her candies very much, and she wants to eat the maximum number of different types of candies 5 | while still following the doctor's advice. Given the integer array candyType of length n, 6 | return the maximum number of different types of candies she can eat if she only eats n / 2 of them. 7 | 8 | Example 1: 9 | Input: candyType = [1,1,2,2,3,3] 10 | Output: 3 11 | Explanation: Alice can only eat 6 / 2 = 3 candies. Since there are only 3 types, she can eat one of each type. 12 | 13 | Example 2: 14 | Input: candyType = [1,1,2,3] 15 | Output: 2 16 | Explanation: Alice can only eat 4 / 2 = 2 candies. Whether she eats types [1,2], [1,3], or [2,3], she still can only eat 2 different types. 17 | 18 | Example 3: 19 | Input: candyType = [6,6,6,6] 20 | Output: 1 21 | Explanation: Alice can only eat 4 / 2 = 2 candies. Even though she can eat 2 candies, she only has 1 type. 22 | 23 | 24 | Constraints: 25 | - n == candyType.length 26 | - 2 <= n <= 104 27 | - n is even. 28 | - -105 <= candyType[i] <= 105 29 | 30 | */ 31 | 32 | function distributeCandies(candyType) { 33 | const n = candyType.length; 34 | 35 | if (n % 2 !== 0) { 36 | return 0; 37 | } 38 | 39 | var hashMap = {}; 40 | 41 | for (var i = 0; i < n; i++) { 42 | hashMap[candyType[i]] = true; 43 | } 44 | 45 | var noOfUniqueCandies = Object.keys(hashMap).length; 46 | 47 | return noOfUniqueCandies >= n / 2 ? n / 2 : noOfUniqueCandies; 48 | } 49 | 50 | distributeCandies([1, 1, 2, 2, 3, 3]); // 3 51 | distributeCandies([1, 1, 2, 2, 3, 3]); // 2 52 | distributeCandies([6, 6, 6, 6]); // 1 53 | 54 | // Time Complexity: O(N) 55 | // Space Complexity: O(N), worst case all the candies in candyType is unique 56 | -------------------------------------------------------------------------------- /problems/leetcode/hashing/6.set_mismatch.js: -------------------------------------------------------------------------------- 1 | /* Problems: You have a set of integers s, which originally contains all the numbers from 1 to n. 2 | Unfortunately, due to some error, one of the numbers in s got duplicated to another number in the set, 3 | which results in repetition of one number and loss of another number. 4 | 5 | You are given an integer array nums representing the data status of this set after the error. Find the number that 6 | occurs twice and the number that is missing and return them in the form of an array. 7 | 8 | Example 1: 9 | Input: nums = [1,2,2,4] 10 | Output: [2,3] 11 | 12 | Example 2: 13 | Input: nums = [1,1] 14 | Output: [1,2] 15 | 16 | */ 17 | 18 | // Solution 1 - Using HashMap 19 | function findMissingAndDuplicate(nums) { 20 | var hash = {}; 21 | 22 | for (var i = 0; i < nums.length; i++) { 23 | if (!hash[nums[i]]) { 24 | hash[nums[i]] = 1; 25 | } else { 26 | hash[nums[i]] += 1; 27 | } 28 | } 29 | 30 | var missing = 1; 31 | var duplicate = -1; 32 | 33 | for (var i = 1; i <= nums.length; i++) { 34 | if (hash[i]) { 35 | if (hash[i] === 2) { 36 | duplicate = i; 37 | } else { 38 | missing = i; 39 | } 40 | } 41 | } 42 | 43 | return [duplicate, missing]; 44 | } 45 | 46 | findMissingAndDuplicate([1, 1]); // [1, 2] 47 | findMissingAndDuplicate([1, 2, 2, 4]); // [2, 3] 48 | findMissingAndDuplicate([3, 2, 2]); // [2, 1] 49 | 50 | // Time Complexity: O(N) 51 | // Space Complexity: O(N) 52 | 53 | // Solution 2 - Using in place array modification 54 | 55 | function findMissingAndDuplicate(nums) { 56 | var missing = 1; 57 | var duplicate = -1; 58 | 59 | for (var i = 0; i < nums.length; i++) { 60 | var num = Math.abs(nums[i]); 61 | if (nums[num - 1] < 0) { 62 | duplicate = num; 63 | } else { 64 | nums[num - 1] *= -1; 65 | } 66 | } 67 | 68 | for (var i = 1; i <= nums.length; i++) { 69 | if (nums[i] > 0) { 70 | missing = i + 1; 71 | } 72 | } 73 | 74 | return [duplicate, missing]; 75 | } 76 | 77 | findMissingAndDuplicate([1, 1]); // [1, 2] 78 | findMissingAndDuplicate([1, 2, 2, 4]); // [2, 3] 79 | findMissingAndDuplicate([3, 2, 2]); // [2, 1] 80 | 81 | // Time Complexity: O(N) 82 | // Space Complexity: O(1), as are we modifying in place and having constant space. 83 | -------------------------------------------------------------------------------- /problems/leetcode/hashing/README.md: -------------------------------------------------------------------------------- 1 | # Hashing 2 | 3 | 1. [Array of Anagrams](./1.array_of_anagrams.js) 4 | 1. [Unique Morse Codes](./2.unique_morse_codes.js) 5 | 1. [Set Matrix Zeros](./3.set_matrix_zeros.js) 6 | 1. [Two Sum](./4.two_sum.js) 7 | 1. [Distribute Candies](./5.distribute_candies.js) 8 | 1. [Set Mismatch](./6.set_mismatch.js) 9 | -------------------------------------------------------------------------------- /problems/leetcode/in place/1.sort_colours.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given an array with n objects colored red, white or blue, sort them in-place so that objects of the same color are adjacent, 2 | with the colors in the order red, white and blue. Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively. 3 | 4 | Example: 5 | Input: [2,0,2,1,1,0] 6 | Output: [0,0,1,1,2,2] 7 | 8 | Follow up: 9 | - A rather straight forward solution is a two-pass algorithm using counting sort. 10 | - First, iterate the array counting number of 0's, 1's, and 2's, then overwrite array with total number of 0's, then 1's and followed by 2's. 11 | - Could you come up with a one-pass algorithm using only constant space? 12 | 13 | Note: You are not suppose to use the library's sort function for this problem. 14 | 15 | */ 16 | 17 | // Solution 1 - Using hashmap 18 | 19 | var sortColors = function(nums) { 20 | var hash = {}; 21 | 22 | for (var i = 0; i < nums.length; i++) { 23 | if (!hash[nums[i]]) { 24 | hash[nums[i]] = 1; 25 | } else { 26 | hash[nums[i]] += 1; 27 | } 28 | } 29 | 30 | var temp = []; 31 | 32 | for (var i in hash) { 33 | for (var j = 1; j <= hash[i]; j++) { 34 | temp.push(parseInt(i)); 35 | } 36 | } 37 | 38 | return temp; 39 | }; 40 | 41 | sortColors([2, 0, 2, 1, 1, 0]); // [0,0,1,1,2,2] 42 | 43 | // Time Complexity: O(N2) 44 | // Space Complexity: O(N) 45 | 46 | // Solution 2 - One Pass using two pointers & swapping 47 | var sortColors = function(nums) { 48 | var low = 0; 49 | var high = nums.length - 1; 50 | var temp; 51 | 52 | for (var i = 0; i <= high;) { 53 | if (nums[i] === 0) { 54 | temp = nums[i]; 55 | nums[i] = nums[low]; 56 | nums[low] = temp; 57 | i++; 58 | low++ 59 | } 60 | else if (nums[i] === 2) { 61 | temp = nums[i]; 62 | nums[i] = nums[high]; 63 | nums[high] = temp; 64 | high--; 65 | } 66 | else { 67 | i++; 68 | } 69 | } 70 | }; 71 | 72 | // Time Complexity: O(N) 73 | // Space Complexity: O(N) 74 | -------------------------------------------------------------------------------- /problems/leetcode/in place/README.md: -------------------------------------------------------------------------------- 1 | # In Place 2 | 3 | 1. [Sort Colours](./1.sort_colours.js) 4 | -------------------------------------------------------------------------------- /problems/leetcode/linked list/1.reverse_a_linked_list.js: -------------------------------------------------------------------------------- 1 | /* Problem: Reverse a linked list. Do it in-place and in one-pass. 2 | 3 | Example: 4 | 5 | Input: 1->2->3->4->5->NULL 6 | 7 | Output: 5->4->3->2->1->NULL 8 | 9 | */ 10 | 11 | // A - is the HEAD NODE of the linked list 12 | 13 | function reverseLinkedList(A) { 14 | if (!A.next) return A; 15 | 16 | var current = A; // CURRENT NODE as HEAD 17 | var prev = null; // prev node as NULL 18 | var next; 19 | 20 | while (current !== null) { 21 | next = current.next; // Getting the NEXT NODE as reference before reversing 22 | current.next = prev; 23 | prev = current; 24 | current = next; 25 | } 26 | 27 | return prev; 28 | } 29 | 30 | // Time Complexity = O(N) 31 | -------------------------------------------------------------------------------- /problems/leetcode/linked list/2.merge_two_linked_list_without_duplicates.js: -------------------------------------------------------------------------------- 1 | /* Problem: Merge two sorted linked lists and return it as a new list. 2 | 3 | Note: The new list should be made by splicing together the nodes of the first two lists, and should also be sorted. 4 | 5 | Example: 6 | 7 | Input 1: 5 -> 8 -> 20 8 | Input 2: 4 -> 11 -> 15 9 | 10 | Output: 4 -> 5 -> 8 -> 11 -> 15 -> 20 11 | 12 | */ 13 | 14 | // To create a new node; 15 | function Node(data) { 16 | this.data = data 17 | this.next = null 18 | } 19 | 20 | function mergeTwoLinkedList(A, B) { 21 | var list1 = A; 22 | var list2 = B; 23 | var newHead = new Node(-1); // Creating new head 24 | var mergedList = newHead; // Assigning new head to var 25 | 26 | while (list1 !== null || list2 !== null) { 27 | if (list1 == null) { 28 | mergedList.next = list2; 29 | break; 30 | } 31 | else if (list2 == null) { 32 | mergedList.next = list1; 33 | break; 34 | } 35 | 36 | var list1Data = list1.data; 37 | var list2Data = list2.data; 38 | 39 | if (list1Data <= list2Data) { 40 | mergedList.next = new Node(list1Data); 41 | list1 = list1.next; 42 | } 43 | else { 44 | mergedList.next = new Node(list2Data); 45 | list2 = list2.next; 46 | } 47 | 48 | mergedList = mergedList.next; 49 | } 50 | 51 | return newHead.next; // Has the sorted array; 52 | } 53 | 54 | mergeTwoLinkedList({ data: 5, next: { data: 8, next: { data: 20, next: null } } }, { data: 4, next: { data: 11, next: { data: 15, next: null } } }) 55 | 56 | // Ans = { "data": 4, "next": { "data": 5, "next": { "data": 8, "next": { "data": 11, "next": { "data": 15, "next": { "data": 20, "next": null } } } } } } 57 | 58 | // Time Complexity = O(2N) 59 | -------------------------------------------------------------------------------- /problems/leetcode/linked list/3.merge_two_linked_list_with_duplicates.js: -------------------------------------------------------------------------------- 1 | /* Problems: 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. 2 | 3 | Note: Return the duplicates in same order 4 | 5 | Example: 6 | 7 | Input 1: [1, 2, 4]; 8 | Input 2: [1, 3, 4] 9 | 10 | Output: [1, 1, 2, 3, 4, 4]; 11 | 12 | */ 13 | 14 | var mergeTwoLists = function (l1, l2) { 15 | var head = new ListNode(-1); 16 | var mergedNode = head; 17 | 18 | while (l1 !== null || l2 !== null) { 19 | if (l1 == null) { 20 | mergedNode.next = l2; 21 | break; 22 | } 23 | 24 | else if (l2 == null) { 25 | mergedNode.next = l1; 26 | break; 27 | } 28 | 29 | if (l1.val === l2.val) { 30 | mergedNode.next = new ListNode(l1.val); 31 | mergedNode.next.next = new ListNode(l2.val); 32 | l1 = l1.next; 33 | l2 = l2.next; 34 | mergedNode = mergedNode.next.next; 35 | } 36 | else if (l2.val > l1.val) { 37 | 38 | mergedNode.next = new ListNode(l1.val); 39 | l1 = l1.next; 40 | mergedNode = mergedNode.next; 41 | 42 | } 43 | else { 44 | mergedNode.next = new ListNode(l2.val); 45 | l2 = l2.next; 46 | mergedNode = mergedNode.next; 47 | } 48 | 49 | } 50 | 51 | return head.next; 52 | }; 53 | 54 | mergeTwoLists({ data: 1, next: { data: 2, next: { data: 4, next: null } } }, { data: 1, next: { data: 3, next: { data: 4, next: null } } }); 55 | 56 | // Ans = [1, 1, 2, 3, 4, 4]; 57 | 58 | // Time Complexity = O(2N) 59 | -------------------------------------------------------------------------------- /problems/leetcode/linked list/4.find_circular_linked_list.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a linked list, determine if it has a cycle in it. 2 | 3 | Note: Solve it without using extra space 4 | 5 | */ 6 | 7 | // Two Pointers Method 8 | 9 | function isCircular(node) { 10 | if (!node) return false; 11 | if (!node.next) return false; 12 | 13 | var pointer1 = node; 14 | var pointer2 = node.next; 15 | 16 | // If pointer1 and pointer2 are equal, it has a cycle then return true 17 | // else no cycle then return false 18 | while (pointer1 !== pointer2) { 19 | if (pointer2 === null || pointer2.next === null) return false; // Not circular linked list, if next node is null 20 | pointer1 = pointer1.next; 21 | pointer2 = pointer2.next.next; 22 | } 23 | 24 | return true; 25 | } 26 | 27 | var list1 = { val: 1, next: { val: 2, next: { val: 1, next: { val: 2, next: {} } } } }; // Circular list 28 | var list2 = { val: 1, next: { val: 2, next: { val: 3, next: null } } }; // Non Circular List 29 | 30 | isCircular(list1); // True 31 | isCircular(list2); // False 32 | 33 | // Time Complexity: O(N), as we are traversing N nodes 34 | -------------------------------------------------------------------------------- /problems/leetcode/linked list/5.intersection_of_two_inked_lists.js: -------------------------------------------------------------------------------- 1 | /* Problem: Write a program to find the node at which the intersection of two singly linked lists begins. 2 | 3 | Example: 4 | List 1: a1 → a2 5 | ↘ 6 | c1 → c2 → c3 7 | ↗ 8 | List 2: b1 → b2 → b3 9 | 10 | L1, L2 to intersect at node c1. 11 | 12 | Note: 13 | 1. If the two linked lists have no intersection at all, return null. 14 | 2. The linked lists must retain their original structure after the function returns. 15 | 3. You may assume there are no cycles anywhere in the entire linked structure. 16 | 4. Your code should preferably run in O(n) time and use only O(1) memory. 17 | */ 18 | 19 | // To create new list node 20 | function ListNode(val) { 21 | this.val = val; 22 | this.next = null; 23 | } 24 | 25 | var getIntersectionNode = function (headA, headB) { 26 | var haveIntersection = null; 27 | 28 | if (!headA || !headB) return haveIntersection; 29 | 30 | var newHeadA = new ListNode(headA.val); 31 | var newHeadB = new ListNode(headB.val); 32 | newHeadA.next = headA.next; 33 | newHeadB.next = headB.next; 34 | 35 | while (newHeadA != null && newHeadB != null) { 36 | var listAData = newHeadA.val; 37 | var listBData = newHeadB.val; 38 | 39 | if (listAData === listBData) { 40 | haveIntersection = newHeadA; 41 | return haveIntersection; 42 | } else if (listAData < listBData) { 43 | newHeadA = newHeadA.next; 44 | } else if (listAData > listBData) { 45 | newHeadB = newHeadB.next; 46 | } 47 | } 48 | 49 | return haveIntersection; 50 | }; 51 | 52 | var headA = { val: 1, next: { val: 3, next: null } }; 53 | var headB = { val: 2, next: { val: 3, next: null } }; 54 | 55 | getIntersectionNode(headA, headB); // { val: 3, next: null } 56 | 57 | // Time Complexity: O(N) 58 | // Space Complexity: O(1) 59 | 60 | // Solution 2 61 | 62 | var getIntersectionNode = function (headA, headB) { 63 | if (!headA || !headB) { 64 | return null; 65 | } 66 | 67 | var pointer1 = headA; 68 | var pointer2 = headB; 69 | 70 | while (pointer1 != pointer2) { 71 | pointer1 = pointer1.next; 72 | pointer2 = pointer2.next; 73 | 74 | if (pointer1 === pointer2) { 75 | return pointer1; 76 | } 77 | 78 | if (pointer1 === null) { 79 | pointer1 = headB; 80 | } 81 | 82 | if (pointer2 === null) { 83 | pointer2 = headA; 84 | } 85 | } 86 | 87 | return pointer1; 88 | }; 89 | 90 | var headA = { val: 1, next: { val: 3, next: null } }; 91 | var headB = { val: 2, next: { val: 3, next: null } }; 92 | 93 | getIntersectionNode(headA, headB); // { val: 3, next: null } 94 | 95 | // Time Complexity: O(N) 96 | // Space Complexity: O(1) 97 | -------------------------------------------------------------------------------- /problems/leetcode/linked list/6.sort_linked_list.js: -------------------------------------------------------------------------------- 1 | /* Problem: Sort a linked list in O(n log n) time using constant space complexity. 2 | 3 | Note: 4 | 1. See which algorithm can sort in log n times. 5 | 6 | Example: 7 | 8 | Input: 9 | var head = { val: 4, next: { val: 3, next: { val: 5, next: { val: 1, next: null } } } }; 10 | 11 | Output: 12 | { "val": 1, "next": { "val": 3, "next": { "val": 4, "next": { "val": 5, "next": null } } } } 13 | 14 | */ 15 | 16 | // Merge sort but little modified 17 | function mergeSort(l1, l2) { 18 | if (l1 == null) return l2; 19 | if (l2 == null) return l1; 20 | 21 | if (l1.val < l2.val) { 22 | l1.next = mergeSort(l1.next, l2); 23 | return l1; 24 | } 25 | else { 26 | l2.next = mergeSort(l1, l2.next); 27 | return l2; 28 | } 29 | } 30 | 31 | var sortedList = function (head) { 32 | if (head == null) return head; 33 | if (head.next == null) return head; 34 | 35 | var prev = head; 36 | var slow = head; 37 | var fast = head; 38 | 39 | while (fast != null && fast.next != null) { 40 | prev = slow; 41 | slow = slow.next; 42 | fast = fast.next.next; 43 | } 44 | 45 | prev.next = null; 46 | 47 | var l1 = sortedList(head); 48 | var l2 = sortedList(slow); 49 | 50 | return mergeSort(l1, l2); 51 | } 52 | 53 | var head = { val: 4, next: { val: 3, next: { val: 5, next: { val: 1, next: null } } } }; 54 | sortedList(head); 55 | 56 | // Time Complexity: O(N Log N), N Log N for no of nodes in list + merge sort 57 | // Space Complexity: O(Log N), Since we used recursion 58 | -------------------------------------------------------------------------------- /problems/leetcode/linked list/7.remove_val_linked_list.js: -------------------------------------------------------------------------------- 1 | /* Problems: Remove all elements from a linked list of integers that have value val. 2 | 3 | Note: List will have duplicate values too. 4 | 5 | Example: 6 | Input: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val = 6 7 | Output: 1 --> 2 --> 3 --> 4 --> 5 8 | 9 | Tips: Idea here is to create new head with extra node (-1) in front and keep head ahead of new head, then if value found newNode.next = newNode.next.next; 10 | */ 11 | 12 | 13 | var removeElements = function (head, val) { 14 | var current = new ListNode(-1); 15 | current.next = head; 16 | var newNode = current; 17 | 18 | while (head != null) { 19 | if (head.val === val) { 20 | newNode.next = newNode.next.next; 21 | } 22 | else { 23 | newNode = newNode.next; 24 | } 25 | 26 | head = head.next; 27 | } 28 | 29 | return current.next; 30 | }; 31 | 32 | var head = { val: 1, next: { val: 2, next: { val: 6, next: { val: 4, next: { val: 5, next: { val: 6, next: null } } } } } }; 33 | 34 | removeElements(head, 6); // { val: 1, next: { val: 2, next: next: { val: 4, next: { val: 5, next: null } } } }; 35 | 36 | // Time Complexity: O(N) 37 | -------------------------------------------------------------------------------- /problems/leetcode/linked list/8.remove_duplicates.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a sorted linked list, delete all duplicates such that each element appear only once. 2 | 3 | Example 1: 4 | Input: 1->1->2 5 | Output: 1->2 6 | 7 | Example 2: 8 | Input: 1->1->2->3->3 9 | Output: 1->2->3 10 | 11 | */ 12 | 13 | function removeDuplicates = function(head) { 14 | var tempList = head; 15 | 16 | while (tempList && tempList.next) { 17 | if (tempList.val === tempList.next.val) { 18 | tempList = tempList.next.next; 19 | } 20 | else { 21 | tempList = tempList.next; 22 | } 23 | } 24 | 25 | return head; // Head will now only have non-duplicates values 26 | } 27 | 28 | // Time Complexity: O(N) 29 | // Space Complexity: O(1), since we didn't used any additional space 30 | -------------------------------------------------------------------------------- /problems/leetcode/linked list/9.binary_tree_to_linked_list.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a binary tree, flatten it to a linked list in-place. 2 | 3 | For example, given the following tree: 4 | 1 5 | / \ 6 | 2 5 7 | / \ \ 8 | 3 4 6 9 | 10 | The flattened tree should look like: 11 | 12 | 1 13 | \ 14 | 2 15 | \ 16 | 3 17 | \ 18 | 4 19 | \ 20 | 5 21 | \ 22 | 6 23 | 24 | */ 25 | 26 | function TreeNode(val) { 27 | this.val = val; 28 | this.left = this.right = null; 29 | } 30 | 31 | // Solution 1 - Without modifying root 32 | 33 | function flattenBinaryTree(root) { 34 | if (!root) return null; 35 | var newRoot = new TreeNode(-1); 36 | var head = newRoot; 37 | 38 | function traverse(root) { 39 | if (!root) return null; 40 | 41 | head.right = new TreeNode(root.val); 42 | head = head.right; 43 | 44 | traverse(root.left); 45 | traverse(root.right); 46 | } 47 | 48 | traverse(root); 49 | 50 | return newRoot.right; 51 | } 52 | 53 | var root = { 54 | val: 1, 55 | left: { val: 2, left: { val: 3, left: null, right: null }, right: { val: 4, left: null, right: null } }, 56 | right: { val: 5, left: null, right: { val: 6, left: null, right: null } } 57 | }; 58 | 59 | flattenBinaryTree(root); // 1 -> 2 -> 3 -> 4 -> 5 -> 6 60 | 61 | // Time Complexity: O(N) 62 | // Space Complexity: O(N) 63 | 64 | // Solution 2 - modifying root 65 | function flattenBinaryTree(root) { 66 | if (!root) return null; 67 | 68 | function traverse(root) { 69 | if (!root) return null; 70 | 71 | var left = traverse(root.left); 72 | var right = traverse(root.right); 73 | 74 | if (!left) return right ? right : root; 75 | left.right = root.right; 76 | 77 | root.right = root.left; 78 | root.left = null; 79 | 80 | return right ? right : left; 81 | } 82 | 83 | traverse(root); 84 | 85 | return root; 86 | } 87 | 88 | var root = { 89 | val: 1, 90 | left: { val: 2, left: { val: 3, left: null, right: null }, right: { val: 4, left: null, right: null } }, 91 | right: { val: 5, left: null, right: { val: 6, left: null, right: null } } 92 | }; 93 | 94 | flattenBinaryTree(root); // 1 -> 2 -> 3 -> 4 -> 5 -> 6 95 | 96 | // Time Complexity: O(N) 97 | // Space Complexity: O(1) 98 | -------------------------------------------------------------------------------- /problems/leetcode/linked list/README.md: -------------------------------------------------------------------------------- 1 | # Linked List 2 | 3 | 1. [Reverse A Linked List](./1.reverse_a_linked_list.js) 4 | 1. [Merge Two Sorted Linked Lists Without Duplicates](./2.merge_two_linked_list_without_duplicates.js) 5 | 1. [Merge Two Sorted Linked Lists With Duplicates](./3.merge_two_linked_list_with_duplicates.js) 6 | 1. [Find if linked list is circular or not](./4.find_circular_linked_list.js) 7 | 1. [Intersection of two linked list](./5.intersection_of_two_inked_lists.js) 8 | 1. [Sort Linked List](./6.sort_linked_list.js) 9 | 1. [Remove elements in Linked List](./7.remove_val_linked_list.js) 10 | 1. [Remove duplicates in Linked List](./8.remove_duplicates.js) 11 | 1. [Binary Tree to Linked List](./9.binary_tree_to_linked_list.js) 12 | -------------------------------------------------------------------------------- /problems/leetcode/numbers/1.plus_one.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a non-negative integer represented as a non-empty array of digits, plus one to the integer. 2 | 3 | Note 1: You may assume the integer do not contain any leading zero, except the number 0 itself. 4 | Note 2: The digits are stored such that the most significant digit is at the head of the list. 5 | 6 | Example: 7 | Input: [9] 8 | Output: [1, 0] 9 | 10 | */ 11 | 12 | function plusOne(digits) { 13 | for (var i = digits.length - 1; i >= 0; i--) { 14 | if (digits[i] < 9) { 15 | digits[i]++; 16 | return digits; 17 | } 18 | 19 | digits[i] = 0; 20 | } 21 | 22 | digits.unshift(1); 23 | return digits; 24 | } 25 | 26 | plusOne([9]); // [1, 0] 27 | plusOne([6, 1, 4, 5, 3, 9, 0, 1, 9, 5, 1, 8, 6, 7, 0, 5, 5, 4, 3]); // [6, 1, 4, 5, 3, 9, 0, 1, 9, 5, 1, 8, 6, 7, 0, 5, 5, 5] 28 | 29 | // Time Complexity: O(N) 30 | -------------------------------------------------------------------------------- /problems/leetcode/numbers/10.find_original_price.js: -------------------------------------------------------------------------------- 1 | /* Problem: Find the original price of a product before sales discount. 2 | 3 | Example: Given an item at $75 sale price after applying a 25% discount, 4 | the function should return the original price of that item before applying the sale percentage, 5 | which is ($100.00) of course, rounded to two decimal places. 6 | 7 | DiscoverOriginalPrice(75, 25) => 100.00M where 75 is the sale price (discounted price), 25 is the sale percentage and 100 is the original price 8 | 9 | */ 10 | 11 | function findOriginalPrice(priceAfterDiscount, discountPercentage) { 12 | return (priceAfterDiscount / (1 - discountPercentage / 100)).toFixed(2); 13 | } 14 | 15 | findOriginalPrice(75, 25); // 100.00 16 | findOriginalPrice(125, 25); // 166.67 17 | -------------------------------------------------------------------------------- /problems/leetcode/numbers/11.multiple_string.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given two non-negative integers num1 and num2 represented as strings, return the product of num1 and num2, also represented as a string. 2 | 3 | Example 1: 4 | Input: num1 = "2", num2 = "3" 5 | Output: "6" 6 | 7 | Example 2: 8 | Input: num1 = "123", num2 = "456" 9 | Output: "56088" 10 | 11 | Note: 12 | 1. The length of both num1 and num2 is < 110. 13 | 2. Both num1 and num2 contain only digits 0-9. 14 | 3. Both num1 and num2 do not contain any leading zero, except the number 0 itself. 15 | 4. You must not use any built-in BigInteger library or convert the inputs to integer directly. 16 | 17 | */ 18 | 19 | function multiplyStrings(str1, str2) { 20 | var resultArr = Array(str1.length + str2.length).fill(0); 21 | 22 | for (var i = str1.length - 1; i >= 0; i--) { 23 | for (var j = str2.length - 1; j >= 0; j--) { 24 | var multi = str1[i] * str2[j] + resultArr[i + j + 1]; 25 | resultArr[i + j] += Math.floor(multi / 10); 26 | resultArr[i + j + 1] = multi % 10; 27 | } 28 | } 29 | 30 | return resultArr 31 | .join("") 32 | .replace(/^0+(?!$)/, "") // to remove all leading 0 except last char in string 33 | .toString(); 34 | } 35 | 36 | multiplyStrings("2", "3"); 37 | 38 | // Time Complexity: O(N * M), N is string one length and M is string two length 39 | // Space Complexity: O(NLen + MLen) 40 | -------------------------------------------------------------------------------- /problems/leetcode/numbers/12.valid_ip.js: -------------------------------------------------------------------------------- 1 | /* Problem: Write an algorithm that will identify valid IPv4 addresses in dot-decimal format. IPs should be considered valid if they consist of four octets, with values between 0 and 255, inclusive. 2 | 3 | Note: Input to the function is guaranteed to be a single string. 4 | 5 | Examples: 6 | Valid inputs: 7 | 1.2.3.4 8 | 123.45.67.89 9 | 10 | Invalid inputs: 11 | 1.2.3 12 | 1.2.3.4.5 13 | 123.456.78.90 14 | 123.045.067.089 15 | 16 | Note: leading zeros (e.g. 01.02.03.04) are considered invalid. 17 | 18 | */ 19 | 20 | function isValidIP(str) { 21 | if (!str) return false; 22 | 23 | var strArr = str.split("."); 24 | 25 | return strArr.length === 4 && strArr.every(strItem => String(Number(strItem)) === strItem && strItem >= 0 && strItem <= 255); 26 | } 27 | 28 | // Time Complexity: O(N), N is length of IP which is 4 29 | // Space Complexity: O(N) 30 | -------------------------------------------------------------------------------- /problems/leetcode/numbers/2.integer_replacement.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a positive integer n and you can do operations as follow: 2 | 3 | 1. If n is even, replace n with n/2. 4 | 2. If n is odd, you can replace n with either n + 1 or n - 1. 5 | 6 | Example 1: 7 | Input: 8 8 | Output: 3 9 | Explanation: 8 -> 4 -> 2 -> 1 10 | 11 | Example 2: 12 | Input: 7 13 | Output: 4 14 | Explanation: 7 -> 8 -> 4 -> 2 -> 1 (or) 7 -> 6 -> 3 -> 2 -> 1 15 | */ 16 | 17 | // Using recursion with O(1) extra space 18 | 19 | var integerReplacement = function (n) { 20 | if (n === 0) return 1; 21 | else if (n === 1) return 0; 22 | 23 | var getMinCount = function (n, count) { 24 | if (n === 1) { 25 | return count; 26 | } 27 | else if (n % 2 === 0) { 28 | n = n / 2; 29 | return getMinCount(n, count + 1); 30 | } 31 | else { 32 | return Math.min(getMinCount(n + 1, count + 1), getMinCount(n - 1, count + 1)); 33 | } 34 | } 35 | 36 | return getMinCount(n, 0); 37 | }; 38 | 39 | integerReplacement(8); // 3 40 | integerReplacement(992); // 11 41 | integerReplacement(993); // 12 42 | integerReplacement(1234); // 14 43 | 44 | // Using recursion without O(1) extra space 45 | 46 | var integerReplacement = function (n) { 47 | if (n === 0) return 1; 48 | else if (n === 1) return 0; 49 | 50 | var getMinCount = function (n) { 51 | if (n === 1) { 52 | return 0; 53 | } 54 | else if (n % 2 === 0) { 55 | n = n / 2; 56 | return 1 + getMinCount(n); 57 | } 58 | else { 59 | return 1 + Math.min(getMinCount(n + 1), getMinCount(n - 1)); 60 | } 61 | } 62 | 63 | return getMinCount(n); 64 | }; 65 | 66 | integerReplacement(8); // 3 67 | integerReplacement(992); // 11 68 | integerReplacement(993); // 12 69 | integerReplacement(1234); // 14 70 | -------------------------------------------------------------------------------- /problems/leetcode/numbers/3.majority_elements.js: -------------------------------------------------------------------------------- 1 | /* Problem: 2 | 3 | Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times. 4 | 5 | Note: You may assume that the array is non-empty and the majority element always exist in the array. 6 | 7 | Example 1: 8 | Input: [3,2,3] 9 | Output: 3 10 | Example 2: 11 | 12 | Example: 2 13 | Input: [2,2,1,1,1,2,2] 14 | Output: 2 15 | 16 | */ 17 | 18 | // Solution 1 - Hashmap 19 | var majorityElement = function(nums) { 20 | var len = nums.length; 21 | var hash = {}; 22 | var sum = 0; 23 | 24 | for (var i = 0; i < len; i++) { 25 | if (!hash[nums[i]]) { 26 | hash[nums[i]] = 1; 27 | } else { 28 | hash[nums[i]] += 1; 29 | } 30 | } 31 | 32 | for (var i in hash) { 33 | if (hash[i] > Math.floor(len / 2)) { 34 | sum = i; 35 | } 36 | } 37 | return sum; 38 | }; 39 | 40 | majorityElement([3, 3, 4]); // 2 41 | 42 | // Time Complexity: O(n) 43 | // Space complexity : O(n), As we are storing atmost (n - n/2) times in the Hashmap 44 | -------------------------------------------------------------------------------- /problems/leetcode/numbers/4.power_of_3.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given an integer, write a function to determine if it is a power of three. 2 | 3 | Example 1: 4 | Input: 27 5 | Output: true 6 | Example 2: 7 | 8 | Input: 0 9 | Output: false 10 | Example 3: 11 | 12 | Input: 9 13 | Output: true 14 | Example 4: 15 | 16 | Input: 45 17 | Output: false 18 | 19 | Follow up: 20 | - Could you do it without using any loop / recursion? 21 | 22 | Questions: 23 | - Will I get negative numbers as well ? 24 | */ 25 | 26 | 27 | // Solution 1 - Use ForLoop & Math.pow() 28 | 29 | var isPowerOfThree = function(n) { 30 | if (n == 0 || n < 0) return false; 31 | else if (n == 1) return true; 32 | 33 | for (var i = 1; i < n; i++) { 34 | if (n % 3 === 0 && Math.pow(3, i) === n) return true; 35 | else if (Math.pow(3, i) > n ) return false; 36 | } 37 | }; 38 | 39 | isPowerOfThree(9); // True 40 | isPowerOfThree(-9); // false 41 | 42 | // Time Complexity: O(N) 43 | 44 | // Solution 2 - Recurrsion 45 | var isPowerOfThree = function(n) { 46 | if (n == 0 || n < 0) return false; 47 | else { 48 | while (n % 3 === 0) { 49 | n /= 3; 50 | } 51 | 52 | return n === 1; 53 | } 54 | } 55 | 56 | isPowerOfThree(9); // True 57 | isPowerOfThree(-9); // false 58 | 59 | // Time Complexity: O(n) 60 | -------------------------------------------------------------------------------- /problems/leetcode/numbers/5.count_primes.js: -------------------------------------------------------------------------------- 1 | /* Problem: Count the number of prime numbers less than a non-negative number, n. 2 | 3 | Example: 4 | Input: 10 5 | Output: 4 6 | 7 | Explanation: There are 4 prime numbers less than 10, they are 2, 3, 5, 7. 8 | 9 | Input: 5 10 | Output: 2 11 | 12 | Explanation: There are 2 prime numbers less than 5, they are 2, 3, 13 | 14 | */ 15 | 16 | function countPrimes(num) { 17 | if (num < 2) return 0; 18 | var count = 0; 19 | 20 | function isPrime(n) { 21 | for (var i = 2; i <= Math.floor(Math.sqrt(n)); i++) { 22 | if (n % i === 0) return false; 23 | } 24 | 25 | return true; 26 | } 27 | 28 | for (var i = 2; i < num; i++) { 29 | if (isPrime(i)) count++; 30 | } 31 | 32 | return count; 33 | } 34 | 35 | countPrimes(10); // 4 36 | 37 | // Time Complexity - O(N2) 38 | -------------------------------------------------------------------------------- /problems/leetcode/numbers/6.string_to_integer.js: -------------------------------------------------------------------------------- 1 | /* Problem: Implement atoi which converts a string to an integer. 2 | 3 | - The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. 4 | Then, starting from this character, takes an optional initial plus or minus sign followed by as many numerical digits as possible, and 5 | interprets them as a numerical value. 6 | 7 | - The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function. 8 | 9 | - If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or 10 | it contains only whitespace characters, no conversion is performed. 11 | 12 | - If no valid conversion could be performed, a zero value is returned. 13 | 14 | Note: 15 | - Only the space character ' ' is considered as whitespace character. 16 | - Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−231, 231 − 1]. 17 | If the numerical value is out of the range of representable values, INT_MAX (231 − 1) or INT_MIN (−231) is returned. 18 | 19 | Example 1: 20 | Input: "42" 21 | Output: 42 22 | 23 | Example 2: 24 | Input: " -42" 25 | Output: -42 26 | Explanation: The first non-whitespace character is '-', which is the minus sign. Then take as many numerical digits as possible, which gets 42. 27 | 28 | Example 3: 29 | Input: "4193 with words" 30 | Output: 4193 31 | Explanation: Conversion stops at digit '3' as the next character is not a numerical digit. 32 | 33 | Example 4: 34 | Input: "words and 987" 35 | Output: 0 36 | Explanation: The first non-whitespace character is 'w', which is not a numerical digit or a +/- sign. Therefore no valid conversion could be performed. 37 | 38 | Example 5: 39 | Input: "-91283472332" 40 | Output: -2147483648 41 | Explanation: The number "-91283472332" is out of the range of a 32-bit signed integer. Thefore INT_MIN (−231) is returned. 42 | 43 | */ 44 | 45 | function stringToInteger(str) { 46 | var trimmedStr = str.replace(/\s/g, ''); // or use .trim() 47 | 48 | if ((trimmedStr.charAt(0) === '-' || trimmedStr.charAt(0) === '+') && (trimmedStr.charAt(1) === '-' || trimmedStr.charAt(1) === '+')) { 49 | return 0; 50 | } 51 | 52 | function getAns(str) { 53 | var parseStr = parseInt(str); // parseInt() method will omit all strings, return only number if its has or else NaN 54 | 55 | if (isNaN(parseStr)) return 0; 56 | else if (parseStr >= Math.pow(2, 31)) { 57 | return Math.pow(2, 31); 58 | } else if (parseStr <= Math.pow(-2, 31)) { 59 | return Math.pow(-2, 31); 60 | } else { 61 | return parseStr; 62 | } 63 | } 64 | 65 | return getAns(trimmedStr); 66 | } 67 | 68 | stringToInteger('-42'); // -42 69 | stringToInteger(' -42'); // -42 70 | stringToInteger('4193 with words'); // 4193 71 | stringToInteger('words and 987'); // 0 72 | stringToInteger(' -0012a42'); // -12 73 | stringToInteger('-91283472332'); // -2147483648 74 | 75 | // Time Complexity: O(N) 76 | -------------------------------------------------------------------------------- /problems/leetcode/numbers/7.happy_numbers.js: -------------------------------------------------------------------------------- 1 | /* Problem: Happy Number 2 | 3 | Write an algorithm to determine if a number is "happy". 4 | 5 | A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers. 6 | 7 | Example: 8 | Input: 19 9 | Output: true 10 | Explanation: 11 | 12 + 92 = 82 12 | 82 + 22 = 68 13 | 62 + 82 = 100 14 | 12 + 02 + 02 = 1 15 | 16 | */ 17 | 18 | // Solution 1: Using Hashmap 19 | 20 | var isHappyNumber = function(num) { 21 | var hashMap = {}; 22 | 23 | while (num != 1 && !hashMap[num]) { 24 | hashMap[num] = num; 25 | num = num.toString().split('').reduce((sum, n) => sum + Math.pow(n, 2), 0); 26 | } 27 | 28 | return num == 1; 29 | }; 30 | 31 | isHappyNumber(19); // True 32 | isHappyNumber(10); // True 33 | isHappyNumber(11); // False 34 | 35 | // Time Complexity: O(N K), assuming while loop executes N times and K denotes counts of digits in number 36 | // Space Complexity: O(K), K denotes counts of digits in number 37 | 38 | // Solution 2: Using Linked List and Finding a loop in it 39 | -------------------------------------------------------------------------------- /problems/leetcode/numbers/8.find_disappearing_numbers.js: -------------------------------------------------------------------------------- 1 | /* Problem: Find All Numbers Disappeared in an Array 2 | 3 | Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once. 4 | 5 | Find all the elements of [1, n] inclusive that do not appear in this array. 6 | 7 | Note: 8 | - Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space. 9 | 10 | Example: 11 | 12 | Input: [4,3,2,7,8,2,3,1] 13 | 14 | Output: [5,6] 15 | 16 | */ 17 | 18 | var findDisappearedNumbers = function(nums) { 19 | var arr = []; 20 | 21 | for (var i = 0; i < nums.length; i++) { 22 | arr[nums[i]] = true; 23 | } 24 | 25 | for (var i = 0; i < nums.length; i++) { 26 | if (arr[i + 1]) { 27 | arr[i + 1] = false; 28 | } else arr[i + 1] = i + 1; 29 | } 30 | 31 | arr = arr.filter((num, index) => (num ? index : null)); 32 | 33 | return arr; 34 | }; 35 | 36 | findDisappearedNumbers([4, 3, 2, 7, 8, 2, 3, 1]); // [5, 6] 37 | 38 | // Time Complexity: O(N) 39 | // Space Complexity: O(N) 40 | -------------------------------------------------------------------------------- /problems/leetcode/numbers/9.self_dividing_numbers.js: -------------------------------------------------------------------------------- 1 | /* Problem: A self-dividing number is a number that is divisible by every digit it contains. 2 | 3 | For example, 128 is a self-dividing number because 128 % 1 == 0, 128 % 2 == 0, and 128 % 8 == 0. 4 | Also, a self-dividing number is not allowed to contain the digit zero. 5 | Given a lower and upper number bound, output a list of every possible self dividing number, including the bounds if possible. 6 | 7 | Example 1: 8 | Input: 9 | left = 1, right = 22 10 | Output: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 15, 22] 11 | 12 | Note: The boundaries of each input argument are 1 <= left <= right <= 10000. 13 | 14 | */ 15 | 16 | var selfDividingNumbers = function(left, right) { 17 | var result = []; 18 | for (var i = left; i <= right; i++) { 19 | if (i < 10) { 20 | result.push(i); 21 | } 22 | 23 | if (i > 9) { 24 | var strNum = i.toString(); 25 | for (var j = 0; j < strNum.length; j++) { 26 | if (i % strNum[j] !== 0) { 27 | break; 28 | } 29 | } 30 | 31 | if (j === strNum.length) { 32 | result.push(i); 33 | } 34 | } 35 | } 36 | 37 | return result; 38 | }; 39 | 40 | selfDividingNumbers(1, 22); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 15, 22] 41 | 42 | // Time Complexity 43 | // O(N*M), N is all numbers and M is digits in the numbers 44 | 45 | // Space Complexity 46 | // O(N) length of result 47 | -------------------------------------------------------------------------------- /problems/leetcode/numbers/README.md: -------------------------------------------------------------------------------- 1 | # Numbers 2 | 3 | 1. [Plus One](./1.plus_one.js) 4 | 1. [Integer Replacement](./2.integer_replacement.js) 5 | 1. [Majority Elements](./3.majority_elements.js) 6 | 1. [Power of 3](./4.power_of_3.js) 7 | 1. [Count Primes](./5.count_primes.js) 8 | 1. [String To Number](./6.string_to_integer.js) 9 | 1. [Happy Number](./7.happy_numbers.js) 10 | 1. [Find Disappeared in an Array](./8.find_disappearing_numbers.js) 11 | 1. [Self Dividing Numbers](./9.self_dividing_numbers.js) 12 | 1. [Find original price](./10.find_original_price.js) 13 | 1. [Multiply Strings](./11.multiple_string.js) 14 | 1. [Valid IP Address](./12.valid_ip.js) 15 | -------------------------------------------------------------------------------- /problems/leetcode/one pass/1.max_profit.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a array of numbers representing the stock prices of a company in chronological order, 2 | write a function that calculates the maximum profit you could have made from buying and selling that stock once. 3 | You must buy before you can sell it. 4 | 5 | 6 | Example: 7 | Input: [9, 11, 8, 5, 7, 10] 8 | Output: 5 9 | 10 | Explanation: min buy is 5 and max sell is 10 so profit is 5 11 | 12 | Input: [7,6,4,3,1] 13 | Output: 0 14 | 15 | Explanation: No profit 16 | 17 | */ 18 | 19 | // Solution 1: Using double iteration 20 | function maxProfit(arr) { 21 | var maxProfit = 0; 22 | 23 | if (arr.length === 0) { 24 | return maxProfit; 25 | } 26 | 27 | var i = 0; 28 | 29 | while (i < arr.length) { 30 | var j = i + 1; 31 | while (j < arr.length) { 32 | var diff = arr[j] - arr[i]; 33 | if (diff > maxProfit) { 34 | maxProfit = diff; 35 | } 36 | 37 | j++; 38 | } 39 | 40 | i++; 41 | } 42 | 43 | return maxProfit; 44 | } 45 | 46 | maxProfit([9, 11, 8, 5, 7, 10]); // 5 47 | maxProfit([14, 13, 12, 11]); // 0 48 | 49 | // Time Complexity: O(N * N - 1 / 2) 50 | // Space Complexity: O(1) 51 | 52 | // Solution 2: One pass 53 | function maxProfit(arr) { 54 | var minBuy = Infinity; 55 | var maxProfit = 0; 56 | var i = 0; 57 | 58 | if (arr.length === 0) { 59 | return profit; 60 | } 61 | 62 | while (i < arr.length) { 63 | if (arr[i] < minBuy) { 64 | minBuy = arr[i]; 65 | } else if (arr[i] - minBuy > maxProfit) { 66 | maxProfit = arr[i] - minBuy; 67 | } 68 | 69 | i++; 70 | } 71 | 72 | return maxProfit; 73 | } 74 | 75 | maxProfit([9, 11, 8, 5, 7, 10]); // 5 76 | maxProfit([14, 13, 12, 11]); // 0 77 | 78 | // Time Complexity: O(N) 79 | // Space Complexity: O(1) 80 | -------------------------------------------------------------------------------- /problems/leetcode/one pass/README.md: -------------------------------------------------------------------------------- 1 | # One Pass 2 | 3 | 1. [Max profit of stock](./1.max_profit.js) 4 | -------------------------------------------------------------------------------- /problems/leetcode/recursion/1.frog_jump.js: -------------------------------------------------------------------------------- 1 | /* Problems: 2 | 3 | Find number of ways a frog can jump (1 feet jump or 2 feet jump) to make it across the river. 4 | 5 | Note: 6 | 1. Frog can either make 2 feet jump or 1 feet jump. 7 | 2. Frog cannot go in reverse. 8 | 9 | Example 1: 10 | Input: 3 Feet long river 11 | Output: 3 Ways 12 | 13 | Explantion: 14 | 15 | Combination 1 = 1 feet + 1 feet + feet 16 | Combination 2 = 1 feet + 2 feet 17 | Combination 1 = 2 feet + 1 feet 18 | 19 | Example 2: 20 | Input: 11 Feet long river 21 | Output: 144 Ways 22 | 23 | */ 24 | 25 | // Solution 1 - recursion 26 | function jumpFrog(totalFeet) { 27 | function jumps(feet) { 28 | if (feet === totalFeet) return 1; 29 | if (feet > totalFeet) return 0; 30 | return jumps(feet + 1) + jumps(feet + 2) 31 | } 32 | 33 | return jumps(0); 34 | } 35 | 36 | 37 | jumpFrog(3); // 3 38 | jumpFrog(11); // 144 39 | 40 | // Time Complexity: O(2^N ) 41 | 42 | 43 | // Solution 2 - recursion with memoization 44 | function jumpFrog(totalFeet) { 45 | function jumps(feet, hash) { 46 | if (hash[feet]) { 47 | return hash[feet]; 48 | } 49 | if (feet === totalFeet) return 1; 50 | if (feet > totalFeet) return 0; 51 | var result = jumps(feet + 1, hash) + jumps(feet + 2, hash) 52 | hash[feet] = result; 53 | return result; 54 | } 55 | return jumps(0, {}); 56 | } 57 | 58 | // Time Complexity: O(N) 59 | -------------------------------------------------------------------------------- /problems/leetcode/recursion/README.md: -------------------------------------------------------------------------------- 1 | # Recursion 2 | 3 | 1. [Frog Jump](./1.frog_jump.js) 4 | -------------------------------------------------------------------------------- /problems/leetcode/search/1.count_element_occurence.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a sorted array of integers, find the number of occurrences of a given target value. 2 | 3 | Hint: Your algorithm’s runtime complexity must be in the order of O(log n). If the target is not found in the array, return 0. 4 | 5 | Example: 6 | 7 | Input: [5, 7, 7, 8, 8, 10] and target value 8 8 | 9 | Output: 2 10 | 11 | */ 12 | 13 | function elementOccurence(arr, target) { 14 | if (arr.length === 0) return 0; 15 | 16 | var firstIndex = -1; 17 | var lastIndex = -1; 18 | var count = 0; 19 | var mid = Math.floor(arr.length / 2); 20 | 21 | while (mid < arr.length) { 22 | if (arr[mid] == target) { 23 | firstIndex = mid - 1; 24 | lastIndex = mid + 1; 25 | count++; 26 | break; 27 | } else if (arr[mid] > target) { 28 | mid--; 29 | } else mid++; 30 | } 31 | 32 | while (firstIndex > -1) { 33 | if (arr[firstIndex] === target) { 34 | count++; 35 | firstIndex--; 36 | } else break; 37 | } 38 | 39 | while (lastIndex < arr.length) { 40 | if (arr[lastIndex] === target) { 41 | count++; 42 | lastIndex++; 43 | } else break; 44 | } 45 | 46 | return count; 47 | } 48 | 49 | elementOccurence([5, 7, 7, 8, 8, 10], 8); // 2 50 | 51 | // Complexity: Time Complexity: O(LOG N) 52 | // Space: O(1) 53 | -------------------------------------------------------------------------------- /problems/leetcode/search/2.search_insert_position.js: -------------------------------------------------------------------------------- 1 | /* Problem: 2 | Given a sorted array and a target value, return the index if the target is found. 3 | If not, return the index where it would be if it were inserted in order. 4 | 5 | Example 1: 6 | Input: [1,3,5,6], 5 7 | Output: 2 8 | 9 | Example 2: 10 | Input: [1,3,5,6], 2 11 | Output: 1 12 | 13 | Example 3: 14 | Input: [1,3,5,6], 7 15 | Output: 4 16 | 17 | Reference: https://leetcode.com/problems/search-insert-position/description/ 18 | */ 19 | 20 | // Solution 1 - Raw version 21 | 22 | var searchInsert = function(arr, target) { 23 | if (arr.length === 0) return -1; 24 | for (var i = 0; i < arr.length; i++) { 25 | if (target < arr[i]) return i; 26 | if (arr[i] === target) return i; 27 | else if (target > arr[i] && target < arr[i + 1]) return i + 1; 28 | else if (target > arr[i] && i === arr.length - 1) return i + 1; 29 | } 30 | }; 31 | 32 | searchInsert([1, 3, 5, 6], 5); // 2 33 | searchInsert([1, 3, 5, 6], 7); // 4 34 | 35 | // Time Complexity: O(N) 36 | 37 | // Solution 2 - Code optimized 38 | 39 | var searchInsert = function(arr, target) { 40 | if (arr.length === 0) return -1; 41 | for (var i = 0; i < arr.length; i++) { 42 | if (arr[i] >= target) return i; 43 | } 44 | return arr.length; 45 | }; 46 | 47 | searchInsert([1, 3, 5, 6], 5); // 2 48 | searchInsert([1, 3, 5, 6], 7); // 4 49 | 50 | // Time Complexity: O(N) 51 | 52 | // Solution 3 - Binary Search 53 | 54 | var searchInsert = function(arr, target) { 55 | if (arr.length === 0) return -1; 56 | var left = 0; 57 | var right = arr.length - 1; 58 | 59 | while (left <= right) { 60 | var mid = Math.floor(left + right / 2); 61 | if (arr[mid] === target) return mid; 62 | else if (arr[mid] < target) { 63 | left = mid + 1; 64 | } else { 65 | left = mid - 1; 66 | } 67 | } 68 | return left; 69 | }; 70 | 71 | searchInsert([1, 3, 5, 6], 5); // 2 72 | searchInsert([1, 3, 5, 6], 7); // 4 73 | 74 | // Time Complexity: O(Log N) 75 | -------------------------------------------------------------------------------- /problems/leetcode/search/3.trailing_factorial_zeros.js: -------------------------------------------------------------------------------- 1 | /* Given an integer n, return the number of trailing zeroes in n!. 2 | 3 | Example 1: 4 | Input: 3 5 | Output: 0 6 | Explanation: 3! = 6, no trailing zero. 7 | Example 2: 8 | 9 | Example: 2 10 | Input: 5 11 | Output: 1 12 | Explanation: 5! = 120, one trailing zero. 13 | 14 | Note: Your solution should be in logarithmic time complexity. 15 | */ 16 | 17 | // Solution 1 18 | var trailingZeroes = function(n) { 19 | var getFactorial = function(n) { 20 | if (n === 0) return 1; 21 | return n * getFactorial(n-1); 22 | } 23 | 24 | var count = 0; 25 | 26 | if (n < 5) return count; 27 | if (n <= 7) return 1; 28 | 29 | var num = getFactorial(n); 30 | 31 | num = num.toString().split(''); 32 | 33 | for (var i = num.length - 1; i > 0; i--) { 34 | if (num[i] > 0) break; 35 | else count++; 36 | } 37 | 38 | return count; 39 | }; 40 | 41 | trailingZeroes(7); // 5040 - Ans 1 42 | 43 | // Time Complexity: O(N^2) 44 | 45 | // Solution 2 46 | // Using 5 to get the trailing zeros 47 | // After 4 only, trailing zero start. So lets count how many 5's are in n 48 | // with this we can get our trailing zeros 49 | 50 | var trailingZeroes = function(n) { 51 | if (n < 5) return 0; 52 | if (n <= 9) return 1; 53 | var count = 0; 54 | while (n >= 5) { 55 | n = parseInt(n/5); 56 | count += parseInt(n); 57 | } 58 | return count; 59 | }; 60 | 61 | // Time Complexity: O(Log N) 62 | -------------------------------------------------------------------------------- /problems/leetcode/search/README.md: -------------------------------------------------------------------------------- 1 | # Search 2 | 3 | 1. [Count Element Occurrence](./1.count_element_occurence.js) 4 | 1. [Search Insert Position](./2.search_insert_position.js) 5 | 1. [Trailing Factorial Zeros](./3.trailing_factorial_zeros.js) 6 | -------------------------------------------------------------------------------- /problems/leetcode/stack and queue/1.evaluate_reverse_polish_notation.js: -------------------------------------------------------------------------------- 1 | /* Problem: Evaluate the value of an arithmetic expression in Reverse Polish Notation. 2 | 3 | Note: Valid operators are +, -, *, /. Each operand may be an integer or another expression. 4 | 5 | Examples: 6 | 7 | Input 1: ["2", "1", "+", "3", "*"] 8 | Output 1: 9 9 | Explanation: ((2 + 1) * 3) 10 | 11 | Input 2: ["4", "13", "5", "/", "+"] 12 | Output 2: 6 13 | Explanation: (4 + (13 / 5)) 14 | 15 | Tips: 16 | - When ever evaluating expression comes, one of the way to solve is to use stack implementation 17 | */ 18 | 19 | var evalRPN = function(tokens) { 20 | if (tokens.length === 1) return parseInt(tokens[0]); 21 | var arr = []; 22 | for (var i = 0; i < tokens.length; i++) { 23 | var temp = tokens[i]; 24 | if (temp == "+") { 25 | arr.push(arr.pop() + arr.pop()); 26 | } else if (temp == "-") { 27 | var val1 = arr.pop(); 28 | var val2 = arr.pop(); 29 | arr.push(val2 - val1); 30 | } else if (temp == "/") { 31 | var val1 = arr.pop(); 32 | var val2 = arr.pop(); 33 | arr.push((val2 / val1) | 0); 34 | } else if (temp == "*") { 35 | arr.push(arr.pop() * arr.pop()); 36 | } else { 37 | arr.push(parseInt(temp)); 38 | } 39 | } 40 | 41 | return arr[0]; 42 | }; 43 | 44 | evalRPN(["2", "1", "+", "3", "*"]); // 9 45 | 46 | // Time Complexity: O(N) 47 | -------------------------------------------------------------------------------- /problems/leetcode/stack and queue/2.min_stack.js: -------------------------------------------------------------------------------- 1 | /* Problem: 2 | 3 | Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. 4 | 5 | push(x) -- Push element x onto stack. 6 | pop() -- Removes the element on top of the stack. 7 | top() -- Get the top element. 8 | getMin() -- Retrieve the minimum element in the stack. 9 | 10 | Note: retrieving the minimum element in constant time. 11 | */ 12 | 13 | // Solution 1 14 | 15 | var MinStack = function() { 16 | this.arr = []; 17 | }; 18 | 19 | MinStack.prototype.push = function(x) { 20 | this.arr.push(x); 21 | }; 22 | 23 | MinStack.prototype.pop = function() { 24 | this.arr.pop(); 25 | }; 26 | 27 | MinStack.prototype.top = function() { 28 | return this.arr[this.arr.length - 1]; 29 | }; 30 | 31 | MinStack.prototype.getMin = function() { 32 | return Math.min.apply(null, this.arr); 33 | }; 34 | 35 | var minStack = new MinStack(); 36 | 37 | minStack.push(1); // [1] 38 | minStack.push(2); // [1, 2] 39 | minStack.push(-1); // [1, 2, -1] 40 | minStack.push(0); // [1, 2, -1, 0] 41 | minStack.pop(); // 0 42 | minStack.getMin(); // -1 43 | minStack.pop(); // -1 44 | minStack.getMin(); // 1 45 | 46 | // Time Complexity of getMin - O(N) 47 | 48 | // Solution 2 - WIP 49 | -------------------------------------------------------------------------------- /problems/leetcode/stack and queue/3.valid_parentheses.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. 2 | 3 | An input string is valid if: 4 | - Open brackets must be closed by the same type of brackets. 5 | - Open brackets must be closed in the correct order. 6 | - Note that an empty string is also considered valid. 7 | 8 | Example 1: 9 | 10 | Input: "()" 11 | Output: true 12 | 13 | Example 2: 14 | Input: "()[]{}" 15 | Output: true 16 | 17 | Example 3: 18 | Input: "(]" 19 | Output: false 20 | 21 | Example 4: 22 | Input: "([)]" 23 | Output: false 24 | 25 | Example 5: 26 | Input: "{[]}" 27 | Output: true 28 | */ 29 | 30 | // Solution 1 - Using Stack 31 | 32 | function isValidParentheses(str) { 33 | if (str === "") return true; // Empty string 34 | var stack = []; 35 | var parenthesesMap = { 36 | "(": ")", 37 | "{": "}", 38 | "[": "]" 39 | }; 40 | 41 | for (var i = 0; i < str.length; i++) { 42 | var char = str[i]; 43 | var stackTop = stack[stack.length - 1]; 44 | if (char === parenthesesMap[stackTop]) { 45 | stack.pop(); 46 | } else { 47 | stack.push(char); 48 | } 49 | } 50 | 51 | return stack.length === 0; // If 0, then given str is valid 52 | } 53 | 54 | isValidParentheses("([[]])"); // True 55 | isValidParentheses("({[[]])"); // False 56 | isValidParentheses("({[]})"); // True 57 | 58 | // Time Complexity: O(N) 59 | // Space Complexity: O(N) 60 | -------------------------------------------------------------------------------- /problems/leetcode/stack and queue/4.daily_temperature.js: -------------------------------------------------------------------------------- 1 | /* Problem: 2 | Given a list of daily temperatures T, return a list such that, for each day in the input, tells you how many days you would have to wait until a warmer temperature. 3 | If there is no future day for which this is possible, put 0 instead. 4 | 5 | Example: 6 | 1. given the list of temperatures T = [73, 74, 75, 71, 69, 72, 76, 73], your output should be [1, 1, 4, 2, 1, 1, 0, 0]. 7 | 8 | Note: The length of temperatures will be in the range [1, 30000]. Each temperature will be an integer in the range [30, 100]. 9 | */ 10 | 11 | var dailyTemperatures = function(T) { 12 | var stack = []; 13 | var arr = []; 14 | 15 | for (var i = T.length - 1; i >= 0; i--) { 16 | while (stack.length && T[i] >= T[stack[stack.length - 1]]) { 17 | stack.pop(); 18 | } 19 | 20 | if (stack.length) { 21 | arr.push(stack[stack.length - 1] - i); 22 | } else { 23 | arr.push(0); 24 | } 25 | 26 | stack.push(i); 27 | } 28 | 29 | return arr.reverse(); 30 | }; 31 | 32 | dailyTemperatures([73, 74, 75, 71, 69, 72, 76, 73]); // [1, 1, 4, 2, 1, 1, 0, 0] 33 | 34 | // Time Complexity: O(N) 35 | // Space Complexity: O(W), W is number allowed values for T[i] 36 | -------------------------------------------------------------------------------- /problems/leetcode/stack and queue/5.push_dominoes.js: -------------------------------------------------------------------------------- 1 | /* Problem: Push Dominoes 2 | 3 | There are N dominoes in a line, and we place each domino vertically upright. 4 | 5 | In the beginning, we simultaneously push some of the dominoes either to the left or to the right. 6 | 7 | - After each second, each domino that is falling to the left pushes the adjacent domino on the left. 8 | 9 | - Similarly, the dominoes falling to the right push their adjacent dominoes standing on the right. 10 | 11 | - When a vertical domino has dominoes falling on it from both sides, it stays still due to the balance of the forces. 12 | 13 | - For the purposes of this question, we will consider that a falling domino expends no additional force to a falling or already fallen domino. 14 | 15 | Given a string "S" representing the initial state. S[i] = 'L', if the i-th domino has been pushed to the left; S[i] = 'R', if the i-th domino has been pushed to the right; S[i] = '.', if the i-th domino has not been pushed. 16 | Return a string representing the final state. 17 | 18 | Eg: 19 | 20 | Example 1: 21 | Input: ".L.R...LR..L.." 22 | Output: "LL.RR.LLRRLL.." 23 | 24 | Example 2: 25 | Input: "RR.L" 26 | Output: "RR.L" 27 | 28 | Explanation: The first domino expends no additional force on the second domino. 29 | 30 | Note: 31 | 0 <= N <= 10^5 32 | String dominoes contains only 'L', 'R' and '.' 33 | 34 | 35 | Reference: https://leetcode.com/problems/push-dominoes/ 36 | 37 | */ 38 | 39 | // Solution - Using Stack 40 | 41 | var pushDominoes = function(dominoes) { 42 | var stack = []; 43 | var str = dominoes.split(''); 44 | 45 | for (var i = 0; i < str.length; i++) { 46 | var char = str[i]; 47 | 48 | if (char === 'L') { 49 | if (stack.length) { 50 | var left = stack.pop() + 1; 51 | var right = i - 1; 52 | 53 | while (left < right && (str[left] === '.' || str[right] === '.')) { 54 | if (str[left] === '.') { 55 | str[left] = 'R'; 56 | left++; 57 | } 58 | 59 | if (str[right] === '.') { 60 | str[right] = 'L'; 61 | right--; 62 | } 63 | } 64 | } else { 65 | var prev = i - 1; 66 | while (prev >= 0 && str[prev] === '.') { 67 | str[prev] = 'L'; 68 | prev--; 69 | } 70 | } 71 | } else if (char === 'R') { 72 | stack.push(i); 73 | } 74 | } 75 | 76 | // If stack is not empty, we reached the end of dominos with "." as last 77 | while (stack.length) { 78 | var last = stack.pop(); 79 | while (++last < str.length && str[last] === '.') { 80 | str[last] = 'R'; 81 | } 82 | } 83 | 84 | return str.join(''); 85 | }; 86 | 87 | pushDominoes('.L.R...LR..L..'); // "LL.RR.LLRRLL.." 88 | 89 | // Time Complexity: O(N) 90 | // Space Complexity: O(N) 91 | -------------------------------------------------------------------------------- /problems/leetcode/stack and queue/README.md: -------------------------------------------------------------------------------- 1 | # Stack and Queue 2 | 3 | 1. [Evaluate Reverse Polish Notation](./1.evaluate_reverse_polish_notation.js) 4 | 1. [Design a stack](./2.min_stack.js) 5 | 1. [Is Valid Parentheses](./3.valid_parentheses.js) 6 | 1. [Daily Temperatures](./4.daily_temperature.js) 7 | 1. [Push Dominoes](./5.push_dominoes.js) 8 | -------------------------------------------------------------------------------- /problems/leetcode/strings/1.longest_common_prefix.js: -------------------------------------------------------------------------------- 1 | /* Problem: Write a function to find the longest common prefix string amongst an array of strings. 2 | 3 | Longest common prefix for a pair of strings S1 and S2 is the longest string S which is the prefix of both S1 and S2. 4 | 5 | As an example, longest common prefix of "abcdefgh" and "abcefgh" is "abc". 6 | 7 | Given the array of strings, you need to find the longest S which is the prefix of ALL the strings in the array. 8 | 9 | Example: 10 | 11 | Input: [ "abd", "abccc", "abcc"] 12 | Output: ab 13 | 14 | */ 15 | 16 | function longestCommonPrefix(arr) { 17 | var longest = ""; 18 | var firstWord = arr[0]; 19 | 20 | for (var i = 0; i < firstWord.length - 1; i++) { 21 | var count = 0; 22 | var char = firstWord[i]; 23 | for (var j = 1; j < arr.length; j++) { 24 | var compareChar = arr[j][i]; 25 | if (char === compareChar) count++; 26 | else break; 27 | } 28 | 29 | if (count === arr.length - 1) { 30 | longest += char; 31 | continue; 32 | } 33 | } 34 | 35 | return longest; 36 | } 37 | 38 | longestCommonPrefix(["abd", "abccc", "abcc"]); // ab 39 | 40 | /* Complexity: 41 | 42 | Time Complexity: O(n^2) 43 | 44 | */ 45 | -------------------------------------------------------------------------------- /problems/leetcode/strings/10.first_uniq_char.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a string, find the first non-repeating character in it and return it's index. If it doesn't exist, return -1. 2 | 3 | Examples: 4 | 5 | s = "leetcode" 6 | return 0. 7 | 8 | s = "loveleetcode", 9 | return 2. 10 | 11 | Note: You may assume the string contain only lowercase letters. 12 | */ 13 | 14 | function firstUniqChar(str) { 15 | var hash = {}; 16 | 17 | for (var i = 0; i < str.length; i++) { 18 | if (!hash[str[i]]) hash[str[i]] = 1; 19 | else { 20 | hash[str[i]] += 1; 21 | } 22 | } 23 | 24 | for (var i = 0; i < str.length; i++) { 25 | if (hash[str[i]] === 1) return i; 26 | } 27 | 28 | return -1; 29 | } 30 | 31 | firstUniqChar('leetcode'); // 0 32 | firstUniqChar('aadsadss'); // -1 33 | 34 | // Time Complexity: O(N) 35 | // Space Complexity: O(N), as we are storing N times in hash 36 | -------------------------------------------------------------------------------- /problems/leetcode/strings/11.strStr.js: -------------------------------------------------------------------------------- 1 | /* Problem: Implement strStr(). Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack. 2 | 3 | Example 1: 4 | Input: haystack = "hello", needle = "ll" 5 | Output: 2 6 | 7 | Example 2: 8 | Input: haystack = "aaaaa", needle = "bba" 9 | Output: -1 10 | 11 | Clarification: 12 | - What should we return when needle is an empty string? This is a great question to ask during an interview. 13 | - 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(). 14 | */ 15 | 16 | // Solution 1 - Using subString method 17 | 18 | var strStr = function(haystack, needle) { 19 | var hashLen = needle.length; 20 | 21 | if (!haystack && needle) return -1; // When haystack string not present but needle present 22 | else if (!haystack) return 0; // // When haystack string not present 23 | 24 | for (var i = 0; i < haystack.length; i++) { 25 | if (haystack.substring(i, hashLen + i) == needle) { 26 | return i; 27 | } 28 | } 29 | 30 | return -1; // When needle string not present in haystack 31 | }; 32 | 33 | strStr("hello", "ll"); // 2 34 | 35 | // Time Complexity: O(N) 36 | // Space Complexity: O(1) 37 | 38 | // Solution 2 - Using indexOf() 39 | 40 | var strStr = function(haystack, needle) { 41 | if (!haystack) return 0; 42 | return haystack.indexOf(needle); 43 | }; 44 | 45 | strStr("hello", "ll"); // 2 46 | 47 | // Time Complexity: O(N) 48 | -------------------------------------------------------------------------------- /problems/leetcode/strings/12.check_if_two_string_are_anagram.js: -------------------------------------------------------------------------------- 1 | /* Problem: Check whether two Strings are Anagram of each other 2 | 3 | For example, “abcd” and “dabc” are an Anagram of each other. 4 | 5 | */ 6 | 7 | // Solution 1 - Sorting 8 | 9 | function checkAnagram(str1, str2) { 10 | if (str1.length !== str2.length) return false; 11 | 12 | str1 = str1 13 | .toLowerCase() 14 | .split("") 15 | .sort() 16 | .join(""); 17 | 18 | str2 = str2 19 | .toLowerCase() 20 | .split("") 21 | .sort() 22 | .join(""); 23 | 24 | for (var i = 0; i < str1.length; i++) { 25 | if (str1[i] !== str2[i]) return false; 26 | } 27 | 28 | return true; 29 | } 30 | 31 | checkAnagram("abcd", "dabc"); // True 32 | checkAnagram("abcd", "dabb"); // False 33 | 34 | // Time Complexity: O(N Log N) 35 | 36 | // Solution 2 - HashMap 37 | function checkAnagram(str1, str2) { 38 | if (str1.length !== str2.length) return false; 39 | 40 | str1 = str1.toLowerCase(); 41 | str2 = str2.toLowerCase(); 42 | 43 | var hash = {}; 44 | 45 | for (var i = 0; i < str1.length; i++) { 46 | if (!hash[str1[i]]) { 47 | hash[str1[i]] = 1; 48 | } else hash[str1[i]]++; 49 | } 50 | 51 | for (var i = 0; i < str2.length; i++) { 52 | hash[str1[i]]--; 53 | } 54 | 55 | for (var key in hash) { 56 | if (hash[key] > 0) return false; 57 | } 58 | 59 | return true; 60 | } 61 | 62 | checkAnagram("abcd", "dabc"); // True 63 | checkAnagram("abcd", "dabb"); // False 64 | 65 | // Time Complexity: O(N) 66 | -------------------------------------------------------------------------------- /problems/leetcode/strings/13.first_non_repeating_char.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a string, find the first non-repeating character in it and return it's index. If it doesn't exist, return -1. 2 | 3 | Note: You may assume the string contain only lowercase letters. 4 | 5 | Examples: 6 | Input: S = "leetcode" 7 | Output: 0 8 | 9 | Input: S = "loveleetcode" 10 | Output: 2 11 | 12 | 13 | Explanation: 14 | 15 | - In example 1, chars l, t, c, o, d are non-repeating but only l is first non-repeating char in given string S. 16 | - In example 2, chars v, t, d are non-repeating but v is first non-repeating char in given string S. 17 | 18 | */ 19 | 20 | // Solution 1: 21 | 22 | function nonRepeatingFirstChar(S) { 23 | var hash = {}; 24 | 25 | for (var i = 0; i < S.length; i++) { 26 | if (!hash[S[i]]) { 27 | hash[S[i]] = 1; 28 | } else { 29 | hash[S[i]] += 1; 30 | } 31 | } 32 | 33 | for (var i = 0; i < S.length; i++) { 34 | if (hash[S[i]] === 1) return i; 35 | } 36 | 37 | return -1; 38 | } 39 | 40 | nonRepeatingFirstChar("loveleetcode"); // 2 41 | 42 | // Time Complexity: O(N) 43 | // Space Complexity: O(N) 44 | 45 | // Note: Problem with above solution is if the non-repeating char is at the end of S we will end up scanning to end which is not efficient. 46 | // Lets solve in solution 2 47 | 48 | // Solution 2: 49 | 50 | function nonRepeatingFirstChar(S) { 51 | var temp = []; 52 | 53 | for (var i = 0; i < S.length; i++) { 54 | temp[i] = [temp[i] ? temp[i][0]++ : 1, i]; 55 | } 56 | 57 | return temp; 58 | } 59 | -------------------------------------------------------------------------------- /problems/leetcode/strings/14.subsequence_of_given_string.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a string S and a set of words D, find the longest word in D that is a subsequence of S. 2 | 3 | Note: 4 | - Word W is a subsequence of S if some number of characters, possibly zero, can be deleted from S to form W, without reordering the remaining characters. 5 | - D can appear in any format (list, hash table, prefix tree, etc) 6 | 7 | Example: 8 | Input: S = "abppplee", D = ["able", "ale", "apple", "bale", "kangaroo"] 9 | Output: "apple" 10 | 11 | Explanation: 12 | - The words "able" and "ale" are both subsequences of S, but they are shorter than "apple". 13 | - The word "bale" is not a subsequence of S because even though S has all the right letters, they are not in the right order. 14 | - The word "kangaroo" is the longest word in D, but it isn't a subsequence of S. 15 | */ 16 | 17 | // Solution 1 18 | 19 | function findSubSequenceOfString(S, D) { 20 | if (!D.length) return ""; 21 | 22 | var result = ""; 23 | var length = 0; 24 | 25 | for (var i = 0; i < D.length; i++) { 26 | if (length < D[i] && isSubSequence(D[i], S)) { 27 | length = D[i].length; 28 | result = D[i]; 29 | } 30 | } 31 | 32 | function isSubSequence(str1, str2) { 33 | var m = str1.length; 34 | var n = str2.length; 35 | 36 | var j = 0; 37 | 38 | for (var i = 0; i < n && j < m; i++) { 39 | if (str[j] === str2[i]) { 40 | j++; 41 | } 42 | } 43 | 44 | return j === m; 45 | } 46 | 47 | return result; 48 | } 49 | 50 | findSubSequenceOfString("abppplee", [ 51 | "able", 52 | "ale", 53 | "apple", 54 | "bale", 55 | "kangaroo" 56 | ]); 57 | 58 | // Time Complexity: O(N * K * L), N is length of D and K is length of S and L is max length of words in D 59 | // Auxillary Space: O(1) 60 | // Space Complexity: O(1) 61 | -------------------------------------------------------------------------------- /problems/leetcode/strings/15.numbers_to_words.js: -------------------------------------------------------------------------------- 1 | /* Problem: Convert a non-negative integer to its english words representation. 2 | 3 | Example 1: 4 | Input: 123 5 | Output: "One Hundred Twenty Three" 6 | 7 | Example 2: 8 | Input: 12345 9 | Output: "Twelve Thousand Three Hundred Forty Five" 10 | 11 | Example 3: 12 | Input: 1234567 13 | Output: "One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven" 14 | 15 | Example 4: 16 | Input: 1234567891 17 | Output: "One Billion Two Hundred Thirty Four Million Five Hundred Sixty Seven Thousand Eight Hundred Ninety One" 18 | 19 | Note: Given input is guaranteed to be less than 2^31 - 1 (2 to the power of 31 minus 1). 20 | */ 21 | 22 | function numberToWords(num) { 23 | if (num === 0) return 'Zero'; 24 | 25 | var lessThanTen = { 1: 'One', 2: 'Two', 3: 'Three', 4: 'Four', 5: 'Five', 6: 'Six', 7: 'Seven', 8: 'Eight', 9: 'Nine' }; 26 | var lessThanTwenty = { 27 | 10: 'Ten', 28 | 11: 'Eleven', 29 | 12: 'Twelve', 30 | 13: 'Thirteen', 31 | 14: 'Fourteen', 32 | 15: 'Fifteen', 33 | 16: 'Sixteen', 34 | 17: 'Seventeen', 35 | 18: 'Eighteen', 36 | 19: 'Nineteen', 37 | 20: 'Twenty' 38 | }; 39 | var lessThanHundred = { 1: 'Ten', 2: 'Twenty', 3: 'Thirty', 4: 'Forty', 5: 'Fifty', 6: 'Sixty', 70: 'Seventy', 8: 'Eighty', 9: 'Ninety' }; 40 | 41 | function getWords(num) { 42 | var str = ''; 43 | if (num < 10) { 44 | if (num === 0) return ''; 45 | str = lessThanTen[num]; 46 | } else if (num < 20) { 47 | str = lessThanTwenty[num]; 48 | } else if (num < 100) { 49 | str = `${lessThanHundred[Math.floor(num / 10)]} ${getWords(num % 10)}`; 50 | } else if (num < 1000) { 51 | str = `${getWords(Math.floor(num / 100))} Hundred ${getWords(num % 100)}`; 52 | } else if (num < 10000) { 53 | str = `${getWords(Math.floor(num / 10000))} Thousand ${getWords(num % 10000)}`; 54 | } else if (num < 1000000) { 55 | str = `${getWords(Math.floor(num / 1000000))} Thousand ${getWords(num % 1000000)}`; 56 | } else { 57 | str = `${getWords(Math.floor(num / 10000000))} Thousand ${getWords(num % 10000000)}`; 58 | } 59 | 60 | return str; 61 | } 62 | 63 | return getWords(num); 64 | } 65 | -------------------------------------------------------------------------------- /problems/leetcode/strings/16.capitalize_first_and_last_char.js: -------------------------------------------------------------------------------- 1 | /* Problem: For this challenge, you will have to write a function called capitalizeFirstLast or capitalize_first_last. This function will capitalize the first and last letter of each word, and lowercase what is in between. 2 | 3 | Example: 4 | Input: "hello world" 5 | Out: "HellO WorlD" 6 | 7 | Rules: 8 | 9 | - The function will take a single parameter, which will be a string. 10 | - The string can contain words separated by a single space. 11 | - Words are made of letters from the ASCII range only. 12 | - The function should return a string. 13 | - Only the first and last letters are uppercased. 14 | - All the other letters should be lowercased. 15 | 16 | */ 17 | 18 | function capitalizeFirstAndLastChar(str) { 19 | var result = ""; 20 | 21 | if (!str.length) { 22 | return result; 23 | } 24 | 25 | result = str[0].toUpperCase(); 26 | var end = -1; 27 | 28 | for (var i = 1; i < str.length; i++) { 29 | if (str[i - 1] === " ") { 30 | end = i; 31 | } 32 | 33 | if (end != -1) { 34 | result += str[end].toUpperCase(); 35 | } else { 36 | if (str[i + 1] === " " || str.length - 1 === i) { 37 | result += str[i].toUpperCase(); 38 | } else { 39 | result += str[i]; 40 | } 41 | } 42 | 43 | end = -1; 44 | } 45 | 46 | return result; 47 | } 48 | 49 | capitalizeFirstAndLastChar("hello world"); // "HellO WorlD" 50 | 51 | // Time Complexity: O(N) 52 | // Space Complexity: O(1) 53 | -------------------------------------------------------------------------------- /problems/leetcode/strings/17.isograms.js: -------------------------------------------------------------------------------- 1 | /* Problem: An isogram is a word that has no repeating letters, consecutive or non-consecutive. 2 | 3 | Implement a function that determines whether a string that contains only letters is an isogram. Assume the empty string is an isogram. 4 | 5 | Note: Ignore letter case. 6 | 7 | Example: 8 | isIsogram("Dermatoglyphics") == true 9 | isIsogram("aba") == false 10 | isIsogram("moOse") == false // -- ignore letter case 11 | 12 | 13 | */ 14 | 15 | // Solution 1 = Using hashMaps 16 | function isIsogram(str) { 17 | var hash = {}; 18 | str = str.toLowerCase(); 19 | 20 | for (var i = 0; i < str.length; i++) { 21 | var char = str[i]; 22 | if (!hash[char]) { 23 | hash[char] = true; 24 | } else { 25 | return false; 26 | } 27 | } 28 | return true; 29 | } 30 | 31 | // Time Complexity: O(N), N is length of string 32 | // Space Complexity: O(N) 33 | 34 | // Solution 2 - Using set 35 | function isIsogram(str) { 36 | return !str || new Set(str.toLowerCase()).size === str.length; 37 | } 38 | 39 | // Time Complexity: O(N), N is length of string 40 | // Space Complexity: O(N) 41 | -------------------------------------------------------------------------------- /problems/leetcode/strings/18.rotate_string.js: -------------------------------------------------------------------------------- 1 | /* Problem: We are given two strings, A and B. A shift on A consists of taking string A and moving the leftmost character to the rightmost position. 2 | 3 | Explanation: 4 | - if A = 'abcde', then it will be 'bcdea' after one shift on A. 5 | - Return True if and only if A can become B after some number of shifts on A. 6 | 7 | Example 1: 8 | Input: A = 'abcde', B = 'cdeab' 9 | Output: true 10 | 11 | Example 2: 12 | Input: A = 'abcde', B = 'abced' 13 | Output: false 14 | Note: 15 | 16 | Note: A and B will have length at most 100. 17 | */ 18 | 19 | // Solution 1 - Shift one chart at a time in str1 to end of str2 and check agaist str2 20 | 21 | function rotateStrings(A, B) { 22 | if (!A && !B) { 23 | return true; 24 | } 25 | 26 | if (A.length !== B.length) { 27 | return false; 28 | } 29 | 30 | if (A === B) { 31 | return true; 32 | } 33 | 34 | for (var i = 0; i < A.length; i++) { 35 | A = A.slice(1, A.length) + A.slice(0, 1); 36 | 37 | if (A === B) { 38 | return true; 39 | } 40 | } 41 | 42 | return false; 43 | } 44 | 45 | rotateStrings("abcde", "cdeab"); 46 | 47 | // Time Complexity: O(N) 48 | // Space Complexity: O(N), N is length of the given string 49 | 50 | // Solution 2 - Similar to solution 1 but with arrays 51 | 52 | function rotateStrings(A, B) { 53 | if (!A && !B) { 54 | return true; 55 | } 56 | 57 | if (A.length !== B.length) { 58 | return false; 59 | } 60 | 61 | if (A === B) { 62 | return true; 63 | } 64 | 65 | var arr = A.split(""); 66 | 67 | for (var i = 0; i < arr.length; i++) { 68 | arr.push(arr.shift()); 69 | 70 | if (arr.join("") === B) { 71 | return true; 72 | } 73 | } 74 | 75 | return false; 76 | } 77 | 78 | rotateStrings("abcde", "cdeab"); 79 | 80 | // Time Complexity: O(N) 81 | // Space Complexity: O(N), N is length of the array 82 | -------------------------------------------------------------------------------- /problems/leetcode/strings/2.power_of_2.js: -------------------------------------------------------------------------------- 1 | /* Problem: Find if Given number is power of 2 or not. 2 | 3 | More specifically, find if given number can be expressed as 2^k where k >= 1. 4 | 5 | Example: 6 | 7 | Input: 5070602400912917605986812821504 8 | Output: 1 9 | 10 | Input: 129 11 | Output: 0 12 | 13 | */ 14 | 15 | function powerOf2OrNot(N) { 16 | if (N < 2) return 0; 17 | var count = N; 18 | while (count > 0) { 19 | count /= 2; 20 | if (count === 1) return 1; 21 | else if ((count - Math.floor(count)) !== 0) return 0; 22 | } 23 | } 24 | 25 | 26 | powerOf2OrNot(128); // 1 27 | powerOf2OrNot(3); // 0 28 | 29 | /* Complexity: 30 | 31 | Time Complexity: O(n) 32 | 33 | */ 34 | -------------------------------------------------------------------------------- /problems/leetcode/strings/3.excel_sheet_column_title.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a positive integer, return its corresponding column title as appear in an Excel sheet. 2 | 3 | Example: 4 | Input: 5 | 1 -> A 6 | 2 -> B 7 | 3 -> C 8 | ... 9 | 26 -> Z 10 | 27 -> AA 11 | 28 -> AB 12 | 13 | Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode 14 | 15 | // String.fromCharCode(someNumber); will the abc based on UTF-16 code units 16 | // Example: String.fromCharCode(65, 66, 67); // returns "ABC" 17 | */ 18 | 19 | function getColumnTitle(num) { 20 | var str = ""; 21 | while (num) { 22 | var char = String.fromCharCode((num - 1) % 26 + "A".charCodeAt()); // "A".charCodeAt() === 65 23 | str = char + str; 24 | num = Math.floor((num - 1) / 26); 25 | } 26 | return str; 27 | } 28 | 29 | getColumnTitle(27); // "AA" 30 | getColumnTitle(5444); // "HAJ" 31 | -------------------------------------------------------------------------------- /problems/leetcode/strings/4.group_of_anagrams.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given an array of strings, group anagrams together. 2 | 3 | Example: 4 | Input: ["eat", "tea", "tan", "ate", "nat", "bat"] 5 | 6 | Output: [["ate", "eat","tea"], ["nat","tan"], ["bat"]] 7 | 8 | */ 9 | 10 | function groupAnagrams(strs) { 11 | var obj = {}; 12 | 13 | strs.forEach(str => { 14 | var val = str.split("").sort().join(""); 15 | if (obj[val]) { 16 | obj[val].push(str); 17 | } 18 | else { 19 | obj[val] = [str]; 20 | } 21 | }); 22 | 23 | var result = []; 24 | 25 | for (var i in obj) { 26 | if (obj.hasOwnProperty(i)) { 27 | result.push(obj[i]); 28 | } 29 | } 30 | 31 | return result; 32 | }; 33 | 34 | groupAnagrams(["eat", "tea", "tan", "ate", "nat", "bat"]); // [["ate", "eat","tea"], ["nat","tan"], ["bat"]] 35 | 36 | // Time Complexity: O(NK) + Sort(), N is no of `str` in `strs` and K is length of each string 37 | -------------------------------------------------------------------------------- /problems/leetcode/strings/5.number_to_words.js: -------------------------------------------------------------------------------- 1 | /* Problem: Convert a non-negative integer to its english words representation. 2 | 3 | Example 1: 4 | Input: 123 5 | Output: "One Hundred Twenty Three" 6 | 7 | Example 2: 8 | Input: 12345 9 | Output: "Twelve Thousand Three Hundred Forty Five" 10 | 11 | Example 3: 12 | Input: 1234567 13 | Output: "One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven" 14 | 15 | Example 4: 16 | Input: 1234567891 17 | Output: "One Billion Two Hundred Thirty Four Million Five Hundred Sixty Seven Thousand Eight Hundred Ninety One" 18 | 19 | Note: Given input is guaranteed to be less than 2^31 - 1 (2 to the power of 31 minus 1). 20 | */ 21 | 22 | function numberToWords(num) { 23 | if (num === 0) return 'Zero'; 24 | 25 | var lessThanTen = { 1: 'One', 2: 'Two', 3: 'Three', 4: 'Four', 5: 'Five', 6: 'Six', 7: 'Seven', 8: 'Eight', 9: 'Nine' }; 26 | var lessThanTwenty = { 27 | 10: 'Ten', 28 | 11: 'Eleven', 29 | 12: 'Twelve', 30 | 13: 'Thirteen', 31 | 14: 'Fourteen', 32 | 15: 'Fifteen', 33 | 16: 'Sixteen', 34 | 17: 'Seventeen', 35 | 18: 'Eighteen', 36 | 19: 'Nineteen', 37 | 20: 'Twenty' 38 | }; 39 | var lessThanHundred = { 1: 'Ten', 2: 'Twenty', 3: 'Thirty', 4: 'Forty', 5: 'Fifty', 6: 'Sixty', 70: 'Seventy', 8: 'Eighty', 9: 'Ninety' }; 40 | 41 | function getWords(num) { 42 | var str = ''; 43 | if (num < 10) { 44 | if (num === 0) return ''; 45 | str = lessThanTen[num]; 46 | } else if (num < 20) { 47 | str = lessThanTwenty[num]; 48 | } else if (num < 100) { 49 | str = `${lessThanHundred[Math.floor(num / 10)]} ${getWords(num % 10)}`; 50 | } else if (num < 1000) { 51 | str = `${getWords(Math.floor(num / 100))} Hundred ${getWords(num % 100)}`; 52 | } else if (num < 10000) { 53 | str = `${getWords(Math.floor(num / 10000))} Thousand ${getWords(num % 10000)}`; 54 | } else if (num < 1000000) { 55 | str = `${getWords(Math.floor(num / 1000000))} Thousand ${getWords(num % 1000000)}`; 56 | } else { 57 | str = `${getWords(Math.floor(num / 10000000))} Thousand ${getWords(num % 10000000)}`; 58 | } 59 | 60 | return str; 61 | } 62 | 63 | return getWords(num); 64 | } 65 | -------------------------------------------------------------------------------- /problems/leetcode/strings/6.students_attendance.js: -------------------------------------------------------------------------------- 1 | /* Problem: You are given a string representing an attendance record for a student. The record only contains the following three characters: 2 | 'A' : Absent. 3 | 'L' : Late. 4 | 'P' : Present. 5 | 6 | Note: A student could be rewarded if his attendance record doesn't contain more than one 'A' (absent) or more than two continuous 'L' (late). 7 | 8 | Example 1: 9 | Input: "PPALLP" 10 | Output: True 11 | 12 | Example 2: 13 | Input: "PPALLL" 14 | Output: False 15 | */ 16 | 17 | var checkRecord = function (s) { 18 | var L = 0; 19 | var A = 0; 20 | 21 | for (var i = 0; i < s.length; i++) { 22 | if (s[i] === "A") { 23 | A++; 24 | if (L <= 2) L = 0; // If its A in string and L is < 2 reset to 0 25 | } 26 | else if (s[i] === "L") { 27 | L++; 28 | } 29 | else { 30 | L = 0; // If L is not continuous, reset to 0 31 | } 32 | 33 | if (L > 2 || A > 1) return false; 34 | } 35 | 36 | return true; 37 | }; 38 | 39 | checkRecord("PPALLP"); // True 40 | checkRecord("PPALLLP"); // False 41 | 42 | // Time Complexity: O(N), N is string length 43 | -------------------------------------------------------------------------------- /problems/leetcode/strings/7.string_reversal_without_changing_special.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a string, that contains special character together with alphabets (‘a’ to ‘z’ and ‘A’ to ‘Z’), reverse the string in a way that special characters are not affected. 2 | 3 | Example 1: 4 | Input: str = "a,b$c" 5 | Output: str = "c,b$a" 6 | Note: $ and , are not moved anywhere and only subsequence "abc" is reversed 7 | 8 | Example 2: 9 | Input: str = "Ab,c,de!$" 10 | Output: str = "ed,c,bA!$" 11 | */ 12 | 13 | 14 | // Solution 1 15 | // Using temp array 16 | 17 | var stringReversal = function (str) { 18 | var tempArr = []; 19 | var regEx = /^[A-Za-z]+$/i; // To check char is alphabet or not 20 | 21 | for (var i = 0; i < str.length; i++) { 22 | if (str[i].match(regEx)) { 23 | tempArr.push(str[i]); 24 | } 25 | } 26 | 27 | tempArr = tempArr.reverse(); // Reversing the alphabets 28 | var tempStr = ""; // To store the result 29 | 30 | for (var i = 0, j = 0; i < str.length; i++) { 31 | if (!str[i].match(regEx)) { 32 | tempStr += str[i]; 33 | } 34 | else if (j < tempArr.length) { 35 | tempStr += tempArr[j]; 36 | j++; 37 | } 38 | } 39 | 40 | return tempStr; 41 | } 42 | 43 | var str = "Ab,c,de!$"; 44 | 45 | stringReversal(str); // ed,c,bA!$" 46 | 47 | // Time Complexity: O(N) 48 | // Space Complexity: O(1) 49 | 50 | // We can optimize even further 51 | // Solution 2 using one traversal with two pointers (start & end) 52 | 53 | var stringReversal = function (str) { 54 | var regEx = /^[A-Za-z]+$/i; // To check char is alphabet or not 55 | var pointer1 = 0; 56 | var pointer2 = str.length - 1; 57 | 58 | str = str.split(""); 59 | 60 | while (pointer1 < pointer2) { 61 | // If not abc, then increment pointer1 and pointer2 62 | if (!str[pointer1].match(regEx)) { 63 | pointer1++; 64 | } 65 | else if (!str[pointer2].match(regEx)) { 66 | pointer2--; 67 | } 68 | else { 69 | var temp2 = str[pointer2]; 70 | var temp1 = str[pointer1]; 71 | str[pointer2] = temp1; 72 | str[pointer1] = temp2; 73 | pointer1++; 74 | pointer2--; 75 | } 76 | } 77 | 78 | return str.join(""); 79 | } 80 | 81 | // Time Complexity: O(N), with one iteration 82 | -------------------------------------------------------------------------------- /problems/leetcode/strings/8.length_of_last_word.js: -------------------------------------------------------------------------------- 1 | /* 2 | Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the length of last word in the string. 3 | If the last word does not exist, return 0. 4 | 5 | Note: A word is defined as a character sequence consists of non-space characters only. 6 | 7 | Example: 8 | Input: "Hello World" 9 | Output: 5 10 | */ 11 | 12 | // Solution 1 13 | 14 | var lengthOfLastWord = function(s) { 15 | s = s.trim(); // To remove last space in str 16 | var length = 0; 17 | if (!s[i]) return length; 18 | var i = s.length - 1; 19 | while (s[i] && s[i] !== ' ') { 20 | length += 1; 21 | i -= 1; 22 | } 23 | return length; 24 | }; 25 | 26 | lengthOfLastWord('hello s world'); // 5 27 | 28 | // Time Complexity: O(N) 29 | 30 | // Solution 2 31 | 32 | var lengthOfLastWord = function(s) { 33 | s = s.trim(); // To remove last space in str 34 | var strArr = s.split(' '); 35 | return strArr[strArr.length - 1].length; 36 | }; 37 | 38 | lengthOfLastWord('hello s world'); // 5 39 | 40 | // Time Complexity: O(N) 41 | -------------------------------------------------------------------------------- /problems/leetcode/strings/9.longest_substr.js: -------------------------------------------------------------------------------- 1 | /* Problem: 2 | Given a string, find the length of the longest substring without repeating characters. 3 | 4 | Example 1: 5 | Input: "abcabcbb" 6 | Output: 3 7 | Explanation: The answer is "abc", with the length of 3. 8 | 9 | Example 2: 10 | Input: "bbbbb" 11 | Output: 1 12 | Explanation: The answer is "b", with the length of 1. 13 | 14 | Example 3: 15 | Input: "pwwkew" 16 | Output: 3 17 | 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 18 | 19 | */ 20 | 21 | function lengthOfLongestSubstr(str) { 22 | var leftWindow = 0; 23 | var rightWindow = 0; 24 | var longestSubStrLength = 0; 25 | var hash = {}; 26 | 27 | while (rightWindow < str.length) { 28 | var char = str[rightWindow]; 29 | 30 | if (!hash[char]) { 31 | hash[char] = char; 32 | // Get max of (prev longestSubStrLength & right - left window + 1) 33 | longestSubStrLength = Math.max(longestSubStrLength, rightWindow - leftWindow + 1); 34 | rightWindow++; 35 | } else { 36 | hash[str[leftWindow]] = null; 37 | leftWindow++; 38 | } 39 | } 40 | 41 | return longestSubStrLength; 42 | } 43 | 44 | lengthOfLongestSubstr('bbbbb'); // 1 45 | lengthOfLongestSubstr('bbbbbac'); // 3 46 | lengthOfLongestSubstr('bbbbbacgokul'); // 8 47 | 48 | // Time Complexity: O(N) 49 | // Space Complexity: O(min(m, n)) 50 | -------------------------------------------------------------------------------- /problems/leetcode/strings/README.md: -------------------------------------------------------------------------------- 1 | # Strings 2 | 3 | 1. [Longest Common Prefix](./1.longest_common_prefix.js) 4 | 1. [Power of 2](./2.power_of_2.js) 5 | 1. [Excel Sheet Column Title](./3.excel_sheet_column_title.js) 6 | 1. [Group Of Anagrams](./4.group_of_anagrams.js) 7 | 1. [Number To Words](./5.number_to_words.js) 8 | 1. [Students Attendance](./6.students_attendance.js) 9 | 1. [String Reversal With Special Characters](./7.string_reversal_without_changing_special.js) 10 | 1. [Length Of Last Words](./8.length_of_last_word.js) 11 | 1. [Find Longest SubString](./9.longest_substr.js) 12 | 1. [First Unique Character](./10.first_uniq_char.js) 13 | 1. [Implement strStr()](./11.strStr.js) 14 | 1. [Check Anagram](./12.check_if_two_string_are_anagram.js) 15 | 1. [First non repeating chars ](./13.first_non_repeating_char.js) 16 | 1. [Subsequence of given string](./14.subsequence_of_given_string.js) 17 | 1. [Numbers to words](./15.numbers_to_words.js) 18 | 1. [Capitalize first and last chars of given string](./16.capitalize_first_and_last_char.js) 19 | 1. [Given string is isogram or not?](./17.isograms.js) 20 | 1. [Rotate the given string](./18.rotate_string.js) 21 | -------------------------------------------------------------------------------- /problems/leetcode/template_problem.js: -------------------------------------------------------------------------------- 1 | /* Problem: 2 | 3 | Pseudo code: 4 | 5 | 6 | */ 7 | 8 | function funz(arr) {} 9 | 10 | funz(arr); 11 | 12 | // Time Complexity: 13 | // Space Complexity: 14 | -------------------------------------------------------------------------------- /problems/leetcode/trees/1.max_depth_of_tree.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a binary tree, find its maximum depth. 2 | 3 | Note: The maximum depth of a binary tree is the number of nodes along the longest path from the root node down to the farthest leaf node. 4 | 5 | Example: 6 | Input: { 7 | data: 1, 8 | left: { 9 | data: 2, 10 | left: null, 11 | right: null 12 | }, 13 | right: null 14 | } 15 | 16 | Output: 2 17 | 18 | Definition for a binary tree node: 19 | function TreeNode(A){ 20 | this.data = A 21 | this.left = null 22 | this.right = null 23 | } 24 | */ 25 | 26 | function maxDepth(A) { 27 | function traverse(A) { 28 | if (!A) return 0; 29 | else { 30 | return 1 + Math.max(traverse(A.left), traverse(A.right)); 31 | } 32 | } 33 | return traverse(A); 34 | } 35 | 36 | maxDepth({ data: 1, left: { data: 2, left: null, right: null }, right: null }); // 2 37 | 38 | // Time Complexity: O(N) as we are traversing almost to deep to the tree 39 | -------------------------------------------------------------------------------- /problems/leetcode/trees/10.symmetric_tree.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). 2 | 3 | Example 1: 4 | Input: 5 | 1 6 | / \ 7 | 2 2 8 | / \ / \ 9 | 3 4 4 3 10 | 11 | Output: True 12 | 13 | Example 2: 14 | Input: 15 | 1 16 | / \ 17 | 2 2 18 | \ \ 19 | 3 3 20 | 21 | Output: False 22 | 23 | */ 24 | 25 | var isSymmetric = function (root) { 26 | if (!root) return true; 27 | 28 | var traverse = function (tree1, tree2) { 29 | if (!tree1 && !tree2) return true; 30 | else if (!tree1 || !tree2) return false; 31 | return (tree1.val === tree2.val) && traverse(tree1.left, tree2.right) && traverse(tree1.right, tree2.left); 32 | } 33 | return traverse(root.left, root.right); 34 | }; 35 | 36 | var root1 = { val: 1, right: { val: 2, right: { val: 3, right: null, left: null }, left: { val: 4, right: null, left: null } }, left: { val: 2, right: { val: 4, right: null, left: null }, left: { val: 3, right: null, left: null } } }; 37 | var root1 = { val: 1, right: { val: 2, right: { val: 3, right: null, left: null }, left: { val: 4, right: null, left: null } }, left: { val: 2, right: { val: 4, right: null, left: null }, left: { val: 1, right: null, left: null } } }; 38 | 39 | isSymmetric(root1); // True 40 | isSymmetric(root2); // False 41 | 42 | // Time Complexity: O(N) 43 | // Space Complexity: O(N) due to recursion 44 | -------------------------------------------------------------------------------- /problems/leetcode/trees/11.path_sum.js: -------------------------------------------------------------------------------- 1 | /* 2 | 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. 3 | Note: A leaf is a node with no children. 4 | 5 | Example:Given the below binary tree and sum = 22, 6 | 5 7 | / \ 8 | 4 8 9 | / / \ 10 | 11 13 4 11 | / \ \ 12 | 7 2 1 13 | 14 | return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22. 15 | 16 | */ 17 | 18 | var hasPathSum = function(root, sum) { 19 | var ans = 0; 20 | var traverse = function(root, sum, ans) { 21 | if (root == null) return false; 22 | ans += root.val; 23 | if (!root.left && !root.right && sum == ans) return true; 24 | return traverse(root.left, sum, ans) || traverse(root.right, sum, ans) 25 | } 26 | return traverse(root, sum, ans); 27 | }; 28 | 29 | var root = { 30 | val: 5, 31 | left: { val: 4, right: null, left: { val: 11, right: { val: 2, right: null, left: null }, left: { val: 7, right: null, left: null } } }, 32 | right: { val: 8, right: { val: 13, right: null, left: null }, left: { val: 4, right: { val: 1, right: null, left: null } } }, 33 | }; 34 | 35 | hasPathSum(root, 22); // true 36 | 37 | // Time Complexity: O(N) 38 | -------------------------------------------------------------------------------- /problems/leetcode/trees/12.level_order_traversal.js: -------------------------------------------------------------------------------- 1 | /* Problem: Binary Tree Level Order Traversal 2 | Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level). 3 | 4 | Example: 5 | - Given binary tree [3,9,20,null,null,15,7], 6 | 7 | 3 8 | / \ 9 | 9 20 10 | / \ 11 | 15 7 12 | 13 | Result: [ [3], [9,20], [15,7] ] 14 | 15 | */ 16 | 17 | var levelOrderTraversal = function(root) { 18 | if (!root) return []; 19 | var result = []; 20 | 21 | function search(root, depth) { 22 | if (root) { 23 | if (result.length < depth) { 24 | result[depth - 1] = []; 25 | } 26 | 27 | result[depth - 1].push(root.val); 28 | search(root.left, depth + 1); 29 | search(root.right, depth + 1); 30 | } else return; 31 | } 32 | 33 | search(root, 1); 34 | 35 | return result; 36 | }; 37 | 38 | var root = { 39 | val: 15, 40 | left: { 41 | val: 5, 42 | left: { 43 | val: 2, 44 | left: null, 45 | right: null 46 | }, 47 | right: { 48 | val: 4, 49 | left: null, 50 | right: null 51 | } 52 | }, 53 | right: { 54 | val: 17, 55 | left: { 56 | val: 15, 57 | left: null, 58 | right: null 59 | }, 60 | right: { 61 | val: 19, 62 | left: null, 63 | right: null 64 | } 65 | } 66 | }; 67 | 68 | levelOrderTraversal(root); // [ [ 15 ], [ 5, 17 ], [ 2, 4, 15, 19 ] ] 69 | -------------------------------------------------------------------------------- /problems/leetcode/trees/2.min_depth_of_tree.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a binary tree, find its minimum depth. 2 | 3 | Note 1: The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node. 4 | Note2: The path has to end on a leaf node 5 | 6 | Example: 7 | Input: { 8 | data: 1, 9 | left: { 10 | data: 2, 11 | left: null, 12 | right: null 13 | }, 14 | right: null 15 | } 16 | 17 | Output: 2 18 | 19 | Definition for a binary tree node: 20 | function TreeNode(A){ 21 | this.data = A 22 | this.left = null 23 | this.right = null 24 | } 25 | */ 26 | 27 | function minDepth(A) { 28 | var traverse = function(A) { 29 | if (!A) return 0; 30 | 31 | if (!A.left && !A.right) return 1; 32 | 33 | if (!A.left) return traverse(A.right) + 1; 34 | 35 | if (!A.right) return traverse(A.left) + 1; 36 | 37 | return 1 + Math.min(traverse(A.left), traverse(A.right)); 38 | }; 39 | 40 | return traverse(A); 41 | } 42 | 43 | minDepth({ 44 | data: 5, 45 | left: { data: 1, left: null, right: null }, 46 | right: { data: 2, left: null, right: null } 47 | }); // 2 48 | 49 | // Time Complexity: O(N) as we are traversing the tree only once 50 | -------------------------------------------------------------------------------- /problems/leetcode/trees/3.find_second_minimum_node.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a non-empty special binary tree consisting of nodes with the non-negative value, 2 | where each node in this tree has exactly two or zero sub-node. If the node has two sub-nodes, then this node's value is the smaller value among its two sub-nodes. 3 | 4 | Note: Given such a binary tree, you need to output the second minimum value in the set made of all the nodes' value in the whole tree. 5 | If no such second minimum value exists, output -1 instead. 6 | 7 | Example: 8 | 9 | Input: 10 | 2 11 | / \ 12 | 2 5 13 | / \ 14 | 4 7 15 | 16 | Output: 5 17 | 18 | Explanation: The smallest value is 2, the second smallest value is 5. 19 | */ 20 | 21 | 22 | function findSecondMinNode(root) { 23 | var left, right; 24 | 25 | if (!root.left) return -1; 26 | if (!root.right) return -1; 27 | 28 | if (root && root.left.val === root.val) { 29 | left = findSecondMinNode(root.left); 30 | } 31 | else { 32 | left = root.left.val; 33 | } 34 | 35 | if (root && root.right.val === root.val) { 36 | right = findSecondMinNode(root.right); 37 | } 38 | else { 39 | right = root.right.val; 40 | } 41 | 42 | if (left === -1 || right === -1) { 43 | return Math.max(left, right); 44 | } 45 | else { 46 | return Math.min(left, right); 47 | } 48 | } 49 | 50 | 51 | var root = { 52 | val: 2, 53 | left: { val: 2, right: null, left: null } 54 | right: { 55 | val: 5, left: { val: 5, right: null, left: null }, right: { val: 7, right: null, left: null } 56 | } 57 | }; 58 | 59 | findSecondMinNode(root); // 5 60 | 61 | // Time Complexity: O(N) 62 | -------------------------------------------------------------------------------- /problems/leetcode/trees/4.is_balanced_tree.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a binary tree, determine if it is height-balanced. 2 | 3 | Note: For this problem, a height-balanced binary tree is defined as: 4 | 5 | A binary tree in which the depth of the two subtrees of every node never differ by more than 1. 6 | 7 | Example 1: 8 | 3 9 | / \ 10 | 9 20 11 | / \ 12 | 15 7 13 | 14 | Ans: True 15 | 16 | Example 2: 17 | 18 | 1 19 | / \ 20 | 2 2 21 | / \ 22 | 3 3 23 | / \ 24 | 4 4 25 | 26 | Ans: False 27 | 28 | */ 29 | 30 | // Using Recursion 31 | var isBalanced = function(root) { 32 | var getHeight = function(root, height) { 33 | if (!root) return height; 34 | 35 | var leftTree = getHeight(root.left, height + 1); // +1 as we going down the tree 36 | var rightTree = getHeight(root.right, height + 1); // +1 as we going down the tree 37 | 38 | if (leftTree < 0 || rightTree < 0 || Math.abs(leftTree - rightTree) > 1) { 39 | return -1; // Math.abs to get positive number, incase if its in -ve number 40 | } 41 | 42 | return Math.max(leftTree, rightTree); // Get Max value 43 | }; 44 | 45 | // Initial height as 0 46 | return getHeight(root, 0) >= 0; // If retured value is >= 0 then it is binary tree with height balanced. 47 | }; 48 | 49 | var root1 = { 50 | val: 3, 51 | right: { 52 | val: 20, 53 | right: { val: 7, right: null, left: null }, 54 | left: { val: 15, right: null, left: null } 55 | }, 56 | left: { val: 9, right: null, left: null } 57 | }; 58 | 59 | isBalanced(root1); // True 60 | 61 | var root2 = { 62 | val: 3, 63 | right: { 64 | val: 20, 65 | right: { val: 7, right: null, left: null }, 66 | left: { val: 15, right: null, left: null } 67 | }, 68 | left: null 69 | }; 70 | 71 | isBalanced(root2); // False 72 | 73 | // Time Complexity: O(N) as we are traversing to N nodes to find its depth 74 | -------------------------------------------------------------------------------- /problems/leetcode/trees/5.check_tree_is_bst.js: -------------------------------------------------------------------------------- 1 | /* Problem: Check if given binary tree is BST or not. 2 | 3 | Note: Assume a BST is defined as follows: 4 | 5 | 1. The left subtree of a node contains only nodes with keys less than the node's key. 6 | 2. The right subtree of a node contains only nodes with keys greater than the node's key. 7 | 3. Both the left and right subtrees must also be binary search trees. 8 | 9 | Example 1: 10 | 9 11 | / \ 12 | 6 10 13 | / \ 14 | 7 12 15 | 16 | Output: True 17 | 18 | Example 2: 19 | 9 20 | / \ 21 | 6 10 22 | / \ 23 | 5 12 24 | 25 | Output: False 26 | */ 27 | 28 | // Idea here is traverse each node with max & min value 29 | 30 | var isBST = function (root) { 31 | if (!root) return true; 32 | var left = root.left; 33 | var right = root.right; 34 | if (left && root.val <= left.val) return false; 35 | if (right && root.val >= right.val) return false; 36 | if (!isBST(root.left) || !isBST(root.right)) return false; 37 | return true; 38 | }; 39 | 40 | var root = { 41 | val: 3, 42 | left: { val: 2, right: null, left: null }, 43 | right: { 44 | val: 5, 45 | left: { val: 4, right: null, left: null }, 46 | right: { val: 7, right: null, left: null } 47 | } 48 | }; 49 | 50 | isBST(root); // True 51 | 52 | var root = { 53 | val: 3, 54 | left: { val: 2, right: null, left: null }, 55 | right: { 56 | val: 5, 57 | left: { val: 19, right: null, left: null }, // val is > parent node 58 | right: { val: 7, right: null, left: null } 59 | } 60 | }; 61 | 62 | isBST(root); // False 63 | 64 | // Time Complexity: O(N) 65 | -------------------------------------------------------------------------------- /problems/leetcode/trees/6.lowest_common_ancestor_bst.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST. 2 | 3 | Note: According to the definition of LCA on Wikipedia: 4 | “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants 5 | (where we allow a node to be a descendant of itself).” 6 | 7 | Example: 8 | 9 | ______6_______ 10 | / \ 11 | ___2__ ___8__ 12 | / \ / \ 13 | 0 _4 7 9 14 | / \ 15 | 3 5 16 | 17 | Output: the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition. 18 | 19 | */ 20 | 21 | // Use the BST clue here to solve the question and do a iteration or recursion to get answer 22 | // p, q < root then values lies in left side of the root. 23 | // p,q > root then values lies in right side of root. 24 | // p is on left and q is on right, then root is the answer. 25 | 26 | var lowestCommonAncestor = function(root, p, q) { 27 | // p, q < root 28 | if (p.val < root.val && q.val < root.val) { 29 | return lowestCommonAncestor(root.left, p, q); 30 | } 31 | // p, q > root 32 | else if (p.val > root.val && q.val > root.val) { 33 | return lowestCommonAncestor(root.right, p, q); 34 | } 35 | // p, q on left and right of the root 36 | else { 37 | return root; 38 | } 39 | }; 40 | 41 | var root = { 42 | val: 6, 43 | left: { 44 | val: 2, 45 | left: { val: 0, right: null, left: null }, 46 | right: { 47 | val: 4, 48 | right: { val: 5, right: null, left: null }, 49 | left: { val: 3, right: null, left: null } 50 | } 51 | }, 52 | right: { 53 | val: 8, 54 | right: { left: null, val: 7, right: null }, 55 | left: { left: null, val: 9, right: null } 56 | } 57 | }; 58 | 59 | var p = { val: 2, left: null, right: null }; 60 | var q = { val: 4, left: null, right: null }; 61 | 62 | lowestCommonAncestor(root, p, q); 63 | 64 | // Time Complexity: O(N), N is number of nodes in tree 65 | -------------------------------------------------------------------------------- /problems/leetcode/trees/7.lowest_common_ancestor_bt.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the BT. 2 | 3 | Note: According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w 4 | as the lowest node in T that has both v and w as descendants (we can allow a node to be a descendant of itself too).” 5 | 6 | Example: 7 | 8 | ______6_______ 9 | / \ 10 | ___2__ ___8__ 11 | / \ / \ 12 | 0 _4 7 9 13 | / \ 14 | 3 5 15 | 16 | Output: the lowest common ancestor (LCA) of nodes 2 and 8 is 6. 17 | Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition. 18 | 19 | */ 20 | 21 | // Since BT is Not BST 22 | // Changing the little logic from BST LCA 23 | // Check for p & q value is == root.val 24 | // If so return root 25 | // if both left & right is found return root as both p & q resides on left and right of root; 26 | // else only left tree is found, return left tree or right tree (As per note) 27 | 28 | var lowestCommonAncestor = function(root, p, q) { 29 | if (!root) return; 30 | 31 | if (p.val === root.val || q.val === root.val) return root; 32 | 33 | var leftTree = lowestCommonAncestor(root.left, p, q); 34 | 35 | var rightTree = lowestCommonAncestor(root.right, p, q); 36 | 37 | if (leftTree && rightTree) return root; 38 | 39 | return leftTree ? leftTree : rightTree; 40 | }; 41 | 42 | var root = { 43 | val: 6, 44 | left: { 45 | val: 2, 46 | left: { val: 0, right: null, left: null }, 47 | right: { 48 | val: 4, 49 | right: { val: 5, right: null, left: null }, 50 | left: { val: 3, right: null, left: null } 51 | } 52 | }, 53 | right: { 54 | val: 8, 55 | right: { left: null, val: 7, right: null }, 56 | left: { left: null, val: 9, right: null } 57 | } 58 | }; 59 | 60 | var p = { val: 2, left: null, right: null }; 61 | var q = { val: 4, left: null, right: null }; 62 | 63 | lowestCommonAncestor(root, p, q); // { "val": 2, "left": { "val": 4, "right": { "val": 5, "right": null, "left": null }, "left": { "val": 3, "right": null, "left": null } } } 64 | 65 | // Time Complexity: O(N), N is number of nodes in tree 66 | -------------------------------------------------------------------------------- /problems/leetcode/trees/8.same_tree.js: -------------------------------------------------------------------------------- 1 | /* tree1roblem: Given two binary trees, write a function to check if they are the same or not. 2 | 3 | Note: Two binary trees are considered the same if they are structurally identical and the nodes have the same value. 4 | 5 | Example 1: 6 | Input: 1 1 7 | / \ / \ 8 | 2 3 2 3 9 | Output: true 10 | 11 | Example 2: 12 | Input: 1 1 13 | / \ 14 | 2 2 15 | Output: false 16 | */ 17 | 18 | // Using recursion 19 | var isSameTree = function (tree1, tree2) { 20 | if (tree1 == null && tree2 == null) return true; 21 | else if (tree1 == null || tree2 == null) return false; 22 | 23 | var traverse = function (tree1, tree2) { 24 | if (!tree1 && !tree2) return true; 25 | else if (!tree1 || !tree2) return false; 26 | else if (tree1.val !== tree2.val) return false; 27 | return traverse(tree1.left, tree2.left) && traverse(tree1.right, tree2.right); 28 | } 29 | 30 | return traverse(tree1, tree2); 31 | }; 32 | 33 | var tree1 = { val: 1, left: { val: 1, left: null, right: null }, right: null }; 34 | var tree2 = { val: 1, left: null, right: { val: 1, left: null, right: null } }; 35 | 36 | isSameTree(tree1, tree2); // False 37 | 38 | var tree1 = { val: 1, left: { val: 1, left: null, right: null }, right: null }; 39 | var tree2 = { val: 1, left: { val: 1, left: null, right: null }, right: null }; 40 | 41 | isSameTree(tree1, tree2); // True 42 | 43 | // Time Complexity: O(T1), where T1 is tree1 and T2 is tree2, where T1 < T2 44 | 45 | // Using iteration 46 | 47 | var isSameTree = function (p, q) { 48 | if (!p && !q) return true; 49 | else if (!p || !q) return false; 50 | var pArr = [p]; // insert p 51 | var qArr = [q]; // insert q 52 | // We are going to use Queue based DataStructure (FIFO) to solve in iteration 53 | while (pArr.length != 0 && qArr.length != 0) { 54 | var tempP = pArr[0]; // Get first value as its Queue 55 | var tempQ = qArr[0]; // Get first value as its Queue 56 | // If val is not equal no need to proceed further, return false 57 | if (tempP.val !== tempQ.val) return false; 58 | 59 | pArr.pop(); // Else its equal then remove from queue 60 | qArr.pop(); // Else its equal then remove from queue 61 | 62 | // if left node is present in both tree, push it else if present only in either of them return false 63 | if (tempP.left && tempQ.left) { 64 | pArr.push(tempP.left); 65 | qArr.push(tempQ.left); 66 | } 67 | else if (tempP.left || tempQ.left) return false; 68 | 69 | // if right node is present in both tree, push it else if present only in either of them return false 70 | if (tempP.right && tempQ.right) { 71 | pArr.push(tempP.right); 72 | qArr.push(tempQ.right); 73 | } 74 | else if (tempP.right || tempQ.right) return false; 75 | } 76 | 77 | return true; 78 | }; 79 | 80 | 81 | var tree1 = { val: 1, left: { val: 1, left: null, right: null }, right: null }; 82 | var tree2 = { val: 1, left: null, right: { val: 1, left: null, right: null } }; 83 | 84 | isSameTree(tree1, tree2); // False 85 | 86 | var tree1 = { val: 1, left: { val: 1, left: null, right: null }, right: null }; 87 | var tree2 = { val: 1, left: { val: 1, left: null, right: null }, right: null }; 88 | 89 | isSameTree(tree1, tree2); // True 90 | 91 | // Time Complexity: O(T1 + T2), T1, T2 is number of nodes in two tree 92 | -------------------------------------------------------------------------------- /problems/leetcode/trees/9.invert_binary_tree.js: -------------------------------------------------------------------------------- 1 | /* Problem: Invert the given binary Tree 2 | 3 | Example: 4 | 5 | Input: 6 | 4 7 | / \ 8 | 2 7 9 | / \ / \ 10 | 1 3 6 9 11 | 12 | Output: 13 | 4 14 | / \ 15 | 7 2 16 | / \ / \ 17 | 9 6 3 1 18 | */ 19 | 20 | var invertTree = function (root) { 21 | if (!root) return root; 22 | 23 | var traverse = function (root) { 24 | if (!root) return null; 25 | 26 | if (root.left && root.right) { 27 | var temp1 = root.left; 28 | var temp2 = root.right; 29 | root.left = temp2; 30 | root.right = temp1; 31 | } 32 | else if (root.left && !root.right) { 33 | root.right = root.left; 34 | root.left = null; 35 | } 36 | else if (!root.left && root.right) { 37 | root.left = root.right; 38 | root.right = null; 39 | } 40 | else { 41 | root.left = null; 42 | root.right = null; 43 | } 44 | 45 | 46 | traverse(root.left); 47 | traverse(root.right); 48 | } 49 | 50 | traverse(root); 51 | 52 | return root; 53 | }; 54 | 55 | var tree = { 56 | val: 2, right: null, left: { val: 3, right: null, left: { val: 1, right: null, left: null } } 57 | } 58 | 59 | invertTree(tree); // { "val": 2, "right": null, "left": { "val": 3, "right": null, "left": { "val": 1, "right": null, "left": null } } } 60 | 61 | // Time Complexity: O(N), N is number of nodes in binary tree 62 | -------------------------------------------------------------------------------- /problems/leetcode/trees/README.md: -------------------------------------------------------------------------------- 1 | # Trees 2 | 3 | 1. [Max Depth Of Tree](./1.max_depth_of_tree.js) 4 | 1. [Min Depth Of Tree](./2.min_depth_of_tree.js) 5 | 1. [Find Second Minimum Node](./3.find_second_minimum_node.js) 6 | 1. [Balanced Tree](./4.is_balanced_tree.js) 7 | 1. [Check Tree is BST](./5.check_tree_is_bst.js) 8 | 1. [Lowest Common Ancestor Of BST](./6.lowest_common_ancestor_bst.js) 9 | 1. [Lowest Common Ancestor Of BT](./7.lowest_common_ancestor_bt.js) 10 | 1. [Same Tree Or Not](./8.same_tree.js) 11 | 1. [Invert Binary Tree](./9.invert_binary_tree.js) 12 | 1. [Symmetric Tree](./10.symmetric_tree.js) 13 | 1. [Has Path Sum](./11.path_sum.js) 14 | 1. [Level Order Traversal](./12.level_order_traversal.js) 15 | -------------------------------------------------------------------------------- /problems/leetcode/trie/1.implement_trie_ds.js: -------------------------------------------------------------------------------- 1 | /* Problems: Implement a trie with insert, search, and startsWith methods. 2 | 3 | Example: 4 | Trie trie = new Trie(); 5 | trie.insert("apple"); 6 | trie.search("apple"); // returns true 7 | trie.search("app"); // returns false 8 | trie.startsWith("app"); // returns true 9 | trie.insert("app"); 10 | trie.search("app"); // returns true 11 | 12 | Note: 13 | - You may assume that all inputs are consist of lowercase letters a-z. 14 | - All inputs are guaranteed to be non-empty strings. 15 | 16 | Application: 17 | 18 | - Search Autocomplete (Google Search Autocomplete) 19 | - Spell Checker 20 | - Word Prediction 21 | 22 | Advantages; 23 | 24 | - Time Complexity: O(L), L is length of keys. 25 | - Apparently faster than BST 26 | 27 | Dis-Advantages: 28 | - Memory of trie. In the worst case, there is one node per character. 29 | 30 | */ 31 | 32 | var Trie = function() { 33 | this.tree = {}; 34 | }; 35 | 36 | Trie.prototype.insert = function(word) { 37 | var node = this.tree; 38 | 39 | for (var i = 0; i < word.length; i++) { 40 | node = node[word[i]] = node[word[i]] || {}; // So basically this will insert like {a: {b: {c: { isEnd: true }}}} 41 | } 42 | 43 | node.isEnd = true; 44 | }; 45 | 46 | Trie.prototype.search = function(word, isPrefix) { 47 | var node = this.tree; 48 | 49 | for (var i = 0; i < word.length; i++) { 50 | if (!node[word[i]]) return false; 51 | node = node[word[i]]; 52 | } 53 | 54 | return isPrefix || !!node.isEnd; 55 | }; 56 | 57 | Trie.prototype.startsWith = function(word) { 58 | return this.search(word, true); 59 | }; 60 | 61 | var t = new Trie(); 62 | t.insert('apple'); 63 | t.search('apple'); // returns true 64 | t.search('app'); // returns false 65 | t.startsWith('app'); // returns true 66 | t.insert('app'); 67 | t.search('app'); // returns true 68 | 69 | // Time Complexity: O(L), L is length of keys 70 | // Space Complexity: O(1) 71 | -------------------------------------------------------------------------------- /problems/leetcode/trie/README.md: -------------------------------------------------------------------------------- 1 | # Trie 2 | 3 | 1. [Implement Trie](./1.implement_trie_ds.js) 4 | -------------------------------------------------------------------------------- /problems/leetcode/two pointers/1.intersection_of_sorted_arrays.js: -------------------------------------------------------------------------------- 1 | /* Problem: Find the intersection of two sorted arrays or Given 2 sorted arrays, find all the elements which occur in both the arrays. 2 | 3 | Example: 4 | Input : 5 | A : [1 2 3 3 4 5 6] 6 | B : [3 3 5] 7 | 8 | Output : [3 3 5] 9 | 10 | Input : 11 | A : [1 2 3 3 4 5 6] 12 | B : [3 5] 13 | 14 | Output : [3 5] 15 | */ 16 | 17 | function findIntersection(A, B) { 18 | var temp = []; 19 | 20 | var pointer1 = 0; 21 | var pointer2 = 0; 22 | 23 | while (pointer1 < A.length && pointer2 < B.length) { 24 | if (A[pointer1] === B[pointer2]) { 25 | temp.push(A[pointer1]); 26 | pointer1++; 27 | pointer2++; 28 | } 29 | else if (A[pointer1] > B[pointer2]) { 30 | pointer2++; 31 | } 32 | else { 33 | pointer1++; 34 | } 35 | } 36 | 37 | return temp; 38 | } 39 | 40 | findIntersection([1, 2, 3, 3, 4, 5, 6, 6], [3, 5, 6]); // [3, 5, 6] 41 | findIntersection([1 2 3 3 4 5 6], [3 5]); // [3, 5] 42 | 43 | /* Complexity: 44 | 45 | Time Complexity: O(M+N), M = A, N = B 46 | 47 | */ 48 | -------------------------------------------------------------------------------- /problems/leetcode/two pointers/2.remove_duplicate_from_array-2.js: -------------------------------------------------------------------------------- 1 | /* Problem: Given a sorted array, remove the duplicates in place such that each element can appear atmost twice and return the new length. 2 | 3 | Note 1: Do not allocate extra space for another array, you must do this in place with constant memory. 4 | Note 2: Even though we want you to return the new length, make sure to change the original array as well in place. 5 | 6 | Example: 7 | 8 | Input: [1,1,1,2] 9 | Output: 3 and Input becomes [1, 1, 2] 10 | 11 | */ 12 | 13 | function removeDuplicates(A) { 14 | var count = 1; 15 | var pointer = 0; 16 | 17 | for (var i = 0; i < A.length; i++) { 18 | if (A[i] !== A[pointer]) { 19 | pointer++; 20 | A[pointer] = A[i]; 21 | count = 1; 22 | } 23 | else { 24 | if (count < 2) { 25 | pointer++; 26 | count++; 27 | A[pointer] = A[i]; 28 | } 29 | else continue; 30 | } 31 | } 32 | 33 | A.length = pointer + 1; // Setting the pointer length to remove moved elements 34 | 35 | return A.length; 36 | } 37 | 38 | removeDuplicates([1, 1, 1, 2]); // [1, 1, 2] 39 | removeDuplicates([1, 1, 1, 2, 3, 3, 3, 5, 5, 5, 6, 6, 6, 7, 7, 9]); // [1, 1, 2, 3, 3, 5, 5, 6, 6, 7, 7, 9] 40 | -------------------------------------------------------------------------------- /problems/leetcode/two pointers/3.intersection_of_unsorted_arrays.js: -------------------------------------------------------------------------------- 1 | /* Problem: Find the intersection of two arrays or Given 2 arrays, find all the elements which occur in both the arrays in same number of times. 2 | 3 | Note: Do it without sorting the array 4 | 5 | Example: 6 | Input : 7 | A : [1, 3, 2, 3] 8 | B : [1, 3, 3] 9 | 10 | Output : [1, 3, 3] 11 | */ 12 | 13 | // Using for loops and hashmap 14 | function findIntersection1(nums1, nums2) { 15 | var hash = {}; 16 | for (var i = 0; i < nums1.length; i++) { 17 | var num = nums1[i]; 18 | if (hash[num]) { 19 | hash[num] += 1 20 | } 21 | else { 22 | hash[num] = 1 23 | } 24 | } 25 | 26 | var temp = []; 27 | for (var i = 0; i < nums2.length; i++) { 28 | var num = nums2[i]; 29 | if (hash[num]) { 30 | hash[num]--; 31 | temp.push(num); 32 | } 33 | } 34 | 35 | return temp; 36 | }; 37 | 38 | findIntersection1([1, 3, 2, 3], [1, 3, 3, 2]); // [1, 3, 3, 2] 39 | 40 | // Using reduce and filter 41 | function findIntersection2(nums1, nums2) { 42 | var hash = nums1.reduce((hash, num) => { 43 | hash[num] = hash[num] ? hash[num] + 1 : 1; 44 | return hash; 45 | }, {}); 46 | 47 | var temp = nums2.filter((num) => { 48 | if (hash[num]) { 49 | hash[num]--; 50 | return true; 51 | } 52 | else return false; 53 | }); 54 | 55 | return temp; 56 | }; 57 | 58 | findIntersection2([1, 3, 2, 3], [1, 3, 3, 2]); // [1, 3, 3, 2] 59 | 60 | /* Complexity: 61 | 62 | Time Complexity: O(M+N) 63 | 64 | */ 65 | -------------------------------------------------------------------------------- /problems/leetcode/two pointers/4.shortest_distance_to_char.js: -------------------------------------------------------------------------------- 1 | /* Problem: Shortest Distance to a Character. 2 | 3 | Given a string S and a character C, return an array of integers representing the shortest distance from the character C in the string. 4 | 5 | Example 1: 6 | Input: S = "loveleetcode", C = 'e' 7 | 8 | Output: [3, 2, 1, 0, 1, 0, 0, 1, 2, 2, 1, 0] 9 | 10 | */ 11 | 12 | var shortestDistanceToChar = function(word, char) { 13 | var result = []; 14 | var count = word.length; 15 | 16 | for (var i = 0; i < word.length; i++) { 17 | if (word[i] === char) { 18 | count = 0; 19 | } else { 20 | count++; 21 | } 22 | 23 | result[i] = count; 24 | } 25 | 26 | for (var j = word.length - 1; i >= 0; i--) { 27 | if (word[i] === char) { 28 | count = 0; 29 | } else { 30 | count++; 31 | } 32 | 33 | result[i] = Math.min(count, result[i]); 34 | } 35 | 36 | return result; 37 | }; 38 | 39 | shortestDistanceToChar('loveleetcode', 'e'); // [3, 2, 1, 0, 1, 0, 0, 1, 2, 2, 1, 0] 40 | 41 | // Time Complexity: O(N), N is length of word. 42 | // Space Complexity: O(N), N is length of result array. 43 | -------------------------------------------------------------------------------- /problems/leetcode/two pointers/README.md: -------------------------------------------------------------------------------- 1 | # Two Pointers 2 | 3 | 1. [Intersection Of Sorted Arrays](./1.intersection_of_sorted_arrays.js) 4 | 1. [Remove Duplicates From Sorted Array](./2.remove_duplicate_from_array-2.js) 5 | 1. [Intersection Of Unsorted Arrays](./3.intersection_of_unsorted_arrays.js) 6 | 1. [Shortest Distance to a Character](./4.shortest_distance_to_char.js) 7 | -------------------------------------------------------------------------------- /problems/others/1.plant_in_garden.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokulkrishh/data-structures-and-algorithms/372961215d642c055e3ec831f19ba7e4265844e3/problems/others/1.plant_in_garden.js -------------------------------------------------------------------------------- /search/README.md: -------------------------------------------------------------------------------- 1 | # Search 2 | 3 | ## Table of Contents 4 | 5 | - [Binary Search](./binary_search.js) 6 | -------------------------------------------------------------------------------- /search/binary_search.js: -------------------------------------------------------------------------------- 1 | /* Problem: Binary Search 2 | 3 | **: Given array should be in sorted order in order for binary search work. 4 | 5 | Pseudo code: 6 | 7 | 1. Start with low and high index of arr. 8 | 2. if low <= high, iterate the arr based on condition 9 | 3. mid = low + high / 2 10 | 4. if target is same arr[mid], return mid index; 11 | 5. if target is > arr[mid] then target lies after the mid index, so increase low = mid + 1; 12 | 6 else target lies below mid index, so do high = mid - 1 13 | 7. If low becomes greater than high that means target is not present in given arr. 14 | 15 | */ 16 | 17 | function binarySearch(arr, target) { 18 | var low = 0; 19 | var high = arr.length; 20 | 21 | while (low <= high) { 22 | var mid = Math.floor((low + high) / 2); 23 | 24 | if (target === arr[mid]) { 25 | return mid; 26 | } 27 | 28 | if (target > arr[mid]) { 29 | low = mid + 1; 30 | } else { 31 | high = mid - 1; 32 | } 33 | } 34 | 35 | return -1; 36 | } 37 | 38 | binarySearch([1, 2, 3, 4, 6, 8, 9, 11, 12], 9); // 6 39 | 40 | // Time Complexity: O(log n) 41 | // Space Complexity: O(1) 42 | -------------------------------------------------------------------------------- /sorting/1.insertion_sort.js: -------------------------------------------------------------------------------- 1 | /* Problem: Insertion Sort 2 | 3 | Pseudo code: 4 | 5 | 1. Start from index 1 to n - 1 in two loops 6 | 2. Compare i - 1 in array with next element, If previous element is > next element, 7 | 3. Swap the small element with next bigger element. 8 | 9 | */ 10 | 11 | function insertionSort(arr) { 12 | for (var i = 1; i < arr.length; i++) { 13 | var current = arr[i]; 14 | for (var j = i - 1; j >= 0 && arr[j] > current; j--) { 15 | arr[j + 1] = arr[j]; 16 | } 17 | arr[j + 1] = current; 18 | } 19 | 20 | return arr; 21 | } 22 | 23 | insertionSort([3, 5, 4, 1, 2]); // [1, 2, 3, 4, 5] 24 | 25 | // Time Complexity: O(N^2) 26 | // Space Complexity: O(1) 27 | -------------------------------------------------------------------------------- /sorting/2.selection_sort.js: -------------------------------------------------------------------------------- 1 | /* Problem: Selection Sort 2 | 3 | Pseudo code: 4 | 5 | 1. Start from index = 0 to n - 1 in two loops 6 | 2. Compare the currentIndex element with nextIndex element. 7 | 3. If currentIndex element > nextIndex element, swap positions 8 | 4. Repeat step 2 & 3 until the array is sorted. 9 | 10 | */ 11 | 12 | function selectionSort(arr) { 13 | for (var i = 0; i < arr.length; i++) { 14 | for (var j = i + 1; j < arr.length; j++) { 15 | if (arr[i] > arr[j]) { 16 | var temp = arr[i]; 17 | arr[i] = arr[j]; 18 | arr[j] = temp; 19 | } 20 | } 21 | } 22 | 23 | return arr; 24 | } 25 | 26 | selectionSort([3, 5, 4, 2, 1]); // [1, 2, 3, 4, 5] 27 | 28 | // Time Complexity: O(N^2) 29 | // Space Complexity: O(1) 30 | -------------------------------------------------------------------------------- /sorting/3.bubble_sort.js: -------------------------------------------------------------------------------- 1 | /* Problem: Bubble Sort 2 | 3 | Pseudo code: 4 | 5 | 1. Start from index 0 to n - 1 in two loops 6 | 2. Compare the currentIndex element with nextIndex element, 7 | 3. If currentIndex element > nextIndex element, swap positions. 8 | 4. If no swapping break the outer loop. 9 | 5. Repeat step 2, 3, 5 until the array is sorted. 10 | 11 | */ 12 | 13 | function bubbleSort(arr) { 14 | var swap = false; 15 | 16 | for (var i = 0; i < arr.length; i++) { 17 | for (var j = 0; j < arr.length; j++) { 18 | if (arr[j] > arr[j + 1]) { 19 | var temp = arr[j + 1]; 20 | arr[j + 1] = arr[j]; 21 | arr[j] = temp; 22 | } 23 | } 24 | 25 | if (!swap) break; 26 | } 27 | 28 | return arr; 29 | } 30 | 31 | bubbleSort([3, 4, 5, 2, 1]); 32 | 33 | // Time Complexity: O(N^2) 34 | // Space Complexity: O(1) 35 | -------------------------------------------------------------------------------- /sorting/4.merge_sort.js: -------------------------------------------------------------------------------- 1 | /* Problem: Merge Sort 2 | 3 | Pseudo code: 4 | 5 | 1. Divide the array into 2 sub array halves. (Divide and Conquer) 6 | 2. If array length is < 2, then it is already sorted, So return it. 7 | 2. Sort each sub array halves recursively by calling mergeSort() again. 8 | 3. Then merge two sub array into one sorted array using doSorting() method. 9 | 10 | */ 11 | 12 | function mergeSort(arr) { 13 | if (arr.length < 2) { 14 | return arr; 15 | } 16 | 17 | var median = Math.floor(arr.length / 2); 18 | 19 | var leftArr = arr.slice(0, median); 20 | var arrRight = arr.slice(median, arr.length); 21 | 22 | return doSorting(mergeSort(leftArr), mergeSort(arrRight)); 23 | 24 | function doSorting(arrLeft, arrRight) { 25 | var tempArr = []; 26 | 27 | while (arrLeft.length && arrRight.length) { 28 | if (arrLeft[0] > arrRight[0]) { 29 | tempArr.push(arrRight.shift()); 30 | } else { 31 | tempArr.push(arrLeft.shift()); 32 | } 33 | } 34 | 35 | while (arrLeft.length) { 36 | tempArr.push(arrLeft.shift()); 37 | } 38 | 39 | while (arrRight.length) { 40 | tempArr.push(arrRight.shift()); 41 | } 42 | 43 | return tempArr; 44 | } 45 | } 46 | 47 | mergeSort([5, 3, 2, 4, 1]); // [1, 2, 3, 4, 5] 48 | 49 | // Time Complexity: O(N Log N) 50 | // Space Complexity: O(N) 51 | -------------------------------------------------------------------------------- /sorting/README.md: -------------------------------------------------------------------------------- 1 | # Sorting Algorithms 2 | 3 | ## Table of Contents 4 | 5 | 1. [Insertion Sort](./1.insertion_sort.js) 6 | 1. [Selection Sort](./2.selection_sort.js) 7 | 1. [Bubble Sort](./3.bubble_sort.js) 8 | 1. [Merge Sort](./4.merge_sort.js) 9 | -------------------------------------------------------------------------------- /tree/README.md: -------------------------------------------------------------------------------- 1 | # Tree 2 | 3 | Unlike Array, LinkedList, Stack, Queues which are linear data structures, trees are hierarchical data structures. 4 | 5 | ![Tree](./images/tree.jpg) 6 | 7 | ### Example: 8 | 9 | #### Binary Tree 10 | 11 | A tree with at most 2 children is called a binary tree. A binary tree can have only two children. 12 | 13 | ![Binary Tree](./images/binary-tree.png) 14 | 15 | #### A Binary Tree node contains 16 | 17 | 1. Data 18 | 1. Pointer to left child 19 | 1. Pointer to right child 20 | -------------------------------------------------------------------------------- /tree/images/binary-tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokulkrishh/data-structures-and-algorithms/372961215d642c055e3ec831f19ba7e4265844e3/tree/images/binary-tree.png -------------------------------------------------------------------------------- /tree/images/tree.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gokulkrishh/data-structures-and-algorithms/372961215d642c055e3ec831f19ba7e4265844e3/tree/images/tree.jpg --------------------------------------------------------------------------------