diff --git a/README.md b/README.md index 74584fdf..7772719c 100644 --- a/README.md +++ b/README.md @@ -178,6 +178,7 @@ | | | | | | |-|-|-|-|-|- +| 0309 |[Best Time to Buy and Sell Stock with Cooldown](src/main/kotlin/g0301_0400/s0309_best_time_to_buy_and_sell_stock_with_cooldown)| Medium | Array, Dynamic_Programming | 272 | 73.33 #### Day 9 @@ -216,6 +217,7 @@ | | | | | | |-|-|-|-|-|- +| 0304 |[Range Sum Query 2D - Immutable](src/main/kotlin/g0301_0400/s0304_range_sum_query_2d_immutable)| Medium | Array, Matrix, Design, Prefix_Sum | 1373 | 85.71 #### Day 15 @@ -330,6 +332,7 @@ | | | | | | |-|-|-|-|-|- +| 0303 |[Range Sum Query - Immutable](src/main/kotlin/g0301_0400/s0303_range_sum_query_immutable)| Easy | Array, Design, Prefix_Sum | 472 | 63.64 ### Programming Skills II @@ -409,6 +412,7 @@ | | | | | | |-|-|-|-|-|- +| 0304 |[Range Sum Query 2D - Immutable](src/main/kotlin/g0301_0400/s0304_range_sum_query_2d_immutable)| Medium | Array, Matrix, Design, Prefix_Sum | 1373 | 85.71 #### Day 14 @@ -703,6 +707,7 @@ | | | | | | |-|-|-|-|-|- +| 0328 |[Odd Even Linked List](src/main/kotlin/g0301_0400/s0328_odd_even_linked_list)| Medium | Top_Interview_Questions, Linked_List | 216 | 86.96 | 0148 |[Sort List](src/main/kotlin/g0101_0200/s0148_sort_list)| Medium | Top_100_Liked_Questions, Top_Interview_Questions, Sorting, Two_Pointers, Linked_List, Divide_and_Conquer, Merge_Sort | 820 | 61.70 #### Day 5 Greedy @@ -892,6 +897,7 @@ | | | | | | |-|-|-|-|-|- +| 0304 |[Range Sum Query 2D - Immutable](src/main/kotlin/g0301_0400/s0304_range_sum_query_2d_immutable)| Medium | Array, Matrix, Design, Prefix_Sum | 1373 | 85.71 | 0074 |[Search a 2D Matrix](src/main/kotlin/g0001_0100/s0074_search_a_2d_matrix)| Medium | Top_100_Liked_Questions, Array, Binary_Search, Matrix | 290 | 40.17 | 0054 |[Spiral Matrix](src/main/kotlin/g0001_0100/s0054_spiral_matrix)| Medium | Top_Interview_Questions, Array, Matrix, Simulation | 224 | 62.50 | 0048 |[Rotate Image](src/main/kotlin/g0001_0100/s0048_rotate_image)| Medium | Top_100_Liked_Questions, Top_Interview_Questions, Array, Math, Matrix | 287 | 46.50 @@ -903,6 +909,7 @@ | | | | | | |-|-|-|-|-|- | 0114 |[Flatten Binary Tree to Linked List](src/main/kotlin/g0101_0200/s0114_flatten_binary_tree_to_linked_list)| Medium | Top_100_Liked_Questions, Depth_First_Search, Tree, Binary_Tree, Stack, Linked_List | 191 | 93.10 +| 0328 |[Odd Even Linked List](src/main/kotlin/g0301_0400/s0328_odd_even_linked_list)| Medium | Top_Interview_Questions, Linked_List | 216 | 86.96 | 0061 |[Rotate List](src/main/kotlin/g0001_0100/s0061_rotate_list)| Medium | Two_Pointers, Linked_List | 193 | 92.16 | 0024 |[Swap Nodes in Pairs](src/main/kotlin/g0001_0100/s0024_swap_nodes_in_pairs)| Medium | Top_100_Liked_Questions, Linked_List, Recursion | 149 | 99.39 | 0142 |[Linked List Cycle II](src/main/kotlin/g0101_0200/s0142_linked_list_cycle_ii)| Medium | Top_100_Liked_Questions, Hash_Table, Two_Pointers, Linked_List | 192 | 63.39 @@ -1559,7 +1566,27 @@ | 0378 |[Kth Smallest Element in a Sorted Matrix](src/main/kotlin/g0301_0400/s0378_kth_smallest_element_in_a_sorted_matrix)| Medium | Top_Interview_Questions, Array, Sorting, Binary_Search, Matrix, Heap_Priority_Queue | 522 | 59.78 | 0347 |[Top K Frequent Elements](src/main/kotlin/g0301_0400/s0347_top_k_frequent_elements)| Medium | Top_100_Liked_Questions, Top_Interview_Questions, Array, Hash_Table, Sorting, Heap_Priority_Queue, Counting, Divide_and_Conquer, Quickselect, Bucket_Sort, Data_Structure_II_Day_20_Heap_Priority_Queue | 268 | 99.74 | 0338 |[Counting Bits](src/main/kotlin/g0301_0400/s0338_counting_bits)| Easy | Top_100_Liked_Questions, Dynamic_Programming, Bit_Manipulation, Udemy_Bit_Manipulation | 186 | 99.26 +| 0330 |[Patching Array](src/main/kotlin/g0301_0400/s0330_patching_array)| Hard | Array, Greedy | 201 | 100.00 +| 0329 |[Longest Increasing Path in a Matrix](src/main/kotlin/g0301_0400/s0329_longest_increasing_path_in_a_matrix)| Hard | Top_Interview_Questions, Dynamic_Programming, Depth_First_Search, Breadth_First_Search, Graph, Memoization, Topological_Sort | 322 | 92.65 +| 0328 |[Odd Even Linked List](src/main/kotlin/g0301_0400/s0328_odd_even_linked_list)| Medium | Top_Interview_Questions, Linked_List, Level_2_Day_4_Linked_List, Udemy_Linked_List | 216 | 86.96 +| 0327 |[Count of Range Sum](src/main/kotlin/g0301_0400/s0327_count_of_range_sum)| Hard | Array, Binary_Search, Ordered_Set, Divide_and_Conquer, Segment_Tree, Binary_Indexed_Tree, Merge_Sort | 638 | 100.00 +| 0326 |[Wiggle Sort II](src/main/kotlin/g0301_0400/s0326_power_of_three)| Easy | Top_Interview_Questions, Math, Recursion | 413 | 76.12 +| 0324 |[Wiggle Sort II](src/main/kotlin/g0301_0400/s0324_wiggle_sort_ii)| Medium | Top_Interview_Questions, Array, Sorting, Divide_and_Conquer, Quickselect | 545 | 57.14 | 0322 |[Coin Change](src/main/kotlin/g0301_0400/s0322_coin_change)| Medium | Top_100_Liked_Questions, Top_Interview_Questions, Array, Dynamic_Programming, Breadth_First_Search, Algorithm_II_Day_18_Dynamic_Programming, Dynamic_Programming_I_Day_20, Level_2_Day_12_Dynamic_Programming | 332 | 50.68 +| 0321 |[Create Maximum Number](src/main/kotlin/g0301_0400/s0321_create_maximum_number)| Hard | Greedy, Stack, Monotonic_Stack | 209 | 100.00 +| 0319 |[Bulb Switcher](src/main/kotlin/g0301_0400/s0319_bulb_switcher)| Medium | Math, Brainteaser | 214 | 77.78 +| 0318 |[Maximum Product of Word Lengths](src/main/kotlin/g0301_0400/s0318_maximum_product_of_word_lengths)| Medium | Array, String, Bit_Manipulation | 477 | 100.00 +| 0316 |[Remove Duplicate Letters](src/main/kotlin/g0301_0400/s0316_remove_duplicate_letters)| Medium | String, Greedy, Stack, Monotonic_Stack | 291 | 81.82 +| 0315 |[Count of Smaller Numbers After Self](src/main/kotlin/g0301_0400/s0315_count_of_smaller_numbers_after_self)| Hard | Top_Interview_Questions, Array, Binary_Search, Ordered_Set, Divide_and_Conquer, Segment_Tree, Binary_Indexed_Tree, Merge_Sort | 1282 | 88.46 +| 0313 |[Super Ugly Number](src/main/kotlin/g0301_0400/s0313_super_ugly_number)| Medium | Array, Dynamic_Programming, Math | 330 | 100.00 +| 0312 |[Burst Balloons](src/main/kotlin/g0301_0400/s0312_burst_balloons)| Hard | Array, Dynamic_Programming | 210 | 100.00 +| 0310 |[Minimum Height Trees](src/main/kotlin/g0301_0400/s0310_minimum_height_trees)| Medium | Depth_First_Search, Breadth_First_Search, Graph, Topological_Sort | 521 | 97.56 +| 0309 |[Best Time to Buy and Sell Stock with Cooldown](src/main/kotlin/g0301_0400/s0309_best_time_to_buy_and_sell_stock_with_cooldown)| Medium | Array, Dynamic_Programming, Dynamic_Programming_I_Day_8 | 272 | 73.33 +| 0307 |[Range Sum Query - Mutable](src/main/kotlin/g0301_0400/s0307_range_sum_query_mutable)| Medium | Array, Design, Segment_Tree, Binary_Indexed_Tree | 1729 | 78.79 +| 0306 |[Additive Number](src/main/kotlin/g0301_0400/s0306_additive_number)| Medium | String, Backtracking | 289 | 22.22 +| 0304 |[Range Sum Query 2D - Immutable](src/main/kotlin/g0301_0400/s0304_range_sum_query_2d_immutable)| Medium | Array, Matrix, Design, Prefix_Sum, Dynamic_Programming_I_Day_14, Programming_Skills_II_Day_13, Udemy_2D_Arrays/Matrix | 1373 | 85.71 +| 0303 |[Range Sum Query - Immutable](src/main/kotlin/g0301_0400/s0303_range_sum_query_immutable)| Easy | Array, Design, Prefix_Sum, Programming_Skills_I_Day_12_Class_and_Object | 472 | 63.64 +| 0301 |[Remove Invalid Parentheses](src/main/kotlin/g0301_0400/s0301_remove_invalid_parentheses)| Hard | String, Breadth_First_Search, Backtracking | 312 | 100.00 | 0300 |[Longest Increasing Subsequence](src/main/kotlin/g0201_0300/s0300_longest_increasing_subsequence)| Medium | Top_100_Liked_Questions, Top_Interview_Questions, Array, Dynamic_Programming, Binary_Search, Algorithm_II_Day_16_Dynamic_Programming, Binary_Search_II_Day_3, Dynamic_Programming_I_Day_18, Udemy_Dynamic_Programming | 318 | 82.28 | 0299 |[Bulls and Cows](src/main/kotlin/g0201_0300/s0299_bulls_and_cows)| Medium | String, Hash_Table, Counting, Level_1_Day_13_Hashmap | 254 | 84.82 | 0297 |[Serialize and Deserialize Binary Tree](src/main/kotlin/g0201_0300/s0297_serialize_and_deserialize_binary_tree)| Hard | Top_Interview_Questions, String, Depth_First_Search, Breadth_First_Search, Tree, Binary_Tree, Design, Data_Structure_II_Day_18_Tree, Udemy_Tree_Stack_Queue | 475 | 78.85 diff --git a/src/main/kotlin/g0301_0400/s0301_remove_invalid_parentheses/readme.md b/src/main/kotlin/g0301_0400/s0301_remove_invalid_parentheses/readme.md new file mode 100644 index 00000000..da6c3a17 --- /dev/null +++ b/src/main/kotlin/g0301_0400/s0301_remove_invalid_parentheses/readme.md @@ -0,0 +1,121 @@ +[![](https://img.shields.io/github/stars/javadev/LeetCode-in-Kotlin?label=Stars&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin) +[![](https://img.shields.io/github/forks/javadev/LeetCode-in-Kotlin?label=Fork%20me%20on%20GitHub%20&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin/fork) + +## 301\. Remove Invalid Parentheses + +Hard + +Given a string `s` that contains parentheses and letters, remove the minimum number of invalid parentheses to make the input string valid. + +Return _all the possible results_. You may return the answer in **any order**. + +**Example 1:** + +**Input:** s = "()())()" + +**Output:** ["(())()","()()()"] + +**Example 2:** + +**Input:** s = "(a)())()" + +**Output:** ["(a())()","(a)()()"] + +**Example 3:** + +**Input:** s = ")(" + +**Output:** [""] + +**Constraints:** + +* `1 <= s.length <= 25` +* `s` consists of lowercase English letters and parentheses `'('` and `')'`. +* There will be at most `20` parentheses in `s`. + +## Solution + +```kotlin +@Suppress("NAME_SHADOWING") +class Solution { + fun removeInvalidParentheses(s: String): List { + val res: MutableList = ArrayList() + // reversed+inverted + val ri = false + dfs(s, 0, 0, res, ri) + return res + } + + // BASIC IDEA: find prefix w/ extra ")". + // THEN use for loop to delete ")"s inside prefix, making recursive calls on the ENTIRE STRING + // b/c you don't know where the next ")" will be deleted. + private fun dfs(s: String, deletionSearch: Int, stackSearch: Int, res: MutableList, ri: Boolean) { + // functions imilarly to LC20. Valid Parenthesis, -1 for ")" and +1 for "(" + var s = s + var deletionSearch = deletionSearch + var stack = 0 + // see recursive call for explanation + var p = stackSearch + while (p < s.length && stack >= 0) { + if (s[p] == ')') { + stack-- + } + if (s[p] == '(') { + stack++ + } + p++ + } + if (stack < 0) { + // p already goes beyond the prefix by +1 + val prefix = s.substring(0, p) + // remove extra ")" from prefix + for (i in deletionSearch until prefix.length) { + // find last ")" in ")))...)" to avoid duplicates + if (s[i] == ')' && (i == prefix.length - 1 || s[i + 1] != ')')) { + // remove s.charAt(i) and recurse + // NOTE: p-1 b/c after you make a deletion, you know that the prefix is valid, + // so there's no point in recounting ")" + // NOTE: p-1 is the start index for COUNTING ")" in the recursive call, not for + // DELETIONS. + // Think of the DELETION index as SEPARATE from the COUNTING/STACK index. + dfs(s.substring(0, i) + s.substring(i + 1), deletionSearch, p - 1, res, ri) + // for next iteration, can only search BEYOND i in recursive calls for the ")" + // to delete + deletionSearch = i + 1 + } + } + } else { + // no extra ")" found + // repeat for "(" + if (!ri) { + // reverse + invert + s = reverseInvert(s) + // call again + dfs(s, 0, 0, res, true) + } else { + // done with both ")" and "(" + // revert to original arr + s = reverseInvert(s) + res.add(s) + } + } + } + + // reverses and inverts to accomplish r->l scan + private fun reverseInvert(s: String): String { + val sb = StringBuilder() + // invert + for (c in s.toCharArray()) { + if (c == '(') { + sb.append(')') + } else if (c == ')') { + sb.append('(') + } else { + sb.append(c) + } + } + // reverse + return sb.reverse().toString() + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0301_0400/s0303_range_sum_query_immutable/readme.md b/src/main/kotlin/g0301_0400/s0303_range_sum_query_immutable/readme.md new file mode 100644 index 00000000..33818f90 --- /dev/null +++ b/src/main/kotlin/g0301_0400/s0303_range_sum_query_immutable/readme.md @@ -0,0 +1,61 @@ +[![](https://img.shields.io/github/stars/javadev/LeetCode-in-Kotlin?label=Stars&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin) +[![](https://img.shields.io/github/forks/javadev/LeetCode-in-Kotlin?label=Fork%20me%20on%20GitHub%20&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin/fork) + +## 303\. Range Sum Query - Immutable + +Easy + +Given an integer array `nums`, handle multiple queries of the following type: + +1. Calculate the **sum** of the elements of `nums` between indices `left` and `right` **inclusive** where `left <= right`. + +Implement the `NumArray` class: + +* `NumArray(int[] nums)` Initializes the object with the integer array `nums`. +* `int sumRange(int left, int right)` Returns the **sum** of the elements of `nums` between indices `left` and `right` **inclusive** (i.e. `nums[left] + nums[left + 1] + ... + nums[right]`). + +**Example 1:** + +**Input** ["NumArray", "sumRange", "sumRange", "sumRange"] [[[-2, 0, 3, -5, 2, -1]], [0, 2], [2, 5], [0, 5]] + +**Output:** [null, 1, -1, -3] + +**Explanation:** NumArray numArray = new NumArray([-2, 0, 3, -5, 2, -1]); numArray.sumRange(0, 2); // return (-2) + 0 + 3 = 1 numArray.sumRange(2, 5); // return 3 + (-5) + 2 + (-1) = -1 numArray.sumRange(0, 5); // return (-2) + 0 + 3 + (-5) + 2 + (-1) = -3 + +**Constraints:** + +* 1 <= nums.length <= 104 +* -105 <= nums[i] <= 105 +* `0 <= left <= right < nums.length` +* At most 104 calls will be made to `sumRange`. + +## Solution + +```kotlin +class NumArray(nums: IntArray) { + private val sums: IntArray + + init { + sums = IntArray(nums.size) + for (i in nums.indices) { + if (i == 0) { + sums[i] = nums[i] + } else { + sums[i] = sums[i - 1] + nums[i] + } + } + } + + fun sumRange(i: Int, j: Int): Int { + return if (i == 0) { + sums[j] + } else sums[j] - sums[i - 1] + } +} + +/* + * Your NumArray object will be instantiated and called as such: + * var obj = NumArray(nums) + * var param_1 = obj.sumRange(left,right) + */ +``` \ No newline at end of file diff --git a/src/main/kotlin/g0301_0400/s0304_range_sum_query_2d_immutable/readme.md b/src/main/kotlin/g0301_0400/s0304_range_sum_query_2d_immutable/readme.md new file mode 100644 index 00000000..aa47557c --- /dev/null +++ b/src/main/kotlin/g0301_0400/s0304_range_sum_query_2d_immutable/readme.md @@ -0,0 +1,73 @@ +[![](https://img.shields.io/github/stars/javadev/LeetCode-in-Kotlin?label=Stars&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin) +[![](https://img.shields.io/github/forks/javadev/LeetCode-in-Kotlin?label=Fork%20me%20on%20GitHub%20&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin/fork) + +## 304\. Range Sum Query 2D - Immutable + +Medium + +Given a 2D matrix `matrix`, handle multiple queries of the following type: + +* Calculate the **sum** of the elements of `matrix` inside the rectangle defined by its **upper left corner** `(row1, col1)` and **lower right corner** `(row2, col2)`. + +Implement the NumMatrix class: + +* `NumMatrix(int[][] matrix)` Initializes the object with the integer matrix `matrix`. +* `int sumRegion(int row1, int col1, int row2, int col2)` Returns the **sum** of the elements of `matrix` inside the rectangle defined by its **upper left corner** `(row1, col1)` and **lower right corner** `(row2, col2)`. + +**Example 1:** + +![](https://assets.leetcode.com/uploads/2021/03/14/sum-grid.jpg) + +**Input** + + ["NumMatrix", "sumRegion", "sumRegion", "sumRegion"] + [[[[3, 0, 1, 4, 2], [5, 6, 3, 2, 1], [1, 2, 0, 1, 5], [4, 1, 0, 1, 7], [1, 0, 3, 0, 5]]], [2, 1, 4, 3], [1, 1, 2, 2], [1, 2, 2, 4]] + +**Output:** [null, 8, 11, 12] + +**Explanation:** + + NumMatrix numMatrix = new NumMatrix([[3, 0, 1, 4, 2], [5, 6, 3, 2, 1], [1, 2, 0, 1, 5], [4, 1, 0, 1, 7], [1, 0, 3, 0, 5]]); + numMatrix.sumRegion(2, 1, 4, 3); // return 8 (i.e sum of the red rectangle) + numMatrix.sumRegion(1, 1, 2, 2); // return 11 (i.e sum of the green rectangle) + numMatrix.sumRegion(1, 2, 2, 4); // return 12 (i.e sum of the blue rectangle) + +**Constraints:** + +* `m == matrix.length` +* `n == matrix[i].length` +* `1 <= m, n <= 200` +* -105 <= matrix[i][j] <= 105 +* `0 <= row1 <= row2 < m` +* `0 <= col1 <= col2 < n` +* At most 104 calls will be made to `sumRegion`. + +## Solution + +```kotlin +class NumMatrix(matrix: Array) { + + private val M = matrix.size + private val N = if (M > 0) matrix[0].size else 0 + + var array = Array (M + 1) { IntArray(N + 1) } + + init { + for (i in 1..M) { + for (j in 1..N) { + array[i][j] = matrix[i - 1][j - 1] + array[i][j - 1] + array[i - 1][j] - array[i - 1][j - 1] + } + } + } + + fun sumRegion(row1: Int, col1: Int, row2: Int, col2: Int): Int { + return array[row2 + 1][col2 + 1] - array[row2 + 1][col1] - array[row1][col2 + 1] + array[row1][col1] + } +} + +/* + * Your NumMatrix object will be instantiated and called as such: + * var obj = NumMatrix(matrix) + * var param_1 = obj.sumRegion(row1,col1,row2,col2) + */ +``` \ No newline at end of file diff --git a/src/main/kotlin/g0301_0400/s0306_additive_number/readme.md b/src/main/kotlin/g0301_0400/s0306_additive_number/readme.md new file mode 100644 index 00000000..f5d8ee77 --- /dev/null +++ b/src/main/kotlin/g0301_0400/s0306_additive_number/readme.md @@ -0,0 +1,73 @@ +[![](https://img.shields.io/github/stars/javadev/LeetCode-in-Kotlin?label=Stars&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin) +[![](https://img.shields.io/github/forks/javadev/LeetCode-in-Kotlin?label=Fork%20me%20on%20GitHub%20&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin/fork) + +## 306\. Additive Number + +Medium + +An **additive number** is a string whose digits can form an **additive sequence**. + +A valid **additive sequence** should contain **at least** three numbers. Except for the first two numbers, each subsequent number in the sequence must be the sum of the preceding two. + +Given a string containing only digits, return `true` if it is an **additive number** or `false` otherwise. + +**Note:** Numbers in the additive sequence **cannot** have leading zeros, so sequence `1, 2, 03` or `1, 02, 3` is invalid. + +**Example 1:** + +**Input:** "112358" + +**Output:** true + +**Explanation:** The digits can form an additive sequence: 1, 1, 2, 3, 5, 8. 1 + 1 = 2, 1 + 2 = 3, 2 + 3 = 5, 3 + 5 = 8 + +**Example 2:** + +**Input:** "199100199" + +**Output:** true + +**Explanation:** The additive sequence is: 1, 99, 100, 199. 1 + 99 = 100, 99 + 100 = 199 + +**Constraints:** + +* `1 <= num.length <= 35` +* `num` consists only of digits. + +**Follow up:** How would you handle overflow for very large input integers? + +## Solution + +```kotlin +class Solution { + fun isAdditiveNumber(num: String): Boolean { + if (num.isEmpty() || num.length < 3) { + return false + } + + fun isInvalid(s: String): Boolean { + return s[0] == '0' && s.length > 1 + } + + fun backtrack(first: Long, second: Long, startIndex: Int): Boolean { + val third = (first + second).toString() + if (num.substring(startIndex).startsWith(third)) { + if (third.length == num.length - startIndex) return true + return backtrack(second, third.toLong(), startIndex + third.length) + } + return false + } + + for (i in 1 until num.length) { + val first = num.substring(0, i) + if (isInvalid(first)) break + for (j in i + 1 until num.length) { + val second = num.substring(i, j) + if (isInvalid(second)) break + if (backtrack(first.toLong(), second.toLong(), j)) return true + } + } + return false + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0301_0400/s0307_range_sum_query_mutable/readme.md b/src/main/kotlin/g0301_0400/s0307_range_sum_query_mutable/readme.md new file mode 100644 index 00000000..36b4ad10 --- /dev/null +++ b/src/main/kotlin/g0301_0400/s0307_range_sum_query_mutable/readme.md @@ -0,0 +1,81 @@ +[![](https://img.shields.io/github/stars/javadev/LeetCode-in-Kotlin?label=Stars&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin) +[![](https://img.shields.io/github/forks/javadev/LeetCode-in-Kotlin?label=Fork%20me%20on%20GitHub%20&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin/fork) + +## 307\. Range Sum Query - Mutable + +Medium + +Given an integer array `nums`, handle multiple queries of the following types: + +1. **Update** the value of an element in `nums`. +2. Calculate the **sum** of the elements of `nums` between indices `left` and `right` **inclusive** where `left <= right`. + +Implement the `NumArray` class: + +* `NumArray(int[] nums)` Initializes the object with the integer array `nums`. +* `void update(int index, int val)` **Updates** the value of `nums[index]` to be `val`. +* `int sumRange(int left, int right)` Returns the **sum** of the elements of `nums` between indices `left` and `right` **inclusive** (i.e. `nums[left] + nums[left + 1] + ... + nums[right]`). + +**Example 1:** + +**Input** ["NumArray", "sumRange", "update", "sumRange"] [[[1, 3, 5]], [0, 2], [1, 2], [0, 2]] + +**Output:** [null, 9, null, 8] + +**Explanation:** NumArray numArray = new NumArray([1, 3, 5]); numArray.sumRange(0, 2); // return 1 + 3 + 5 = 9 numArray.update(1, 2); // nums = [1, 2, 5] numArray.sumRange(0, 2); // return 1 + 2 + 5 = 8 + +**Constraints:** + +* 1 <= nums.length <= 3 * 104 +* `-100 <= nums[i] <= 100` +* `0 <= index < nums.length` +* `-100 <= val <= 100` +* `0 <= left <= right < nums.length` +* At most 3 * 104 calls will be made to `update` and `sumRange`. + +## Solution + +```kotlin +class NumArray(private val nums: IntArray) { + private var sum = 0 + + init { + for (num in nums) { + sum += num + } + } + + fun update(index: Int, `val`: Int) { + sum -= nums[index] - `val` + nums[index] = `val` + } + + fun sumRange(left: Int, right: Int): Int { + var sumRange = 0 + if (right - left < nums.size / 2) { + // Array to sum is less than half + for (i in left..right) { + sumRange += nums[i] + } + } else { + // Array to sum is more than half + // Better to take total sum and substract the numbers not in range + sumRange = sum + for (i in 0 until left) { + sumRange -= nums[i] + } + for (i in right + 1 until nums.size) { + sumRange -= nums[i] + } + } + return sumRange + } +} + +/* + * Your NumArray object will be instantiated and called as such: + * var obj = NumArray(nums) + * obj.update(index,`val`) + * var param_2 = obj.sumRange(left,right) + */ +``` \ No newline at end of file diff --git a/src/main/kotlin/g0301_0400/s0309_best_time_to_buy_and_sell_stock_with_cooldown/readme.md b/src/main/kotlin/g0301_0400/s0309_best_time_to_buy_and_sell_stock_with_cooldown/readme.md new file mode 100644 index 00000000..b04c3f03 --- /dev/null +++ b/src/main/kotlin/g0301_0400/s0309_best_time_to_buy_and_sell_stock_with_cooldown/readme.md @@ -0,0 +1,53 @@ +[![](https://img.shields.io/github/stars/javadev/LeetCode-in-Kotlin?label=Stars&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin) +[![](https://img.shields.io/github/forks/javadev/LeetCode-in-Kotlin?label=Fork%20me%20on%20GitHub%20&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin/fork) + +## 309\. Best Time to Buy and Sell Stock with Cooldown + +Medium + +You are given an array `prices` where `prices[i]` is the price of a given stock on the ith day. + +Find the maximum profit you can achieve. You may complete as many transactions as you like (i.e., buy one and sell one share of the stock multiple times) with the following restrictions: + +* After you sell your stock, you cannot buy stock on the next day (i.e., cooldown one day). + +**Note:** You may not engage in multiple transactions simultaneously (i.e., you must sell the stock before you buy again). + +**Example 1:** + +**Input:** prices = [1,2,3,0,2] + +**Output:** 3 + +**Explanation:** transactions = [buy, sell, cooldown, buy, sell] + +**Example 2:** + +**Input:** prices = [1] + +**Output:** 0 + +**Constraints:** + +* `1 <= prices.length <= 5000` +* `0 <= prices[i] <= 1000` + +## Solution + +```kotlin +class Solution { + fun maxProfit(prices: IntArray): Int { + var sell = 0 + var prevSell = 0 + var buy = Int.MIN_VALUE + var prevBuy: Int + for (price in prices) { + prevBuy = buy + buy = Math.max(prevSell - price, prevBuy) + prevSell = sell + sell = Math.max(prevBuy + price, prevSell) + } + return sell + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0301_0400/s0310_minimum_height_trees/readme.md b/src/main/kotlin/g0301_0400/s0310_minimum_height_trees/readme.md new file mode 100644 index 00000000..57155098 --- /dev/null +++ b/src/main/kotlin/g0301_0400/s0310_minimum_height_trees/readme.md @@ -0,0 +1,87 @@ +[![](https://img.shields.io/github/stars/javadev/LeetCode-in-Kotlin?label=Stars&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin) +[![](https://img.shields.io/github/forks/javadev/LeetCode-in-Kotlin?label=Fork%20me%20on%20GitHub%20&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin/fork) + +## 310\. Minimum Height Trees + +Medium + +A tree is an undirected graph in which any two vertices are connected by _exactly_ one path. In other words, any connected graph without simple cycles is a tree. + +Given a tree of `n` nodes labelled from `0` to `n - 1`, and an array of `n - 1` `edges` where edges[i] = [ai, bi] indicates that there is an undirected edge between the two nodes ai and bi in the tree, you can choose any node of the tree as the root. When you select a node `x` as the root, the result tree has height `h`. Among all possible rooted trees, those with minimum height (i.e. `min(h)`) are called **minimum height trees** (MHTs). + +Return _a list of all **MHTs'** root labels_. You can return the answer in **any order**. + +The **height** of a rooted tree is the number of edges on the longest downward path between the root and a leaf. + +**Example 1:** + +![](https://assets.leetcode.com/uploads/2020/09/01/e1.jpg) + +**Input:** n = 4, edges = \[\[1,0],[1,2],[1,3]] + +**Output:** [1] + +**Explanation:** As shown, the height of the tree is 1 when the root is the node with label 1 which is the only MHT. + +**Example 2:** + +![](https://assets.leetcode.com/uploads/2020/09/01/e2.jpg) + +**Input:** n = 6, edges = \[\[3,0],[3,1],[3,2],[3,4],[5,4]] + +**Output:** [3,4] + +**Constraints:** + +* 1 <= n <= 2 * 104 +* `edges.length == n - 1` +* 0 <= ai, bi < n +* ai != bi +* All the pairs (ai, bi) are distinct. +* The given input is **guaranteed** to be a tree and there will be **no repeated** edges. + +## Solution + +```kotlin +class Solution { + fun findMinHeightTrees(n: Int, edges: Array): List { + if (n == 1) return mutableListOf(0) + val degrees = IntArray(n) { 0 } + val graph = buildGraph(degrees, n, edges) + val queue = ArrayDeque() + for ((idxNode, degree) in degrees.withIndex()) { + if (degree == 1) { + queue.addLast(idxNode) + } + } + var ans = mutableListOf() + while (queue.isNotEmpty()) { + val size = queue.size + val newLeaves = mutableListOf() + for (_sz in 0 until size) { + val cur = queue.removeFirst() + newLeaves.add(cur) + for (next in graph[cur]) { + if (--degrees[next] == 1) { + queue.addLast(next) + } + } + } + ans = newLeaves + } + return ans + } + + private fun buildGraph(degrees: IntArray, n: Int, edges: Array): Array> { + val graph = Array(n) { arrayListOf() } + for (edge in edges) { + val (u, v) = edge + graph[u].add(v) + graph[v].add(u) + ++degrees[u] + ++degrees[v] + } + return graph + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0301_0400/s0312_burst_balloons/readme.md b/src/main/kotlin/g0301_0400/s0312_burst_balloons/readme.md new file mode 100644 index 00000000..22292c2c --- /dev/null +++ b/src/main/kotlin/g0301_0400/s0312_burst_balloons/readme.md @@ -0,0 +1,68 @@ +[![](https://img.shields.io/github/stars/javadev/LeetCode-in-Kotlin?label=Stars&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin) +[![](https://img.shields.io/github/forks/javadev/LeetCode-in-Kotlin?label=Fork%20me%20on%20GitHub%20&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin/fork) + +## 312\. Burst Balloons + +Hard + +You are given `n` balloons, indexed from `0` to `n - 1`. Each balloon is painted with a number on it represented by an array `nums`. You are asked to burst all the balloons. + +If you burst the ith balloon, you will get `nums[i - 1] * nums[i] * nums[i + 1]` coins. If `i - 1` or `i + 1` goes out of bounds of the array, then treat it as if there is a balloon with a `1` painted on it. + +Return _the maximum coins you can collect by bursting the balloons wisely_. + +**Example 1:** + +**Input:** nums = [3,1,5,8] + +**Output:** 167 + +**Explanation:** nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> [] coins = 3\*1\*5 + 3\*5\*8 + 1\*3\*8 + 1\*8\*1 = 167 + +**Example 2:** + +**Input:** nums = [1,5] + +**Output:** 10 + +**Constraints:** + +* `n == nums.length` +* `1 <= n <= 300` +* `0 <= nums[i] <= 100` + +## Solution + +```kotlin +class Solution { + fun maxCoins(nums: IntArray): Int { + if (nums.size == 0) { + return 0 + } + val dp = Array(nums.size) { IntArray(nums.size) } + return balloonBurstDp(nums, dp) + } + + private fun balloonBurstDp(nums: IntArray, dp: Array): Int { + for (gap in nums.indices) { + var si = 0 + var ei = gap + while (ei < nums.size) { + val l = if (si - 1 == -1) 1 else nums[si - 1] + val r = if (ei + 1 == nums.size) 1 else nums[ei + 1] + var maxAns = -1e7.toInt() + for (cut in si..ei) { + val leftAns = if (si == cut) 0 else dp[si][cut - 1] + val rightAns = if (ei == cut) 0 else dp[cut + 1][ei] + val myAns = leftAns + l * nums[cut] * r + rightAns + maxAns = Math.max(maxAns, myAns) + } + dp[si][ei] = maxAns + si++ + ei++ + } + } + return dp[0][nums.size - 1] + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0301_0400/s0313_super_ugly_number/readme.md b/src/main/kotlin/g0301_0400/s0313_super_ugly_number/readme.md new file mode 100644 index 00000000..7e7d716e --- /dev/null +++ b/src/main/kotlin/g0301_0400/s0313_super_ugly_number/readme.md @@ -0,0 +1,65 @@ +[![](https://img.shields.io/github/stars/javadev/LeetCode-in-Kotlin?label=Stars&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin) +[![](https://img.shields.io/github/forks/javadev/LeetCode-in-Kotlin?label=Fork%20me%20on%20GitHub%20&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin/fork) + +## 313\. Super Ugly Number + +Medium + +A **super ugly number** is a positive integer whose prime factors are in the array `primes`. + +Given an integer `n` and an array of integers `primes`, return _the_ nth _**super ugly number**_. + +The nth **super ugly number** is **guaranteed** to fit in a **32-bit** signed integer. + +**Example 1:** + +**Input:** n = 12, primes = [2,7,13,19] + +**Output:** 32 + +**Explanation:** [1,2,4,7,8,13,14,16,19,26,28,32] is the sequence of the first 12 super ugly numbers given primes = [2,7,13,19]. + +**Example 2:** + +**Input:** n = 1, primes = [2,3,5] + +**Output:** 1 + +**Explanation:** 1 has no prime factors, therefore all of its prime factors are in the array primes = [2,3,5]. + +**Constraints:** + +* 1 <= n <= 105 +* `1 <= primes.length <= 100` +* `2 <= primes[i] <= 1000` +* `primes[i]` is **guaranteed** to be a prime number. +* All the values of `primes` are **unique** and sorted in **ascending order**. + +## Solution + +```kotlin +class Solution { + fun nthSuperUglyNumber(n: Int, primes: IntArray): Int { + val primes1 = LongArray(primes.size) + for (i in primes.indices) { + primes1[i] = primes[i].toLong() + } + val index = IntArray(primes.size) + val n1 = LongArray(n) + n1[0] = 1L + for (i in 1 until n) { + var min = Long.MAX_VALUE + for (l in primes1) { + min = Math.min(min, l) + } + n1[i] = min + for (j in primes1.indices) { + if (min == primes1[j]) { + primes1[j] = primes[j] * n1[++index[j]] + } + } + } + return n1[n - 1].toInt() + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0301_0400/s0315_count_of_smaller_numbers_after_self/readme.md b/src/main/kotlin/g0301_0400/s0315_count_of_smaller_numbers_after_self/readme.md new file mode 100644 index 00000000..6ffd5d27 --- /dev/null +++ b/src/main/kotlin/g0301_0400/s0315_count_of_smaller_numbers_after_self/readme.md @@ -0,0 +1,93 @@ +[![](https://img.shields.io/github/stars/javadev/LeetCode-in-Kotlin?label=Stars&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin) +[![](https://img.shields.io/github/forks/javadev/LeetCode-in-Kotlin?label=Fork%20me%20on%20GitHub%20&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin/fork) + +## 315\. Count of Smaller Numbers After Self + +Hard + +You are given an integer array `nums` and you have to return a new `counts` array. The `counts` array has the property where `counts[i]` is the number of smaller elements to the right of `nums[i]`. + +**Example 1:** + +**Input:** nums = [5,2,6,1] + +**Output:** [2,1,1,0] + +**Explanation:** To the right of 5 there are **2** smaller elements (2 and 1). To the right of 2 there is only **1** smaller element (1). To the right of 6 there is **1** smaller element (1). To the right of 1 there is **0** smaller element. + +**Example 2:** + +**Input:** nums = [-1] + +**Output:** [0] + +**Example 3:** + +**Input:** nums = [-1,-1] + +**Output:** [0,0] + +**Constraints:** + +* 1 <= nums.length <= 105 +* -104 <= nums[i] <= 104 + +## Solution + +```kotlin +import java.util.LinkedList + +@Suppress("NAME_SHADOWING") +class Solution { + fun countSmaller(nums: IntArray): List { + var minVal = 10001 + var maxVal = -10001 + for (a in nums) { + minVal = Math.min(minVal, a) + maxVal = Math.max(maxVal, a) + } + val range = maxVal - (minVal - 1) + 1 + val offset = -(minVal - 1) + val bit = FenwickTree(range) + val ans = LinkedList() + val n = nums.size + var i = n - 1 + while (i >= 0) { + bit.update(offset + nums[i], 1) + ans.addFirst(bit.ps(offset + nums[i] - 1)) + i-- + } + return ans + } + + private class FenwickTree(n: Int) { + // binary index tree, index 0 is not used + var bit: IntArray + var n: Int + + init { + this.n = n + 1 + bit = IntArray(this.n) + } + + fun update(i: Int, v: Int) { + var i = i + while (i < n) { + bit[i] += v + i += Integer.lowestOneBit(i) + } + } + + // prefix sum query + fun ps(j: Int): Int { + var j = j + var ps = 0 + while (j != 0) { + ps += bit[j] + j -= Integer.lowestOneBit(j) + } + return ps + } + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0301_0400/s0316_remove_duplicate_letters/readme.md b/src/main/kotlin/g0301_0400/s0316_remove_duplicate_letters/readme.md new file mode 100644 index 00000000..8aae407f --- /dev/null +++ b/src/main/kotlin/g0301_0400/s0316_remove_duplicate_letters/readme.md @@ -0,0 +1,70 @@ +[![](https://img.shields.io/github/stars/javadev/LeetCode-in-Kotlin?label=Stars&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin) +[![](https://img.shields.io/github/forks/javadev/LeetCode-in-Kotlin?label=Fork%20me%20on%20GitHub%20&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin/fork) + +## 316\. Remove Duplicate Letters + +Medium + +Given a string `s`, remove duplicate letters so that every letter appears once and only once. You must make sure your result is **the smallest in lexicographical order** among all possible results. + +**Example 1:** + +**Input:** s = "bcabc" + +**Output:** "abc" + +**Example 2:** + +**Input:** s = "cbacdcbc" + +**Output:** "acdb" + +**Constraints:** + +* 1 <= s.length <= 104 +* `s` consists of lowercase English letters. + +**Note:** This question is the same as 1081: [https://leetcode.com/problems/smallest-subsequence-of-distinct-characters/](https://leetcode.com/problems/smallest-subsequence-of-distinct-characters/) + +## Solution + +```kotlin +class Solution { + fun removeDuplicateLetters(s: String): String { + val charCount = IntArray(26) + val charAdded = BooleanArray(26) + // Build the char count array + for (c in s.toCharArray()) { + charCount[c.code - 'a'.code] += 1 + } + val sb = StringBuilder() + // i = index of the input string + // j = index of the output stringBuilder + var j = 0 + for (i in 0 until s.length) { + val curr = s[i] + // If the curr char is NOT already added in the final string + if (!charAdded[curr.code - 'a'.code]) { + // If the prev char in final string is lexicographically greater than curr char of + // input string + // And there are more characters in charCount array then we can remove this prev + // char from final string + // Do this check iteratively until all characters are removed from the final string + // or prev char < curr char + while (j > 0 && sb[j - 1] > curr && charCount[sb[j - 1].code - 'a'.code] > 0) { + charAdded[sb[j - 1].code - 'a'.code] = false + sb.deleteCharAt(j - 1) + j-- + } + // Add the curr char in final string and mark that character as added in the string + sb.append(curr) + charAdded[curr.code - 'a'.code] = true + j++ + } + // Reduce the count of the current character from the charCount array + charCount[curr.code - 'a'.code] -= 1 + } + return sb.toString() + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0301_0400/s0318_maximum_product_of_word_lengths/readme.md b/src/main/kotlin/g0301_0400/s0318_maximum_product_of_word_lengths/readme.md new file mode 100644 index 00000000..b7c48427 --- /dev/null +++ b/src/main/kotlin/g0301_0400/s0318_maximum_product_of_word_lengths/readme.md @@ -0,0 +1,70 @@ +[![](https://img.shields.io/github/stars/javadev/LeetCode-in-Kotlin?label=Stars&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin) +[![](https://img.shields.io/github/forks/javadev/LeetCode-in-Kotlin?label=Fork%20me%20on%20GitHub%20&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin/fork) + +## 318\. Maximum Product of Word Lengths + +Medium + +Given a string array `words`, return _the maximum value of_ `length(word[i]) * length(word[j])` _where the two words do not share common letters_. If no such two words exist, return `0`. + +**Example 1:** + +**Input:** words = ["abcw","baz","foo","bar","xtfn","abcdef"] + +**Output:** 16 + +**Explanation:** The two words can be "abcw", "xtfn". + +**Example 2:** + +**Input:** words = ["a","ab","abc","d","cd","bcd","abcd"] + +**Output:** 4 + +**Explanation:** The two words can be "ab", "cd". + +**Example 3:** + +**Input:** words = ["a","aa","aaa","aaaa"] + +**Output:** 0 + +**Explanation:** No such pair of words. + +**Constraints:** + +* `2 <= words.length <= 1000` +* `1 <= words[i].length <= 1000` +* `words[i]` consists only of lowercase English letters. + +## Solution + +```kotlin +class Solution { + fun maxProduct(words: Array): Int { + val n = words.size + var res = 0 + val masks = IntArray(n) + for (i in 0 until n) { + masks[i] = getMask(words[i]) + } + for (i in 0 until n) { + for (j in i + 1 until n) { + if (masks[i] and masks[j] == 0) { + res = Math.max(res, words[i].length * words[j].length) + } + } + } + return res + } + + private fun getMask(s: String): Int { + var mask = 0 + for (i in 0 until s.length) { + val c = s[i] + mask = mask or (1 shl c.code - 'a'.code) + } + return mask + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0301_0400/s0319_bulb_switcher/readme.md b/src/main/kotlin/g0301_0400/s0319_bulb_switcher/readme.md new file mode 100644 index 00000000..9ae45fe0 --- /dev/null +++ b/src/main/kotlin/g0301_0400/s0319_bulb_switcher/readme.md @@ -0,0 +1,50 @@ +[![](https://img.shields.io/github/stars/javadev/LeetCode-in-Kotlin?label=Stars&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin) +[![](https://img.shields.io/github/forks/javadev/LeetCode-in-Kotlin?label=Fork%20me%20on%20GitHub%20&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin/fork) + +## 319\. Bulb Switcher + +Medium + +There are `n` bulbs that are initially off. You first turn on all the bulbs, then you turn off every second bulb. + +On the third round, you toggle every third bulb (turning on if it's off or turning off if it's on). For the ith round, you toggle every `i` bulb. For the nth round, you only toggle the last bulb. + +Return _the number of bulbs that are on after `n` rounds_. + +**Example 1:** + +![](https://assets.leetcode.com/uploads/2020/11/05/bulb.jpg) + +**Input:** n = 3 + +**Output:** 1 + +**Explanation:** At first, the three bulbs are [off, off, off]. After the first round, the three bulbs are [on, on, on]. After the second round, the three bulbs are [on, off, on]. After the third round, the three bulbs are [on, off, off]. So you should return 1 because there is only one bulb is on. + +**Example 2:** + +**Input:** n = 0 + +**Output:** 0 + +**Example 3:** + +**Input:** n = 1 + +**Output:** 1 + +**Constraints:** + +* 0 <= n <= 109 + +## Solution + +```kotlin +class Solution { + fun bulbSwitch(n: Int): Int { + return if (n < 2) { + n + } else Math.sqrt(n.toDouble()).toInt() + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0301_0400/s0321_create_maximum_number/readme.md b/src/main/kotlin/g0301_0400/s0321_create_maximum_number/readme.md new file mode 100644 index 00000000..7ea4531e --- /dev/null +++ b/src/main/kotlin/g0301_0400/s0321_create_maximum_number/readme.md @@ -0,0 +1,131 @@ +[![](https://img.shields.io/github/stars/javadev/LeetCode-in-Kotlin?label=Stars&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin) +[![](https://img.shields.io/github/forks/javadev/LeetCode-in-Kotlin?label=Fork%20me%20on%20GitHub%20&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin/fork) + +## 321\. Create Maximum Number + +Hard + +You are given two integer arrays `nums1` and `nums2` of lengths `m` and `n` respectively. `nums1` and `nums2` represent the digits of two numbers. You are also given an integer `k`. + +Create the maximum number of length `k <= m + n` from digits of the two numbers. The relative order of the digits from the same array must be preserved. + +Return an array of the `k` digits representing the answer. + +**Example 1:** + +**Input:** nums1 = [3,4,6,5], nums2 = [9,1,2,5,8,3], k = 5 + +**Output:** [9,8,6,5,3] + +**Example 2:** + +**Input:** nums1 = [6,7], nums2 = [6,0,4], k = 5 + +**Output:** [6,7,6,0,4] + +**Example 3:** + +**Input:** nums1 = [3,9], nums2 = [8,9], k = 3 + +**Output:** [9,8,9] + +**Constraints:** + +* `m == nums1.length` +* `n == nums2.length` +* `1 <= m, n <= 500` +* `0 <= nums1[i], nums2[i] <= 9` +* `1 <= k <= m + n` + +## Solution + +```kotlin +class Solution { + fun maxNumber(nums1: IntArray, nums2: IntArray, k: Int): IntArray { + if (k == 0) { + return IntArray(0) + } + val maxSubNums1 = IntArray(k) + val maxSubNums2 = IntArray(k) + var res = IntArray(k) + // select l elements from nums1 + for (l in 0..Math.min(k, nums1.size)) { + if (l + nums2.size < k) { + continue + } + // create maximum number for each array + // nums1: l elements; nums2: k - l elements + maxSubArray(nums1, maxSubNums1, l) + maxSubArray(nums2, maxSubNums2, k - l) + // merge the two maximum numbers + // if get a larger number than res, update res + res = merge(maxSubNums1, maxSubNums2, l, k - l, res) + } + return res + } + + private fun maxSubArray(nums: IntArray, maxSub: IntArray, size: Int) { + if (size == 0) { + return + } + var j = 0 + for (i in nums.indices) { + while (j > 0 && nums.size - i + j > size && nums[i] > maxSub[j - 1]) { + j-- + } + if (j < size) { + maxSub[j++] = nums[i] + } + } + } + + private fun merge(maxSub1: IntArray, maxSub2: IntArray, size1: Int, size2: Int, res: IntArray): IntArray { + val merge = IntArray(res.size) + var i = 0 + var j = 0 + var idx = 0 + var equal = true + while (i < size1 || j < size2) { + if (j >= size2) { + merge[idx] = maxSub1[i++] + } else if (i >= size1) { + merge[idx] = maxSub2[j++] + } else { + var ii = i + var jj = j + while (ii < size1 && jj < size2 && maxSub1[ii] == maxSub2[jj]) { + ii++ + jj++ + } + if (ii < size1 && jj < size2) { + if (maxSub1[ii] > maxSub2[jj]) { + merge[idx] = maxSub1[i++] + } else { + merge[idx] = maxSub2[j++] + } + } else if (jj == size2) { + merge[idx] = maxSub1[i++] + } else { + // ii == size1 + merge[idx] = maxSub2[j++] + } + } + // break if we already know merge must be < res + if (merge[idx] > res[idx]) { + equal = false + } else if (equal && merge[idx] < res[idx]) { + break + } + idx++ + } + // if get a larger number than res, update res + val k = res.size + if (i == size1 && j == size2 && !equal) { + return merge + } + return if (equal && merge[k - 1] > res[k - 1]) { + merge + } else res + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0301_0400/s0324_wiggle_sort_ii/readme.md b/src/main/kotlin/g0301_0400/s0324_wiggle_sort_ii/readme.md new file mode 100644 index 00000000..2f05d38e --- /dev/null +++ b/src/main/kotlin/g0301_0400/s0324_wiggle_sort_ii/readme.md @@ -0,0 +1,64 @@ +[![](https://img.shields.io/github/stars/javadev/LeetCode-in-Kotlin?label=Stars&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin) +[![](https://img.shields.io/github/forks/javadev/LeetCode-in-Kotlin?label=Fork%20me%20on%20GitHub%20&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin/fork) + +## 324\. Wiggle Sort II + +Medium + +Given an integer array `nums`, reorder it such that `nums[0] < nums[1] > nums[2] < nums[3]...`. + +You may assume the input array always has a valid answer. + +**Example 1:** + +**Input:** nums = [1,5,1,1,6,4] + +**Output:** [1,6,1,5,1,4] + +**Explanation:** [1,4,1,5,1,6] is also accepted. + +**Example 2:** + +**Input:** nums = [1,3,2,2,3,1] + +**Output:** [2,3,1,3,1,2] + +**Constraints:** + +* 1 <= nums.length <= 5 * 104 +* `0 <= nums[i] <= 5000` +* It is guaranteed that there will be an answer for the given input `nums`. + +**Follow Up:** Can you do it in `O(n)` time and/or **in-place** with `O(1)` extra space? + +## Solution + +```kotlin +import java.util.Arrays + +class Solution { + fun wiggleSort(nums: IntArray) { + Arrays.sort(nums) + val result = IntArray(nums.size) + var index = nums.size - 1 + var i = 1 + // Start filling all peaks (which is all at odd indexes) from start + while (i < nums.size) { + result[i] = nums[index] + --index + i += 2 + } + // Start filling all valleys (which is all at even indexes) from end + // why from end, as the last peak index may have smallest largest value, so to + // make sure, that is also '>', fill in the smallest element near it. + i = if ((nums.size - 1) % 2 == 0) nums.size - 1 else nums.size - 2 + index = 0 + while (i >= 0) { + result[i] = nums[index] + ++index + i -= 2 + } + System.arraycopy(result, 0, nums, 0, nums.size) + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0301_0400/s0326_power_of_three/readme.md b/src/main/kotlin/g0301_0400/s0326_power_of_three/readme.md new file mode 100644 index 00000000..8f199bf4 --- /dev/null +++ b/src/main/kotlin/g0301_0400/s0326_power_of_three/readme.md @@ -0,0 +1,48 @@ +[![](https://img.shields.io/github/stars/javadev/LeetCode-in-Kotlin?label=Stars&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin) +[![](https://img.shields.io/github/forks/javadev/LeetCode-in-Kotlin?label=Fork%20me%20on%20GitHub%20&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin/fork) + +## 324\. Wiggle Sort II + +Medium + +Given an integer array `nums`, reorder it such that `nums[0] < nums[1] > nums[2] < nums[3]...`. + +You may assume the input array always has a valid answer. + +**Example 1:** + +**Input:** nums = [1,5,1,1,6,4] + +**Output:** [1,6,1,5,1,4] + +**Explanation:** [1,4,1,5,1,6] is also accepted. + +**Example 2:** + +**Input:** nums = [1,3,2,2,3,1] + +**Output:** [2,3,1,3,1,2] + +**Constraints:** + +* 1 <= nums.length <= 5 * 104 +* `0 <= nums[i] <= 5000` +* It is guaranteed that there will be an answer for the given input `nums`. + +**Follow Up:** Can you do it in `O(n)` time and/or **in-place** with `O(1)` extra space? + +## Solution + +```kotlin +class Solution { + fun isPowerOfThree(n: Int): Boolean { + if (n == 1 || n == 3) { + return true + } + if (n == 0 || n % 3 != 0) { + return false + } + return isPowerOfThree(n / 3) + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0301_0400/s0327_count_of_range_sum/readme.md b/src/main/kotlin/g0301_0400/s0327_count_of_range_sum/readme.md new file mode 100644 index 00000000..20d187a5 --- /dev/null +++ b/src/main/kotlin/g0301_0400/s0327_count_of_range_sum/readme.md @@ -0,0 +1,78 @@ +[![](https://img.shields.io/github/stars/javadev/LeetCode-in-Kotlin?label=Stars&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin) +[![](https://img.shields.io/github/forks/javadev/LeetCode-in-Kotlin?label=Fork%20me%20on%20GitHub%20&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin/fork) + +## 327\. Count of Range Sum + +Hard + +Given an integer array `nums` and two integers `lower` and `upper`, return _the number of range sums that lie in_ `[lower, upper]` _inclusive_. + +Range sum `S(i, j)` is defined as the sum of the elements in `nums` between indices `i` and `j` inclusive, where `i <= j`. + +**Example 1:** + +**Input:** nums = [-2,5,-1], lower = -2, upper = 2 + +**Output:** 3 + +**Explanation:** The three ranges are: [0,0], [2,2], and [0,2] and their respective sums are: -2, -1, 2. + +**Example 2:** + +**Input:** nums = [0], lower = 0, upper = 0 + +**Output:** 1 + +**Constraints:** + +* 1 <= nums.length <= 105 +* -231 <= nums[i] <= 231 - 1 +* -105 <= lower <= upper <= 105 +* The answer is **guaranteed** to fit in a **32-bit** integer. + +## Solution + +```kotlin +class Solution { + fun countRangeSum(nums: IntArray, lower: Int, upper: Int): Int { + val n = nums.size + val sums = LongArray(n + 1) + for (i in 0 until n) { + sums[i + 1] = sums[i] + nums[i] + } + return countWhileMergeSort(sums, 0, n + 1, lower, upper) + } + + private fun countWhileMergeSort(sums: LongArray, start: Int, end: Int, lower: Int, upper: Int): Int { + if (end - start <= 1) { + return 0 + } + val mid = (start + end) / 2 + var count = ( + countWhileMergeSort(sums, start, mid, lower, upper) + + countWhileMergeSort(sums, mid, end, lower, upper) + ) + var j = mid + var k = mid + var t = mid + val cache = LongArray(end - start) + var r = 0 + for (i in start until mid) { + while (k < end && sums[k] - sums[i] < lower) { + k++ + } + while (j < end && sums[j] - sums[i] <= upper) { + j++ + } + while (t < end && sums[t] < sums[i]) { + cache[r++] = sums[t++] + } + cache[r] = sums[i] + count += j - k + r++ + } + System.arraycopy(cache, 0, sums, start, t - start) + return count + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0301_0400/s0328_odd_even_linked_list/readme.md b/src/main/kotlin/g0301_0400/s0328_odd_even_linked_list/readme.md new file mode 100644 index 00000000..95ada253 --- /dev/null +++ b/src/main/kotlin/g0301_0400/s0328_odd_even_linked_list/readme.md @@ -0,0 +1,76 @@ +[![](https://img.shields.io/github/stars/javadev/LeetCode-in-Kotlin?label=Stars&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin) +[![](https://img.shields.io/github/forks/javadev/LeetCode-in-Kotlin?label=Fork%20me%20on%20GitHub%20&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin/fork) + +## 328\. Odd Even Linked List + +Medium + +Given the `head` of a singly linked list, group all the nodes with odd indices together followed by the nodes with even indices, and return _the reordered list_. + +The **first** node is considered **odd**, and the **second** node is **even**, and so on. + +Note that the relative order inside both the even and odd groups should remain as it was in the input. + +You must solve the problem in `O(1)` extra space complexity and `O(n)` time complexity. + +**Example 1:** + +![](https://assets.leetcode.com/uploads/2021/03/10/oddeven-linked-list.jpg) + +**Input:** head = [1,2,3,4,5] + +**Output:** [1,3,5,2,4] + +**Example 2:** + +![](https://assets.leetcode.com/uploads/2021/03/10/oddeven2-linked-list.jpg) + +**Input:** head = [2,1,3,5,6,4,7] + +**Output:** [2,3,6,7,1,5,4] + +**Constraints:** + +* The number of nodes in the linked list is in the range [0, 104]. +* -106 <= Node.val <= 106 + +## Solution + +```kotlin +import com_github_leetcode.ListNode + +/* + * Example: + * var li = ListNode(5) + * var v = li.`val` + * Definition for singly-linked list. + * class ListNode(var `val`: Int) { + * var next: ListNode? = null + * } + */ +class Solution { + fun oddEvenList(head: ListNode?): ListNode? { + val odd = ListNode(0) + val even = ListNode(0) + var oddPointer = odd + var evenPointer = even + var pointer = head + var count = 0 + while (pointer != null) { + if (count % 2 == 0) { + oddPointer.next = pointer + oddPointer = oddPointer.next!! + } else { + evenPointer.next = pointer + evenPointer = evenPointer.next!! + } + val next = pointer.next + pointer.next = null + pointer = next + count++ + } + oddPointer.next = even.next + return odd.next + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0301_0400/s0329_longest_increasing_path_in_a_matrix/readme.md b/src/main/kotlin/g0301_0400/s0329_longest_increasing_path_in_a_matrix/readme.md new file mode 100644 index 00000000..53067907 --- /dev/null +++ b/src/main/kotlin/g0301_0400/s0329_longest_increasing_path_in_a_matrix/readme.md @@ -0,0 +1,86 @@ +[![](https://img.shields.io/github/stars/javadev/LeetCode-in-Kotlin?label=Stars&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin) +[![](https://img.shields.io/github/forks/javadev/LeetCode-in-Kotlin?label=Fork%20me%20on%20GitHub%20&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin/fork) + +## 329\. Longest Increasing Path in a Matrix + +Hard + +Given an `m x n` integers `matrix`, return _the length of the longest increasing path in_ `matrix`. + +From each cell, you can either move in four directions: left, right, up, or down. You **may not** move **diagonally** or move **outside the boundary** (i.e., wrap-around is not allowed). + +**Example 1:** + +![](https://assets.leetcode.com/uploads/2021/01/05/grid1.jpg) + +**Input:** matrix = \[\[9,9,4],[6,6,8],[2,1,1]] + +**Output:** 4 + +**Explanation:** The longest increasing path is `[1, 2, 6, 9]`. + +**Example 2:** + +![](https://assets.leetcode.com/uploads/2021/01/27/tmp-grid.jpg) + +**Input:** matrix = \[\[3,4,5],[3,2,6],[2,2,1]] + +**Output:** 4 + +**Explanation:** The longest increasing path is `[3, 4, 5, 6]`. Moving diagonally is not allowed. + +**Example 3:** + +**Input:** matrix = \[\[1]] + +**Output:** 1 + +**Constraints:** + +* `m == matrix.length` +* `n == matrix[i].length` +* `1 <= m, n <= 200` +* 0 <= matrix[i][j] <= 231 - 1 + +## Solution + +```kotlin +class Solution { + fun longestIncreasingPath(matrix: Array): Int { + var maxIncreasingSequenceCount = 0 + val n = matrix.size - 1 + val m = matrix[0].size - 1 + val memory = Array(n + 1) { IntArray(m + 1) } + for (i in matrix.indices) { + for (j in matrix[i].indices) { + maxIncreasingSequenceCount = Math.max(maxIncreasingSequenceCount, move(i, j, n, m, matrix, memory)) + } + } + return maxIncreasingSequenceCount + } + + private fun move(row: Int, col: Int, n: Int, m: Int, matrix: Array, memory: Array): Int { + if (memory[row][col] == 0) { + var count = 1 + // move down + if (row < n && matrix[row + 1][col] > matrix[row][col]) { + count = Math.max(count, move(row + 1, col, n, m, matrix, memory) + 1) + } + // move right + if (col < m && matrix[row][col + 1] > matrix[row][col]) { + count = Math.max(count, move(row, col + 1, n, m, matrix, memory) + 1) + } + // move up + if (row > 0 && matrix[row - 1][col] > matrix[row][col]) { + count = Math.max(count, move(row - 1, col, n, m, matrix, memory) + 1) + } + // move left + if (col > 0 && matrix[row][col - 1] > matrix[row][col]) { + count = Math.max(count, move(row, col - 1, n, m, matrix, memory) + 1) + } + memory[row][col] = count + } + return memory[row][col] + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0301_0400/s0330_patching_array/readme.md b/src/main/kotlin/g0301_0400/s0330_patching_array/readme.md new file mode 100644 index 00000000..80cf11ea --- /dev/null +++ b/src/main/kotlin/g0301_0400/s0330_patching_array/readme.md @@ -0,0 +1,58 @@ +[![](https://img.shields.io/github/stars/javadev/LeetCode-in-Kotlin?label=Stars&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin) +[![](https://img.shields.io/github/forks/javadev/LeetCode-in-Kotlin?label=Fork%20me%20on%20GitHub%20&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin/fork) + +## 330\. Patching Array + +Hard + +Given a sorted integer array `nums` and an integer `n`, add/patch elements to the array such that any number in the range `[1, n]` inclusive can be formed by the sum of some elements in the array. + +Return _the minimum number of patches required_. + +**Example 1:** + +**Input:** nums = [1,3], n = 6 + +**Output:** 1 Explanation: Combinations of nums are [1], [3], [1,3], which form possible sums of: 1, 3, 4. Now if we add/patch 2 to nums, the combinations are: [1], [2], [3], [1,3], [2,3], [1,2,3]. Possible sums are 1, 2, 3, 4, 5, 6, which now covers the range [1, 6]. So we only need 1 patch. + +**Example 2:** + +**Input:** nums = [1,5,10], n = 20 + +**Output:** 2 Explanation: The two patches can be [2, 4]. + +**Example 3:** + +**Input:** nums = [1,2,2], n = 5 + +**Output:** 0 + +**Constraints:** + +* `1 <= nums.length <= 1000` +* 1 <= nums[i] <= 104 +* `nums` is sorted in **ascending order**. +* 1 <= n <= 231 - 1 + +## Solution + +```kotlin +class Solution { + fun minPatches(nums: IntArray, n: Int): Int { + var res = 0 + var sum: Long = 0 + var i = 0 + while (sum < n) { + // required number + val req = sum + 1 + if (i < nums.size && nums[i] <= req) { + sum += nums[i++].toLong() + } else { + sum += req + res++ + } + } + return res + } +} +``` \ No newline at end of file