├── .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 | 
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 | 
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 | 
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 | 
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 | 
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 | 
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
--------------------------------------------------------------------------------