diff --git a/README.md b/README.md index e805fa5d..627041e2 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ | | | | | | |-|-|-|-|-|- | 0797 |[All Paths From Source to Target](src/main/kotlin/g0701_0800/s0797_all_paths_from_source_to_target)| Medium | Depth_First_Search, Breadth_First_Search, Graph, Backtracking | 232 | 100.00 +| 0841 |[Keys and Rooms](src/main/kotlin/g0801_0900/s0841_keys_and_rooms)| Medium | Depth_First_Search, Breadth_First_Search, Graph | 189 | 69.23 #### Day 8 Standard Traversal @@ -76,6 +77,7 @@ | | | | | | |-|-|-|-|-|- +| 0847 |[Shortest Path Visiting All Nodes](src/main/kotlin/g0801_0900/s0847_shortest_path_visiting_all_nodes)| Hard | Dynamic_Programming, Breadth_First_Search, Bit_Manipulation, Graph, Bitmask | 164 | 100.00 #### Day 11 Breadth First Search @@ -262,6 +264,7 @@ | | | | | | |-|-|-|-|-|- +| 0844 |[Backspace String Compare](src/main/kotlin/g0801_0900/s0844_backspace_string_compare)| Easy | String, Two_Pointers, Stack, Simulation | 126 | 98.31 | 0394 |[Decode String](src/main/kotlin/g0301_0400/s0394_decode_string)| Medium | Top_100_Liked_Questions, String, Stack, Recursion | 224 | 64.86 #### Day 15 Heap @@ -859,6 +862,7 @@ | | | | | | |-|-|-|-|-|- +| 0841 |[Keys and Rooms](src/main/kotlin/g0801_0900/s0841_keys_and_rooms)| Medium | Depth_First_Search, Breadth_First_Search, Graph | 189 | 69.23 #### Day 20 Heap Priority Queue @@ -1002,6 +1006,7 @@ | | | | | | |-|-|-|-|-|- +| 0844 |[Backspace String Compare](src/main/kotlin/g0801_0900/s0844_backspace_string_compare)| Easy | String, Two_Pointers, Stack, Simulation | 126 | 98.31 | 0011 |[Container With Most Water](src/main/kotlin/g0001_0100/s0011_container_with_most_water)| Medium | Top_100_Liked_Questions, Top_Interview_Questions, Array, Greedy, Two_Pointers | 474 | 89.18 #### Day 5 Sliding Window @@ -1139,6 +1144,7 @@ | | | | | | |-|-|-|-|-|- | 0035 |[Search Insert Position](src/main/kotlin/g0001_0100/s0035_search_insert_position)| Easy | Top_100_Liked_Questions, Array, Binary_Search | 267 | 50.32 +| 0852 |[Peak Index in a Mountain Array](src/main/kotlin/g0801_0900/s0852_peak_index_in_a_mountain_array)| Easy | Array, Binary_Search | 433 | 94.29 #### Day 3 @@ -1267,6 +1273,7 @@ | | | | | | |-|-|-|-|-|- +| 0826 |[Most Profit Assigning Work](src/main/kotlin/g0801_0900/s0826_most_profit_assigning_work)| Medium | Array, Sorting, Greedy, Binary_Search, Two_Pointers | 366 | 100.00 | 0436 |[Find Right Interval](src/main/kotlin/g0401_0500/s0436_find_right_interval)| Medium | Array, Sorting, Binary_Search | 333 | 100.00 #### Day 12 @@ -1680,6 +1687,42 @@ | 1143 |[Longest Common Subsequence](src/main/kotlin/g1101_1200/s1143_longest_common_subsequence)| Medium | Top_100_Liked_Questions, String, Dynamic_Programming, Algorithm_II_Day_17_Dynamic_Programming, Dynamic_Programming_I_Day_19, Udemy_Dynamic_Programming | 307 | 38.36 | 0994 |[Rotting Oranges](src/main/kotlin/g0901_1000/s0994_rotting_oranges)| Medium | Array, Breadth_First_Search, Matrix, Algorithm_I_Day_9_Breadth_First_Search_Depth_First_Search, Level_2_Day_10_Graph/BFS/DFS | 308 | 57.93 | 0864 |[Shortest Path to Get All Keys](src/main/kotlin/g0801_0900/s0864_shortest_path_to_get_all_keys)| Hard | Breadth_First_Search, Bit_Manipulation | 176 | 100.00 +| 0857 |[Minimum Cost to Hire K Workers](src/main/kotlin/g0801_0900/s0857_minimum_cost_to_hire_k_workers)| Hard | Array, Sorting, Greedy, Heap_Priority_Queue | 302 | 100.00 +| 0856 |[Score of Parentheses](src/main/kotlin/g0801_0900/s0856_score_of_parentheses)| Medium | String, Stack | 129 | 84.62 +| 0855 |[Exam Room](src/main/kotlin/g0801_0900/s0855_exam_room)| Medium | Design, Ordered_Set | 644 | 83.33 +| 0854 |[K-Similar Strings](src/main/kotlin/g0801_0900/s0854_k_similar_strings)| Hard | String, Breadth_First_Search | 136 | 100.00 +| 0853 |[Car Fleet](src/main/kotlin/g0801_0900/s0853_car_fleet)| Medium | Array, Sorting, Stack, Monotonic_Stack | 757 | 85.29 +| 0852 |[Peak Index in a Mountain Array](src/main/kotlin/g0801_0900/s0852_peak_index_in_a_mountain_array)| Easy | Array, Binary_Search, Binary_Search_I_Day_2 | 433 | 94.29 +| 0851 |[Loud and Rich](src/main/kotlin/g0801_0900/s0851_loud_and_rich)| Medium | Array, Depth_First_Search, Graph, Topological_Sort | 347 | 100.00 +| 0850 |[Rectangle Area II](src/main/kotlin/g0801_0900/s0850_rectangle_area_ii)| Hard | Array, Ordered_Set, Segment_Tree, Line_Sweep | 171 | 100.00 +| 0849 |[Maximize Distance to Closest Person](src/main/kotlin/g0801_0900/s0849_maximize_distance_to_closest_person)| Medium | Array | 196 | 88.46 +| 0848 |[Shifting Letters](src/main/kotlin/g0801_0900/s0848_shifting_letters)| Medium | Array, String | 537 | 93.75 +| 0847 |[Shortest Path Visiting All Nodes](src/main/kotlin/g0801_0900/s0847_shortest_path_visiting_all_nodes)| Hard | Dynamic_Programming, Breadth_First_Search, Bit_Manipulation, Graph, Bitmask, Graph_Theory_I_Day_10_Standard_Traversal | 164 | 100.00 +| 0846 |[Hand of Straights](src/main/kotlin/g0801_0900/s0846_hand_of_straights)| Medium | Array, Hash_Table, Sorting, Greedy | 306 | 96.15 +| 0845 |[Longest Mountain in Array](src/main/kotlin/g0801_0900/s0845_longest_mountain_in_array)| Medium | Array, Dynamic_Programming, Two_Pointers, Enumeration | 222 | 100.00 +| 0844 |[Backspace String Compare](src/main/kotlin/g0801_0900/s0844_backspace_string_compare)| Easy | String, Two_Pointers, Stack, Simulation, Algorithm_II_Day_4_Two_Pointers, Level_1_Day_14_Stack | 126 | 98.31 +| 0843 |[Guess the Word](src/main/kotlin/g0801_0900/s0843_guess_the_word)| Hard | Array, String, Math, Game_Theory, Interactive | 75 | 100.00 +| 0842 |[Split Array into Fibonacci Sequence](src/main/kotlin/g0801_0900/s0842_split_array_into_fibonacci_sequence)| Medium | String, Backtracking | 142 | 100.00 +| 0841 |[Keys and Rooms](src/main/kotlin/g0801_0900/s0841_keys_and_rooms)| Medium | Depth_First_Search, Breadth_First_Search, Graph, Data_Structure_II_Day_19_Graph, Graph_Theory_I_Day_7_Standard_Traversal | 189 | 69.23 +| 0840 |[Magic Squares In Grid](src/main/kotlin/g0801_0900/s0840_magic_squares_in_grid)| Medium | Array, Math, Matrix | 149 | 100.00 +| 0839 |[Similar String Groups](src/main/kotlin/g0801_0900/s0839_similar_string_groups)| Hard | Array, String, Depth_First_Search, Breadth_First_Search, Union_Find | 205 | 100.00 +| 0838 |[Push Dominoes](src/main/kotlin/g0801_0900/s0838_push_dominoes)| Medium | String, Dynamic_Programming, Two_Pointers | 270 | 100.00 +| 0837 |[New 21 Game](src/main/kotlin/g0801_0900/s0837_new_21_game)| Medium | Dynamic_Programming, Math, Sliding_Window, Probability_and_Statistics | 144 | 75.00 +| 0836 |[Rectangle Overlap](src/main/kotlin/g0801_0900/s0836_rectangle_overlap)| Easy | Math, Geometry | 121 | 100.00 +| 0835 |[Image Overlap](src/main/kotlin/g0801_0900/s0835_image_overlap)| Medium | Array, Matrix | 163 | 100.00 +| 0834 |[Sum of Distances in Tree](src/main/kotlin/g0801_0900/s0834_sum_of_distances_in_tree)| Hard | Dynamic_Programming, Depth_First_Search, Tree, Graph | 746 | 100.00 +| 0833 |[Find And Replace in String](src/main/kotlin/g0801_0900/s0833_find_and_replace_in_string)| Medium | Array, String, Sorting | 158 | 100.00 +| 0832 |[Flipping an Image](src/main/kotlin/g0801_0900/s0832_flipping_an_image)| Easy | Array, Matrix, Two_Pointers, Simulation | 190 | 94.44 +| 0831 |[Masking Personal Information](src/main/kotlin/g0801_0900/s0831_masking_personal_information)| Medium | String | 149 | 100.00 +| 0830 |[Positions of Large Groups](src/main/kotlin/g0801_0900/s0830_positions_of_large_groups)| Easy | String | 221 | 100.00 +| 0829 |[Consecutive Numbers Sum](src/main/kotlin/g0801_0900/s0829_consecutive_numbers_sum)| Hard | Math, Enumeration | 151 | 100.00 +| 0828 |[Count Unique Characters of All Substrings of a Given String](src/main/kotlin/g0801_0900/s0828_count_unique_characters_of_all_substrings_of_a_given_string)| Hard | String, Hash_Table, Dynamic_Programming | 216 | 100.00 +| 0827 |[Making A Large Island](src/main/kotlin/g0801_0900/s0827_making_a_large_island)| Hard | Array, Depth_First_Search, Breadth_First_Search, Matrix, Union_Find | 985 | 100.00 +| 0826 |[Most Profit Assigning Work](src/main/kotlin/g0801_0900/s0826_most_profit_assigning_work)| Medium | Array, Sorting, Greedy, Binary_Search, Two_Pointers, Binary_Search_II_Day_11 | 366 | 100.00 +| 0825 |[Friends Of Appropriate Ages](src/main/kotlin/g0801_0900/s0825_friends_of_appropriate_ages)| Medium | Array, Sorting, Binary_Search, Two_Pointers | 278 | 100.00 +| 0824 |[Goat Latin](src/main/kotlin/g0801_0900/s0824_goat_latin)| Easy | String | 146 | 100.00 +| 0823 |[Binary Trees With Factors](src/main/kotlin/g0801_0900/s0823_binary_trees_with_factors)| Medium | Array, Hash_Table, Dynamic_Programming | 298 | 100.00 +| 0822 |[Card Flipping Game](src/main/kotlin/g0801_0900/s0822_card_flipping_game)| Medium | Array, Hash_Table | 186 | 100.00 | 0821 |[Shortest Distance to a Character](src/main/kotlin/g0801_0900/s0821_shortest_distance_to_a_character)| Easy | Array, String, Two_Pointers | 168 | 88.00 | 0820 |[Short Encoding of Words](src/main/kotlin/g0801_0900/s0820_short_encoding_of_words)| Medium | Array, String, Hash_Table, Trie | 231 | 100.00 | 0819 |[Most Common Word](src/main/kotlin/g0801_0900/s0819_most_common_word)| Easy | String, Hash_Table, Counting | 211 | 83.33 diff --git a/src/main/kotlin/g0801_0900/s0815_bus_routes/readme.md b/src/main/kotlin/g0801_0900/s0815_bus_routes/readme.md index bc20ed82..a2fad086 100644 --- a/src/main/kotlin/g0801_0900/s0815_bus_routes/readme.md +++ b/src/main/kotlin/g0801_0900/s0815_bus_routes/readme.md @@ -39,7 +39,6 @@ Return _the least number of buses you must take to travel from_ `source` _to_ `t ## Solution ```kotlin -import java.util.Arrays import java.util.LinkedList import java.util.Queue import kotlin.collections.ArrayList @@ -89,14 +88,14 @@ class Solution { val len = routes.size val graph: Array?> = arrayOfNulls(len) for (i in 0 until len) { - Arrays.sort(routes[i]) + routes[i].sort() graph[i] = ArrayList() - var id = Arrays.binarySearch(routes[i], source) + var id = routes[i].binarySearch(source) if (id >= 0) { queue.offer(i) taken[i] = true } - id = Arrays.binarySearch(routes[i], target) + id = routes[i].binarySearch(target) if (id >= 0) { targetRoutes.add(i) } diff --git a/src/main/kotlin/g0801_0900/s0822_card_flipping_game/readme.md b/src/main/kotlin/g0801_0900/s0822_card_flipping_game/readme.md new file mode 100644 index 00000000..c44dcf44 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0822_card_flipping_game/readme.md @@ -0,0 +1,88 @@ +[![](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) + +## 822\. Card Flipping Game + +Medium + +You are given two **0-indexed** integer arrays `fronts` and `backs` of length `n`, where the ith card has the positive integer `fronts[i]` printed on the front and `backs[i]` printed on the back. Initially, each card is placed on a table such that the front number is facing up and the other is facing down. You may flip over any number of cards (possibly zero). + +After flipping the cards, an integer is considered **good** if it is facing down on some card and **not** facing up on any card. + +Return _the minimum possible good integer after flipping the cards_. If there are no good integers, return `0`. + +**Example 1:** + +**Input:** fronts = [1,2,4,4,7], backs = [1,3,4,1,3] + +**Output:** 2 + +**Explanation:** + +If we flip the second card, the face up numbers are [1,3,4,4,7] and the face down are [1,2,4,1,3]. + +2 is the minimum good integer as it appears facing down but not facing up. + +It can be shown that 2 is the minimum possible good integer obtainable after flipping some cards. + +**Example 2:** + +**Input:** fronts = [1], backs = [1] + +**Output:** 0 + +**Explanation:** There are no good integers no matter how we flip the cards, so we return 0. + +**Constraints:** + +* `n == fronts.length == backs.length` +* `1 <= n <= 1000` +* `1 <= fronts[i], backs[i] <= 2000` + +## Solution + +```kotlin +class Solution { + fun flipgame(fronts: IntArray, backs: IntArray): Int { + val max = findMax(fronts, backs) + var value = 10000 + val twinCardHash = IntArray(max + 1) + val existingNumbersHash = IntArray(max + 1) + for (i in fronts.indices) { + if (fronts[i] == backs[i]) { + twinCardHash[fronts[i]]++ + } + existingNumbersHash[fronts[i]]++ + existingNumbersHash[backs[i]]++ + } + for (i in 1..max) { + if (twinCardHash[i] == 0 && i < value && existingNumbersHash[i] != 0) { + value = i + break + } + } + return if (value == 10000) { + 0 + } else { + value + } + } + + companion object { + private fun findMax(fronts: IntArray, backs: IntArray): Int { + var max = 0 + for (front in fronts) { + if (max < front) { + max = front + } + } + for (back in backs) { + if (max < back) { + max = back + } + } + return max + } + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0823_binary_trees_with_factors/readme.md b/src/main/kotlin/g0801_0900/s0823_binary_trees_with_factors/readme.md new file mode 100644 index 00000000..035ebff8 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0823_binary_trees_with_factors/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) + +## 823\. Binary Trees With Factors + +Medium + +Given an array of unique integers, `arr`, where each integer `arr[i]` is strictly greater than `1`. + +We make a binary tree using these integers, and each number may be used for any number of times. Each non-leaf node's value should be equal to the product of the values of its children. + +Return _the number of binary trees we can make_. The answer may be too large so return the answer **modulo** 109 + 7. + +**Example 1:** + +**Input:** arr = [2,4] + +**Output:** 3 + +**Explanation:** We can make these trees: `[2], [4], [4, 2, 2]` + +**Example 2:** + +**Input:** arr = [2,4,5,10] + +**Output:** 7 + +**Explanation:** We can make these trees: `[2], [4], [5], [10], [4, 2, 2], [10, 2, 5], [10, 5, 2]`. + +**Constraints:** + +* `1 <= arr.length <= 1000` +* 2 <= arr[i] <= 109 +* All the values of `arr` are **unique**. + +## Solution + +```kotlin +class Solution { + private val dp: MutableMap = HashMap() + private val nums: MutableMap = HashMap() + fun numFactoredBinaryTrees(arr: IntArray): Int { + arr.sort() + for (i in arr.indices) { + nums[arr[i]] = i + } + var ans: Long = 0 + for (i in arr.indices.reversed()) { + ans = (ans % MOD + recursion(arr, arr[i], i) % MOD) % MOD + } + return ans.toInt() + } + + private fun recursion(arr: IntArray, v: Int, idx: Int): Long { + if (dp.containsKey(v)) { + return dp[v]!! + } + var ret: Long = 1 + for (i in 0 until idx) { + val child = arr[i] + if (v % child == 0 && nums.containsKey(v / child)) { + ret += ( + ( + recursion(arr, child, nums[arr[i]]!!) % + MOD + * recursion(arr, v / child, nums[v / child]!!) % + MOD + ) % + MOD + ) + } + } + dp[v] = ret + return ret + } + + companion object { + private const val MOD = 1e9.toInt() + 7 + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0824_goat_latin/readme.md b/src/main/kotlin/g0801_0900/s0824_goat_latin/readme.md new file mode 100644 index 00000000..e4c5aa76 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0824_goat_latin/readme.md @@ -0,0 +1,67 @@ +[![](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) + +## 824\. Goat Latin + +Easy + +You are given a string `sentence` that consist of words separated by spaces. Each word consists of lowercase and uppercase letters only. + +We would like to convert the sentence to "Goat Latin" (a made-up language similar to Pig Latin.) The rules of Goat Latin are as follows: + +* If a word begins with a vowel (`'a'`, `'e'`, `'i'`, `'o'`, or `'u'`), append `"ma"` to the end of the word. + * For example, the word `"apple"` becomes `"applema"`. +* If a word begins with a consonant (i.e., not a vowel), remove the first letter and append it to the end, then add `"ma"`. + * For example, the word `"goat"` becomes `"oatgma"`. +* Add one letter `'a'` to the end of each word per its word index in the sentence, starting with `1`. + * For example, the first word gets `"a"` added to the end, the second word gets `"aa"` added to the end, and so on. + +Return _the final sentence representing the conversion from sentence to Goat Latin_. + +**Example 1:** + +**Input:** sentence = "I speak Goat Latin" + +**Output:** "Imaa peaksmaaa oatGmaaaa atinLmaaaaa" + +**Example 2:** + +**Input:** sentence = "The quick brown fox jumped over the lazy dog" + +**Output:** "heTmaa uickqmaaa rownbmaaaa oxfmaaaaa umpedjmaaaaaa overmaaaaaaa hetmaaaaaaaa azylmaaaaaaaaa ogdmaaaaaaaaaa" + +**Constraints:** + +* `1 <= sentence.length <= 150` +* `sentence` consists of English letters and spaces. +* `sentence` has no leading or trailing spaces. +* All the words in `sentence` are separated by a single space. + +## Solution + +```kotlin +class Solution { + fun toGoatLatin(sentence: String): String { + val splits = sentence.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + val sb = StringBuilder() + val a = StringBuilder() + for (word in splits) { + if (isVowel(word[0])) { + sb.append(word).append("ma") + } else { + val firstChar = word[0] + sb.append(word.substring(1)).append(firstChar).append("ma") + } + a.append("a") + sb.append(a) + sb.append(" ") + } + return sb.toString().trim { it <= ' ' } + } + + private fun isVowel(c: Char): Boolean { + return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || + c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U' + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0825_friends_of_appropriate_ages/readme.md b/src/main/kotlin/g0801_0900/s0825_friends_of_appropriate_ages/readme.md new file mode 100644 index 00000000..5559d6eb --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0825_friends_of_appropriate_ages/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) + +## 825\. Friends Of Appropriate Ages + +Medium + +There are `n` persons on a social media website. You are given an integer array `ages` where `ages[i]` is the age of the ith person. + +A Person `x` will not send a friend request to a person `y` (`x != y`) if any of the following conditions is true: + +* `age[y] <= 0.5 * age[x] + 7` +* `age[y] > age[x]` +* `age[y] > 100 && age[x] < 100` + +Otherwise, `x` will send a friend request to `y`. + +Note that if `x` sends a request to `y`, `y` will not necessarily send a request to `x`. Also, a person will not send a friend request to themself. + +Return _the total number of friend requests made_. + +**Example 1:** + +**Input:** ages = [16,16] + +**Output:** 2 + +**Explanation:** 2 people friend request each other. + +**Example 2:** + +**Input:** ages = [16,17,18] + +**Output:** 2 + +**Explanation:** Friend requests are made 17 -> 16, 18 -> 17. + +**Example 3:** + +**Input:** ages = [20,30,100,110,120] + +**Output:** 3 + +**Explanation:** Friend requests are made 110 -> 100, 120 -> 110, 120 -> 100. + +**Constraints:** + +* `n == ages.length` +* 1 <= n <= 2 * 104 +* `1 <= ages[i] <= 120` + +## Solution + +```kotlin +class Solution { + fun numFriendRequests(ages: IntArray): Int { + val counter = IntArray(121) + for (k in ages) { + counter[k]++ + } + var result = 0 + for (k in 15 until counter.size) { + if (counter[k] == 0) { + continue + } + result += counter[k] * (counter[k] - 1) + var y = k - 1 + while (y > k / 2.0 + 7) { + result += counter[k] * counter[y] + y-- + } + } + return result + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0826_most_profit_assigning_work/readme.md b/src/main/kotlin/g0801_0900/s0826_most_profit_assigning_work/readme.md new file mode 100644 index 00000000..d048d9bd --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0826_most_profit_assigning_work/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) + +## 826\. Most Profit Assigning Work + +Medium + +You have `n` jobs and `m` workers. You are given three arrays: `difficulty`, `profit`, and `worker` where: + +* `difficulty[i]` and `profit[i]` are the difficulty and the profit of the ith job, and +* `worker[j]` is the ability of jth worker (i.e., the jth worker can only complete a job with difficulty at most `worker[j]`). + +Every worker can be assigned **at most one job**, but one job can be **completed multiple times**. + +* For example, if three workers attempt the same job that pays `$1`, then the total profit will be `$3`. If a worker cannot complete any job, their profit is `$0`. + +Return the maximum profit we can achieve after assigning the workers to the jobs. + +**Example 1:** + +**Input:** difficulty = [2,4,6,8,10], profit = [10,20,30,40,50], worker = [4,5,6,7] + +**Output:** 100 + +**Explanation:** Workers are assigned jobs of difficulty [4,4,6,6] and they get a profit of [20,20,30,30] separately. + +**Example 2:** + +**Input:** difficulty = [85,47,57], profit = [24,66,99], worker = [40,25,25] + +**Output:** 0 + +**Constraints:** + +* `n == difficulty.length` +* `n == profit.length` +* `m == worker.length` +* 1 <= n, m <= 104 +* 1 <= difficulty[i], profit[i], worker[i] <= 105 + +## Solution + +```kotlin +class Solution { + fun maxProfitAssignment(difficulty: IntArray, profit: IntArray, worker: IntArray): Int { + val n = 100000 + val maxProfit = IntArray(n) + for (i in difficulty.indices) { + maxProfit[difficulty[i]] = maxProfit[difficulty[i]].coerceAtLeast(profit[i]) + } + for (i in 1 until n) { + maxProfit[i] = maxProfit[i].coerceAtLeast(maxProfit[i - 1]) + } + var sum = 0 + for (efficiency in worker) { + sum += maxProfit[efficiency] + } + return sum + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0827_making_a_large_island/readme.md b/src/main/kotlin/g0801_0900/s0827_making_a_large_island/readme.md new file mode 100644 index 00000000..1960f8d5 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0827_making_a_large_island/readme.md @@ -0,0 +1,133 @@ +[![](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) + +## 827\. Making A Large Island + +Hard + +You are given an `n x n` binary matrix `grid`. You are allowed to change **at most one** `0` to be `1`. + +Return _the size of the largest **island** in_ `grid` _after applying this operation_. + +An **island** is a 4-directionally connected group of `1`s. + +**Example 1:** + +**Input:** grid = \[\[1,0],[0,1]] + +**Output:** 3 + +**Explanation:** Change one 0 to 1 and connect two 1s, then we get an island with area = 3. + +**Example 2:** + +**Input:** grid = \[\[1,1],[1,0]] + +**Output:** 4 + +**Explanation:** Change the 0 to 1 and make the island bigger, only one island with area = 4. + +**Example 3:** + +**Input:** grid = \[\[1,1],[1,1]] + +**Output:** 4 + +**Explanation:** Can't change any 0 to 1, only one island with area = 4. + +**Constraints:** + +* `n == grid.length` +* `n == grid[i].length` +* `1 <= n <= 500` +* `grid[i][j]` is either `0` or `1`. + +## Solution + +```kotlin +class Solution { + private lateinit var p: IntArray + private lateinit var s: IntArray + + private fun makeSet(x: Int, y: Int, rl: Int) { + val a = x * rl + y + p[a] = a + s[a] = 1 + } + + private fun comb(x1: Int, y1: Int, x2: Int, y2: Int, rl: Int) { + var a = find(x1 * rl + y1) + var b = find(x2 * rl + y2) + if (a == b) { + return + } + if (s[a] < s[b]) { + val t = a + a = b + b = t + } + p[b] = a + s[a] += s[b] + } + + private fun find(a: Int): Int { + if (p[a] == a) { + return a + } + p[a] = find(p[a]) + return p[a] + } + + fun largestIsland(grid: Array): Int { + val rl = grid.size + val cl = grid[0].size + p = IntArray(rl * cl) + s = IntArray(rl * cl) + for (i in 0 until rl) { + for (j in 0 until cl) { + if (grid[i][j] == 0) { + continue + } + makeSet(i, j, rl) + if (i > 0 && grid[i - 1][j] == 1) { + comb(i, j, i - 1, j, rl) + } + if (j > 0 && grid[i][j - 1] == 1) { + comb(i, j, i, j - 1, rl) + } + } + } + var m = 0 + var t: Int + val sz: HashMap = HashMap() + for (i in 0 until rl) { + for (j in 0 until cl) { + if (grid[i][j] == 0) { + // find root, check if same and combine size + t = 1 + if (i > 0 && grid[i - 1][j] == 1) { + sz[find((i - 1) * rl + j)] = s[find((i - 1) * rl + j)] + } + if (j > 0 && grid[i][j - 1] == 1) { + sz[find(i * rl + j - 1)] = s[find(i * rl + j - 1)] + } + if (i < rl - 1 && grid[i + 1][j] == 1) { + sz[find((i + 1) * rl + j)] = s[find((i + 1) * rl + j)] + } + if (j < cl - 1 && grid[i][j + 1] == 1) { + sz[find(i * rl + j + 1)] = s[find(i * rl + j + 1)] + } + for (`val` in sz.values) { + t += `val` + } + m = m.coerceAtLeast(t) + sz.clear() + } else { + m = m.coerceAtLeast(s[i * rl + j]) + } + } + } + return m + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0828_count_unique_characters_of_all_substrings_of_a_given_string/readme.md b/src/main/kotlin/g0801_0900/s0828_count_unique_characters_of_all_substrings_of_a_given_string/readme.md new file mode 100644 index 00000000..a8cff8cb --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0828_count_unique_characters_of_all_substrings_of_a_given_string/readme.md @@ -0,0 +1,92 @@ +[![](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) + +## 828\. Count Unique Characters of All Substrings of a Given String + +Hard + +Let's define a function `countUniqueChars(s)` that returns the number of unique characters on `s`. + +* For example, calling `countUniqueChars(s)` if `s = "LEETCODE"` then `"L"`, `"T"`, `"C"`, `"O"`, `"D"` are the unique characters since they appear only once in `s`, therefore `countUniqueChars(s) = 5`. + +Given a string `s`, return the sum of `countUniqueChars(t)` where `t` is a substring of `s`. The test cases are generated such that the answer fits in a 32-bit integer. + +Notice that some substrings can be repeated so in this case you have to count the repeated ones too. + +**Example 1:** + +**Input:** s = "ABC" + +**Output:** 10 + +**Explanation:** All possible substrings are: "A","B","C","AB","BC" and "ABC". + +Every substring is composed with only unique letters. + +Sum of lengths of all substring is 1 + 1 + 1 + 2 + 2 + 3 = 10 + +**Example 2:** + +**Input:** s = "ABA" + +**Output:** 8 + +**Explanation:** The same as example 1, except `countUniqueChars`("ABA") = 1. + +**Example 3:** + +**Input:** s = "LEETCODE" + +**Output:** 92 + +**Constraints:** + +* 1 <= s.length <= 105 +* `s` consists of uppercase English letters only. + +## Solution + +```kotlin +class Solution { + fun uniqueLetterString(s: String): Int { + // Store last index of a character. + val lastCharIdx = IntArray(26) + // Store last to last index of a character. + // Eg. For ABA - lastCharIdx = 2, prevLastCharIdx = 0. + val prevLastCharIdx = IntArray(26) + lastCharIdx.fill(-1) + prevLastCharIdx.fill(-1) + val len = s.length + val dp = IntArray(len) + var account = 1 + dp[0] = 1 + lastCharIdx[s[0].code - 'A'.code] = 0 + prevLastCharIdx[s[0].code - 'A'.code] = 0 + for (i in 1 until len) { + val ch = s[i] + val chIdx = ch.code - 'A'.code + val lastSeenIdx = lastCharIdx[chIdx] + val prevLastIdx = prevLastCharIdx[chIdx] + dp[i] = dp[i - 1] + 1 + if (lastSeenIdx == -1) { + dp[i] += i + } else { + // Add count for curr index from index of last char appearance. + dp[i] += i - lastSeenIdx - 1 + if (prevLastIdx == lastSeenIdx) { + // if last char idx is the only appearance of the char from left so far, + // substrings that overlap [0, lastSeenIdx] will need count to be discounted, as + // current char will cause duplication. + dp[i] -= lastSeenIdx + 1 + } else { + dp[i] -= lastSeenIdx - prevLastIdx + } + } + prevLastCharIdx[chIdx] = lastSeenIdx + lastCharIdx[chIdx] = i + account += dp[i] + } + return account + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0829_consecutive_numbers_sum/readme.md b/src/main/kotlin/g0801_0900/s0829_consecutive_numbers_sum/readme.md new file mode 100644 index 00000000..97607d74 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0829_consecutive_numbers_sum/readme.md @@ -0,0 +1,62 @@ +[![](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) + +## 829\. Consecutive Numbers Sum + +Hard + +Given an integer `n`, return _the number of ways you can write_ `n` _as the sum of consecutive positive integers._ + +**Example 1:** + +**Input:** n = 5 + +**Output:** 2 + +**Explanation:** 5 = 2 + 3 + +**Example 2:** + +**Input:** n = 9 + +**Output:** 3 + +**Explanation:** 9 = 4 + 5 = 2 + 3 + 4 + +**Example 3:** + +**Input:** n = 15 + +**Output:** 4 + +**Explanation:** 15 = 8 + 7 = 4 + 5 + 6 = 1 + 2 + 3 + 4 + 5 + +**Constraints:** + +* 1 <= n <= 109 + +## Solution + +```kotlin +class Solution { + fun consecutiveNumbersSum(n: Int): Int { + var ans = 0 + var i = 1 + while (i * i <= n) { + if (n % i > 0) { + i++ + continue + } + val j = n / i + if (i % 2 == 1) { + ans++ + } + if (j != i && j % 2 == 1) { + ans++ + } + i++ + } + return ans + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0830_positions_of_large_groups/readme.md b/src/main/kotlin/g0801_0900/s0830_positions_of_large_groups/readme.md new file mode 100644 index 00000000..0f1f0a79 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0830_positions_of_large_groups/readme.md @@ -0,0 +1,67 @@ +[![](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) + +## 830\. Positions of Large Groups + +Easy + +In a string `s` of lowercase letters, these letters form consecutive groups of the same character. + +For example, a string like `s = "abbxxxxzyy"` has the groups `"a"`, `"bb"`, `"xxxx"`, `"z"`, and `"yy"`. + +A group is identified by an interval `[start, end]`, where `start` and `end` denote the start and end indices (inclusive) of the group. In the above example, `"xxxx"` has the interval `[3,6]`. + +A group is considered **large** if it has 3 or more characters. + +Return _the intervals of every **large** group sorted in **increasing order by start index**_. + +**Example 1:** + +**Input:** s = "abbxxxxzzy" + +**Output:** [[3,6]] + +**Explanation:** `"xxxx" is the only` large group with start index 3 and end index 6. + +**Example 2:** + +**Input:** s = "abc" + +**Output:** [] + +**Explanation:** We have groups "a", "b", and "c", none of which are large groups. + +**Example 3:** + +**Input:** s = "abcdddeeeeaabbbcd" + +**Output:** [[3,5],[6,9],[12,14]] + +**Explanation:** The large groups are "ddd", "eeee", and "bbb". + +**Constraints:** + +* `1 <= s.length <= 1000` +* `s` contains lowercase English letters only. + +## Solution + +```kotlin +class Solution { + fun largeGroupPositions(s: String): List> { + val map: MutableList> = ArrayList() + var i = 0 + while (i < s.length) { + var j = i + while (j < s.length && s[j] == s[i]) { + j++ + } + if (j - 1 - i + 1 >= 3) { + map.add(listOf(i, j - 1)) + } + i = j + } + return map + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0831_masking_personal_information/readme.md b/src/main/kotlin/g0801_0900/s0831_masking_personal_information/readme.md new file mode 100644 index 00000000..92f1044c --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0831_masking_personal_information/readme.md @@ -0,0 +1,119 @@ +[![](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) + +## 831\. Masking Personal Information + +Medium + +You are given a personal information string `s`, representing either an **email address** or a **phone number**. Return _the **masked** personal information using the below rules_. + +**Email address:** + +An email address is: + +* A **name** consisting of uppercase and lowercase English letters, followed by +* The `'@'` symbol, followed by +* The **domain** consisting of uppercase and lowercase English letters with a dot `'.'` somewhere in the middle (not the first or last character). + +To mask an email: + +* The uppercase letters in the **name** and **domain** must be converted to lowercase letters. +* The middle letters of the **name** (i.e., all but the first and last letters) must be replaced by 5 asterisks `"*****"`. + +**Phone number:** + +A phone number is formatted as follows: + +* The phone number contains 10-13 digits. +* The last 10 digits make up the **local number**. +* The remaining 0-3 digits, in the beginning, make up the **country code**. +* **Separation characters** from the set `{'+', '-', '(', ')', ' '}` separate the above digits in some way. + +To mask a phone number: + +* Remove all **separation characters**. +* The masked phone number should have the form: + * `"***-***-XXXX"` if the country code has 0 digits. + * `"+*-***-***-XXXX"` if the country code has 1 digit. + * `"+**-***-***-XXXX"` if the country code has 2 digits. + * `"+***-***-***-XXXX"` if the country code has 3 digits. +* `"XXXX"` is the last 4 digits of the **local number**. + +**Example 1:** + +**Input:** s = "LeetCode@LeetCode.com" + +**Output:** "l\*\*\*\*\*e@leetcode.com" + +**Explanation:** s is an email address. + +The name and domain are converted to lowercase, and the middle of the name is replaced by 5 asterisks. + +**Example 2:** + +**Input:** s = "AB@qq.com" + +**Output:** "a\*\*\*\*\*b@qq.com" + +**Explanation:** s is an email address. + +The name and domain are converted to lowercase, and the middle of the name is replaced by 5 asterisks. + +Note that even though "ab" is 2 characters, it still must have 5 asterisks in the middle. + +**Example 3:** + +**Input:** s = "1(234)567-890" + +**Output:** "\*\*\*-\*\*\*-7890" + +**Explanation:** s is a phone number. + +There are 10 digits, so the local number is 10 digits and the country code is 0 digits. + +Thus, the resulting masked number is "\*\*\*-\*\*\*-7890". + +**Constraints:** + +* `s` is either a **valid** email or a phone number. +* If `s` is an email: + * `8 <= s.length <= 40` + * `s` consists of uppercase and lowercase English letters and exactly one `'@'` symbol and `'.'` symbol. +* If `s` is a phone number: + * `10 <= s.length <= 20` + * `s` consists of digits, spaces, and the symbols `'('`, `')'`, `'-'`, and `'+'`. + +## Solution + +```kotlin +import java.util.Locale + +class Solution { + fun maskPII(s: String): String { + val masked = StringBuilder() + return if (Character.isAlphabetic(s[0].code)) { + val locationOfAtSymbol = s.indexOf("@") - 1 + masked.append(s[0]).append("*****").append(s.substring(locationOfAtSymbol)) + masked.toString().lowercase(Locale.getDefault()) + } else { + val allDigits = StringBuilder() + var pointer = -1 + while (++pointer < s.length) { + if (Character.isDigit(s[pointer])) { + allDigits.append(s[pointer]) + } + } + val numDigits = allDigits.length + if (numDigits == 11) { + masked.append("+*-") + } else if (numDigits == 12) { + masked.append("+**-") + } else if (numDigits == 13) { + masked.append("+***-") + } + masked.append("***-***-").append(allDigits.substring(numDigits - 4)) + masked.toString() + } + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0832_flipping_an_image/readme.md b/src/main/kotlin/g0801_0900/s0832_flipping_an_image/readme.md new file mode 100644 index 00000000..31e4696d --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0832_flipping_an_image/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) + +## 832\. Flipping an Image + +Easy + +Given an `n x n` binary matrix `image`, flip the image **horizontally**, then invert it, and return _the resulting image_. + +To flip an image horizontally means that each row of the image is reversed. + +* For example, flipping `[1,1,0]` horizontally results in `[0,1,1]`. + +To invert an image means that each `0` is replaced by `1`, and each `1` is replaced by `0`. + +* For example, inverting `[0,1,1]` results in `[1,0,0]`. + +**Example 1:** + +**Input:** image = \[\[1,1,0],[1,0,1],[0,0,0]] + +**Output:** [[1,0,0],[0,1,0],[1,1,1]] + +**Explanation:** First reverse each row: [[0,1,1],[1,0,1],[0,0,0]]. Then, invert the image: [[1,0,0],[0,1,0],[1,1,1]] + +**Example 2:** + +**Input:** image = \[\[1,1,0,0],[1,0,0,1],[0,1,1,1],[1,0,1,0]] + +**Output:** [[1,1,0,0],[0,1,1,0],[0,0,0,1],[1,0,1,0]] + +**Explanation:** First reverse each row: [[0,0,1,1],[1,0,0,1],[1,1,1,0],[0,1,0,1]]. Then invert the image: [[1,1,0,0],[0,1,1,0],[0,0,0,1],[1,0,1,0]] + +**Constraints:** + +* `n == image.length` +* `n == image[i].length` +* `1 <= n <= 20` +* `images[i][j]` is either `0` or `1`. + +## Solution + +```kotlin +class Solution { + fun flipAndInvertImage(image: Array): Array { + val m = image.size + val n = image[0].size + val result = Array(m) { IntArray(n) } + for (i in 0 until m) { + val flipped = reverse(image[i]) + result[i] = invert(flipped) + } + return result + } + + private fun invert(flipped: IntArray): IntArray { + val result = IntArray(flipped.size) + for (i in flipped.indices) { + if (flipped[i] == 0) { + result[i] = 1 + } else { + result[i] = 0 + } + } + return result + } + + private fun reverse(nums: IntArray): IntArray { + var i = 0 + var j = nums.size - 1 + while (i < j) { + val tmp = nums[i] + nums[i] = nums[j] + nums[j] = tmp + i++ + j-- + } + return nums + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0833_find_and_replace_in_string/readme.md b/src/main/kotlin/g0801_0900/s0833_find_and_replace_in_string/readme.md new file mode 100644 index 00000000..82fa2e9f --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0833_find_and_replace_in_string/readme.md @@ -0,0 +1,89 @@ +[![](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) + +## 833\. Find And Replace in String + +Medium + +You are given a **0-indexed** string `s` that you must perform `k` replacement operations on. The replacement operations are given as three **0-indexed** parallel arrays, `indices`, `sources`, and `targets`, all of length `k`. + +To complete the ith replacement operation: + +1. Check if the **substring** `sources[i]` occurs at index `indices[i]` in the **original string** `s`. +2. If it does not occur, **do nothing**. +3. Otherwise if it does occur, **replace** that substring with `targets[i]`. + +For example, if `s = "abcd"`, `indices[i] = 0`, `sources[i] = "ab"`, and `targets[i] = "eee"`, then the result of this replacement will be `"eeecd"`. + +All replacement operations must occur **simultaneously**, meaning the replacement operations should not affect the indexing of each other. The testcases will be generated such that the replacements will **not overlap**. + +* For example, a testcase with `s = "abc"`, `indices = [0, 1]`, and `sources = ["ab","bc"]` will not be generated because the `"ab"` and `"bc"` replacements overlap. + +Return _the **resulting string** after performing all replacement operations on_ `s`. + +A **substring** is a contiguous sequence of characters in a string. + +**Example 1:** + +![](https://assets.leetcode.com/uploads/2021/06/12/833-ex1.png) + +**Input:** s = "abcd", indices = [0, 2], sources = ["a", "cd"], targets = ["eee", "ffff"] + +**Output:** "eeebffff" + +**Explanation:** "a" occurs at index 0 in s, so we replace it with "eee". "cd" occurs at index 2 in s, so we replace it with "ffff". + +**Example 2:** + +![](https://assets.leetcode.com/uploads/2021/06/12/833-ex2-1.png) + +**Input:** s = "abcd", indices = [0, 2], sources = ["ab","ec"], targets = ["eee","ffff"] + +**Output:** "eeecd" + +**Explanation:** "ab" occurs at index 0 in s, so we replace it with "eee". "ec" does not occur at index 2 in s, so we do nothing. + +**Constraints:** + +* `1 <= s.length <= 1000` +* `k == indices.length == sources.length == targets.length` +* `1 <= k <= 100` +* `0 <= indexes[i] < s.length` +* `1 <= sources[i].length, targets[i].length <= 50` +* `s` consists of only lowercase English letters. +* `sources[i]` and `targets[i]` consist of only lowercase English letters. + +## Solution + +```kotlin +class Solution { + fun findReplaceString(s: String, indices: IntArray, sources: Array, targets: Array): String { + val sb = StringBuilder() + val stringIndexToKIndex: MutableMap = HashMap() + for (i in indices.indices) { + stringIndexToKIndex[indices[i]] = i + } + var indexIntoS = 0 + while (indexIntoS < s.length) { + if (stringIndexToKIndex.containsKey(indexIntoS)) { + val substringInSources = sources[stringIndexToKIndex[indexIntoS]!!] + if (indexIntoS + substringInSources.length <= s.length) { + val substringInS = s.substring(indexIntoS, indexIntoS + substringInSources.length) + if (substringInS == substringInSources) { + sb.append(targets[stringIndexToKIndex[indexIntoS]!!]) + indexIntoS += substringInS.length - 1 + } else { + sb.append(s[indexIntoS]) + } + } else { + sb.append(s[indexIntoS]) + } + } else { + sb.append(s[indexIntoS]) + } + indexIntoS++ + } + return sb.toString() + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0834_sum_of_distances_in_tree/readme.md b/src/main/kotlin/g0801_0900/s0834_sum_of_distances_in_tree/readme.md new file mode 100644 index 00000000..183ce3ea --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0834_sum_of_distances_in_tree/readme.md @@ -0,0 +1,99 @@ +[![](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) + +## 834\. Sum of Distances in Tree + +Hard + +There is an undirected connected tree with `n` nodes labeled from `0` to `n - 1` and `n - 1` edges. + +You are given the integer `n` and the array `edges` where edges[i] = [ai, bi] indicates that there is an edge between nodes ai and bi in the tree. + +Return an array `answer` of length `n` where `answer[i]` is the sum of the distances between the ith node in the tree and all other nodes. + +**Example 1:** + +![](https://assets.leetcode.com/uploads/2021/07/23/lc-sumdist1.jpg) + +**Input:** n = 6, edges = \[\[0,1],[0,2],[2,3],[2,4],[2,5]] + +**Output:** [8,12,6,10,10,10] + +**Explanation:** The tree is shown above. + +We can see that dist(0,1) + dist(0,2) + dist(0,3) + dist(0,4) + dist(0,5) equals 1 + 1 + 2 + 2 + 2 = 8. + +Hence, answer[0] = 8, and so on. + +**Example 2:** + +![](https://assets.leetcode.com/uploads/2021/07/23/lc-sumdist2.jpg) + +**Input:** n = 1, edges = [] + +**Output:** [0] + +**Example 3:** + +![](https://assets.leetcode.com/uploads/2021/07/23/lc-sumdist3.jpg) + +**Input:** n = 2, edges = \[\[1,0]] + +**Output:** [1,1] + +**Constraints:** + +* 1 <= n <= 3 * 104 +* `edges.length == n - 1` +* `edges[i].length == 2` +* 0 <= ai, bi < n +* ai != bi +* The given input represents a valid tree. + +## Solution + +```kotlin +class Solution { + private var n = 0 + private lateinit var count: IntArray + private lateinit var answer: IntArray + private lateinit var graph: Array?> + + private fun postorder(node: Int, parent: Int) { + for (child in graph[node]!!) { + if (child != parent) { + postorder(child, node) + count[node] += count[child] + answer[node] += answer[child] + count[child] + } + } + } + + private fun preorder(node: Int, parent: Int) { + for (child in graph[node]!!) { + if (child != parent) { + answer[child] = answer[node] - count[child] + n - count[child] + preorder(child, node) + } + } + } + + fun sumOfDistancesInTree(n: Int, edges: Array): IntArray { + this.n = n + count = IntArray(n) + answer = IntArray(n) + graph = arrayOfNulls(n) + count.fill(1) + for (i in 0 until n) { + graph[i] = ArrayList() + } + for (edge in edges) { + graph[edge[0]]?.add(edge[1]) + graph[edge[1]]?.add(edge[0]) + } + postorder(0, -1) + preorder(0, -1) + return answer + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0835_image_overlap/readme.md b/src/main/kotlin/g0801_0900/s0835_image_overlap/readme.md new file mode 100644 index 00000000..ffc17be4 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0835_image_overlap/readme.md @@ -0,0 +1,95 @@ +[![](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) + +## 835\. Image Overlap + +Medium + +You are given two images, `img1` and `img2`, represented as binary, square matrices of size `n x n`. A binary matrix has only `0`s and `1`s as values. + +We **translate** one image however we choose by sliding all the `1` bits left, right, up, and/or down any number of units. We then place it on top of the other image. We can then calculate the **overlap** by counting the number of positions that have a `1` in **both** images. + +Note also that a translation does **not** include any kind of rotation. Any `1` bits that are translated outside of the matrix borders are erased. + +Return _the largest possible overlap_. + +**Example 1:** + +![](https://assets.leetcode.com/uploads/2020/09/09/overlap1.jpg) + +**Input:** img1 = \[\[1,1,0],[0,1,0],[0,1,0]], img2 = \[\[0,0,0],[0,1,1],[0,0,1]] + +**Output:** 3 + +**Explanation:** We translate img1 to right by 1 unit and down by 1 unit. ![](https://assets.leetcode.com/uploads/2020/09/09/overlap_step1.jpg) The number of positions that have a 1 in both images is 3 (shown in red). ![](https://assets.leetcode.com/uploads/2020/09/09/overlap_step2.jpg) + +**Example 2:** + +**Input:** img1 = \[\[1]], img2 = \[\[1]] + +**Output:** 1 + +**Example 3:** + +**Input:** img1 = \[\[0]], img2 = \[\[0]] + +**Output:** 0 + +**Constraints:** + +* `n == img1.length == img1[i].length` +* `n == img2.length == img2[i].length` +* `1 <= n <= 30` +* `img1[i][j]` is either `0` or `1`. +* `img2[i][j]` is either `0` or `1`. + +## Solution + +```kotlin +class Solution { + fun largestOverlap(img1: Array, img2: Array): Int { + val bits1 = bitwise(img1) + val bits2 = bitwise(img2) + val n = img1.size + var res = 0 + for (hori in -1 * n + 1 until n) { + for (veti in -1 * n + 1 until n) { + var curOverLapping = 0 + if (veti < 0) { + for (i in -1 * veti until n) { + curOverLapping += if (hori < 0) { + Integer.bitCount( + bits1[i] shl -1 * hori and bits2[i - -1 * veti] + ) + } else { + Integer.bitCount(bits1[i] shr hori and bits2[i - -1 * veti]) + } + } + } else { + for (i in 0 until n - veti) { + curOverLapping += if (hori < 0) { + Integer.bitCount(bits1[i] shl -1 * hori and bits2[veti + i]) + } else { + Integer.bitCount(bits1[i] shr hori and bits2[veti + i]) + } + } + } + res = Math.max(res, curOverLapping) + } + } + return res + } + + private fun bitwise(img: Array): IntArray { + val bits = IntArray(img.size) + for (i in img.indices) { + var cur = 0 + for (j in img[0].indices) { + cur = cur * 2 + img[i][j] + } + bits[i] = cur + } + return bits + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0836_rectangle_overlap/readme.md b/src/main/kotlin/g0801_0900/s0836_rectangle_overlap/readme.md new file mode 100644 index 00000000..e4772849 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0836_rectangle_overlap/readme.md @@ -0,0 +1,47 @@ +[![](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) + +## 836\. Rectangle Overlap + +Easy + +An axis-aligned rectangle is represented as a list `[x1, y1, x2, y2]`, where `(x1, y1)` is the coordinate of its bottom-left corner, and `(x2, y2)` is the coordinate of its top-right corner. Its top and bottom edges are parallel to the X-axis, and its left and right edges are parallel to the Y-axis. + +Two rectangles overlap if the area of their intersection is **positive**. To be clear, two rectangles that only touch at the corner or edges do not overlap. + +Given two axis-aligned rectangles `rec1` and `rec2`, return `true` _if they overlap, otherwise return_ `false`. + +**Example 1:** + +**Input:** rec1 = [0,0,2,2], rec2 = [1,1,3,3] + +**Output:** true + +**Example 2:** + +**Input:** rec1 = [0,0,1,1], rec2 = [1,0,2,1] + +**Output:** false + +**Example 3:** + +**Input:** rec1 = [0,0,1,1], rec2 = [2,2,3,3] + +**Output:** false + +**Constraints:** + +* `rec1.length == 4` +* `rec2.length == 4` +* -109 <= rec1[i], rec2[i] <= 109 +* `rec1` and `rec2` represent a valid rectangle with a non-zero area. + +## Solution + +```kotlin +class Solution { + fun isRectangleOverlap(rec1: IntArray, rec2: IntArray): Boolean { + return rec1[0] < rec2[2] && rec2[0] < rec1[2] && rec1[1] < rec2[3] && rec2[1] < rec1[3] + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0837_new_21_game/readme.md b/src/main/kotlin/g0801_0900/s0837_new_21_game/readme.md new file mode 100644 index 00000000..f2474e06 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0837_new_21_game/readme.md @@ -0,0 +1,71 @@ +[![](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) + +## 837\. New 21 Game + +Medium + +Alice plays the following game, loosely based on the card game **"21"**. + +Alice starts with `0` points and draws numbers while she has less than `k` points. During each draw, she gains an integer number of points randomly from the range `[1, maxPts]`, where `maxPts` is an integer. Each draw is independent and the outcomes have equal probabilities. + +Alice stops drawing numbers when she gets `k` **or more points**. + +Return the probability that Alice has `n` or fewer points. + +Answers within 10-5 of the actual answer are considered accepted. + +**Example 1:** + +**Input:** n = 10, k = 1, maxPts = 10 + +**Output:** 1.00000 + +**Explanation:** Alice gets a single card, then stops. + +**Example 2:** + +**Input:** n = 6, k = 1, maxPts = 10 + +**Output:** 0.60000 + +**Explanation:** Alice gets a single card, then stops. In 6 out of 10 possibilities, she is at or below 6 points. + +**Example 3:** + +**Input:** n = 21, k = 17, maxPts = 10 + +**Output:** 0.73278 + +**Constraints:** + +* 0 <= k <= n <= 104 +* 1 <= maxPts <= 104 + +## Solution + +```kotlin +class Solution { + fun new21Game(n: Int, k: Int, maxPts: Int): Double { + if (k == 0) return 1.00 + if (k == 1 && maxPts <= n) return 1.00 + val dp = DoubleArray(n + 1) + dp[0] = 1.00 + var prev = 0.00 + for (i in 1..n) { + if (i - maxPts - 1 >= 0) { + prev -= dp[i - 1 - maxPts] + } + if (i - 1 < k) { + prev += dp[i - 1] + } + dp[i] = prev / maxPts + } + var res = 0.00 + for (i in k..n) { + res += dp[i] + } + return res + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0838_push_dominoes/readme.md b/src/main/kotlin/g0801_0900/s0838_push_dominoes/readme.md new file mode 100644 index 00000000..89a60014 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0838_push_dominoes/readme.md @@ -0,0 +1,98 @@ +[![](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) + +## 838\. Push Dominoes + +Medium + +There are `n` dominoes in a line, and we place each domino vertically upright. In the beginning, we simultaneously push some of the dominoes either to the left or to the right. + +After each second, each domino that is falling to the left pushes the adjacent domino on the left. Similarly, the dominoes falling to the right push their adjacent dominoes standing on the right. + +When a vertical domino has dominoes falling on it from both sides, it stays still due to the balance of the forces. + +For the purposes of this question, we will consider that a falling domino expends no additional force to a falling or already fallen domino. + +You are given a string `dominoes` representing the initial state where: + +* `dominoes[i] = 'L'`, if the ith domino has been pushed to the left, +* `dominoes[i] = 'R'`, if the ith domino has been pushed to the right, and +* `dominoes[i] = '.'`, if the ith domino has not been pushed. + +Return _a string representing the final state_. + +**Example 1:** + +**Input:** dominoes = "RR.L" + +**Output:** "RR.L" + +**Explanation:** The first domino expends no additional force on the second domino. + +**Example 2:** + +![](https://s3-lc-upload.s3.amazonaws.com/uploads/2018/05/18/domino.png) + +**Input:** dominoes = ".L.R...LR..L.." + +**Output:** "LL.RR.LLRRLL.." + +**Constraints:** + +* `n == dominoes.length` +* 1 <= n <= 105 +* `dominoes[i]` is either `'L'`, `'R'`, or `'.'`. + +## Solution + +```kotlin +class Solution { + fun pushDominoes(dominoes: String): String { + val ch = CharArray(dominoes.length + 2) + ch[0] = 'L' + ch[ch.size - 1] = 'R' + for (k in 1 until ch.size - 1) { + ch[k] = dominoes[k - 1] + } + var i = 0 + var j = 1 + while (j < ch.size) { + while (ch[j] == '.') { + j++ + } + if (ch[i] == 'L' && ch[j] == 'L') { + while (i != j) { + ch[i] = 'L' + i++ + } + j++ + } else if (ch[i] == 'R' && ch[j] == 'R') { + while (i != j) { + ch[i] = 'R' + i++ + } + j++ + } else if (ch[i] == 'L' && ch[j] == 'R') { + i = j + j++ + } else if (ch[i] == 'R' && ch[j] == 'L') { + var rTemp = i + 1 + var lTemp = j - 1 + while (rTemp < lTemp) { + ch[rTemp] = 'R' + ch[lTemp] = 'L' + rTemp++ + lTemp-- + } + i = j + j++ + } + } + val sb = StringBuilder() + for (k in 1 until ch.size - 1) { + sb.append(ch[k]) + } + return sb.toString() + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0839_similar_string_groups/readme.md b/src/main/kotlin/g0801_0900/s0839_similar_string_groups/readme.md new file mode 100644 index 00000000..ef90b893 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0839_similar_string_groups/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) + +## 839\. Similar String Groups + +Hard + +Two strings `X` and `Y` are similar if we can swap two letters (in different positions) of `X`, so that it equals `Y`. Also two strings `X` and `Y` are similar if they are equal. + +For example, `"tars"` and `"rats"` are similar (swapping at positions `0` and `2`), and `"rats"` and `"arts"` are similar, but `"star"` is not similar to `"tars"`, `"rats"`, or `"arts"`. + +Together, these form two connected groups by similarity: `{"tars", "rats", "arts"}` and `{"star"}`. Notice that `"tars"` and `"arts"` are in the same group even though they are not similar. Formally, each group is such that a word is in the group if and only if it is similar to at least one other word in the group. + +We are given a list `strs` of strings where every string in `strs` is an anagram of every other string in `strs`. How many groups are there? + +**Example 1:** + +**Input:** strs = ["tars","rats","arts","star"] + +**Output:** 2 + +**Example 2:** + +**Input:** strs = ["omv","ovm"] + +**Output:** 1 + +**Constraints:** + +* `1 <= strs.length <= 300` +* `1 <= strs[i].length <= 300` +* `strs[i]` consists of lowercase letters only. +* All words in `strs` have the same length and are anagrams of each other. + +## Solution + +```kotlin +import java.util.LinkedList +import java.util.Queue + +class Solution { + fun numSimilarGroups(strs: Array): Int { + val visited = BooleanArray(strs.size) + var res = 0 + for (i in strs.indices) { + if (!visited[i]) { + res++ + bfs(i, visited, strs) + } + } + return res + } + + private fun bfs(i: Int, visited: BooleanArray, strs: Array) { + val qu: Queue = LinkedList() + qu.add(strs[i]) + visited[i] = true + while (!qu.isEmpty()) { + val s = qu.poll() + for (j in strs.indices) { + if (visited[j]) { + continue + } + if (isSimilar(s, strs[j])) { + visited[j] = true + qu.add(strs[j]) + } + } + } + } + + private fun isSimilar(s1: String, s2: String): Boolean { + var c1: Char? = null + var c2: Char? = null + var mismatchCount = 0 + for (i in s1.indices) { + if (s1[i] == s2[i]) { + continue + } + mismatchCount++ + if (c1 == null) { + c1 = s1[i] + c2 = s2[i] + } else if (s2[i] != c1 || s1[i] != c2) { + return false + } else if (mismatchCount > 2) { + return false + } + } + return true + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0840_magic_squares_in_grid/readme.md b/src/main/kotlin/g0801_0900/s0840_magic_squares_in_grid/readme.md new file mode 100644 index 00000000..3f6ac2bc --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0840_magic_squares_in_grid/readme.md @@ -0,0 +1,83 @@ +[![](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) + +## 840\. Magic Squares In Grid + +Medium + +A `3 x 3` magic square is a `3 x 3` grid filled with distinct numbers **from** `1` **to** `9` such that each row, column, and both diagonals all have the same sum. + +Given a `row x col` `grid` of integers, how many `3 x 3` "magic square" subgrids are there? (Each subgrid is contiguous). + +**Example 1:** + +![](https://assets.leetcode.com/uploads/2020/09/11/magic_main.jpg) + +**Input:** grid = \[\[4,3,8,4],[9,5,1,9],[2,7,6,2]] + +**Output:** 1 + +**Explanation:** The following subgrid is a 3 x 3 magic square: ![](https://assets.leetcode.com/uploads/2020/09/11/magic_valid.jpg) while this one is not: ![](https://assets.leetcode.com/uploads/2020/09/11/magic_invalid.jpg) In total, there is only one magic square inside the given grid. + +**Example 2:** + +**Input:** grid = \[\[8]] + +**Output:** 0 + +**Constraints:** + +* `row == grid.length` +* `col == grid[i].length` +* `1 <= row, col <= 10` +* `0 <= grid[i][j] <= 15` + +## Solution + +```kotlin +class Solution { + fun numMagicSquaresInside(grid: Array): Int { + val m = grid.size + val n = grid[0].size + var count = 0 + for (i in 0 until m - 2) { + for (j in 0 until n - 2) { + val set: MutableSet = HashSet() + val sum = grid[i][j] + grid[i][j + 1] + grid[i][j + 2] + if (sum == grid[i + 1][j] + grid[i + 1][j + 1] + grid[i + 1][j + 2] && sum == grid[i + 2][j] + + grid[i + 2][j + 1] + grid[i + 2][j + 2] && sum == grid[i][j] + grid[i + 1][j] + grid[i + 2][j] && + sum == grid[i][j + 1] + grid[i + 1][j + 1] + grid[i + 2][j + 1] && sum == grid[i][j + 2] + + grid[i + 1][j + 2] + grid[i + 2][j + 2] && sum == grid[i][j] + grid[i + 1][j + 1] + + grid[i + 2][j + 2] && sum == grid[i][j + 2] + grid[i + 1][j + 1] + grid[i + 2][j] && set.add( + grid[i][j] + ) && + isLegit(grid[i][j]) && + set.add(grid[i][j + 1]) && + isLegit(grid[i][j + 1]) && + set.add(grid[i][j + 2]) && + isLegit(grid[i][j + 2]) && + set.add(grid[i + 1][j]) && + isLegit(grid[i + 1][j]) && + set.add(grid[i + 1][j + 1]) && + isLegit(grid[i + 1][j + 1]) && + set.add(grid[i + 1][j + 2]) && + isLegit(grid[i + 1][j + 2]) && + set.add(grid[i + 2][j]) && + isLegit(grid[i + 2][j]) && + set.add(grid[i + 2][j + 1]) && + isLegit(grid[i + 2][j + 1]) && + set.add(grid[i + 2][j + 2]) && + isLegit(grid[i + 2][j + 2]) + ) { + count++ + } + } + } + return count + } + + private fun isLegit(num: Int): Boolean { + return num in 1..9 + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0841_keys_and_rooms/readme.md b/src/main/kotlin/g0801_0900/s0841_keys_and_rooms/readme.md new file mode 100644 index 00000000..4f0e378d --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0841_keys_and_rooms/readme.md @@ -0,0 +1,72 @@ +[![](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) + +## 841\. Keys and Rooms + +Medium + +There are `n` rooms labeled from `0` to `n - 1` and all the rooms are locked except for room `0`. Your goal is to visit all the rooms. However, you cannot enter a locked room without having its key. + +When you visit a room, you may find a set of **distinct keys** in it. Each key has a number on it, denoting which room it unlocks, and you can take all of them with you to unlock the other rooms. + +Given an array `rooms` where `rooms[i]` is the set of keys that you can obtain if you visited room `i`, return `true` _if you can visit **all** the rooms, or_ `false` _otherwise_. + +**Example 1:** + +**Input:** rooms = \[\[1],[2],[3],[]] + +**Output:** true + +**Explanation:** + +We visit room 0 and pick up key 1. + +We then visit room 1 and pick up key 2. + +We then visit room 2 and pick up key 3. + +We then visit room 3. + +Since we were able to visit every room, we return true. + +**Example 2:** + +**Input:** rooms = \[\[1,3],[3,0,1],[2],[0]] + +**Output:** false + +**Explanation:** We can not enter room number 2 since the only key that unlocks it is in that room. + +**Constraints:** + +* `n == rooms.length` +* `2 <= n <= 1000` +* `0 <= rooms[i].length <= 1000` +* `1 <= sum(rooms[i].length) <= 3000` +* `0 <= rooms[i][j] < n` +* All the values of `rooms[i]` are **unique**. + +## Solution + +```kotlin +import java.util.TreeSet + +class Solution { + fun canVisitAllRooms(rooms: List?>): Boolean { + val visited: MutableSet = HashSet() + visited.add(0) + val treeSet = TreeSet(rooms[0]) + while (!treeSet.isEmpty()) { + val key = treeSet.pollFirst() + if (!visited.add(key)) { + continue + } + if (visited.size == rooms.size) { + return true + } + treeSet.addAll(rooms[key]!!) + } + return visited.size == rooms.size + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0842_split_array_into_fibonacci_sequence/readme.md b/src/main/kotlin/g0801_0900/s0842_split_array_into_fibonacci_sequence/readme.md new file mode 100644 index 00000000..ad6f5d61 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0842_split_array_into_fibonacci_sequence/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) + +## 842\. Split Array into Fibonacci Sequence + +Medium + +You are given a string of digits `num`, such as `"123456579"`. We can split it into a Fibonacci-like sequence `[123, 456, 579]`. + +Formally, a **Fibonacci-like** sequence is a list `f` of non-negative integers such that: + +* 0 <= f[i] < 231, (that is, each integer fits in a **32-bit** signed integer type), +* `f.length >= 3`, and +* `f[i] + f[i + 1] == f[i + 2]` for all `0 <= i < f.length - 2`. + +Note that when splitting the string into pieces, each piece must not have extra leading zeroes, except if the piece is the number `0` itself. + +Return any Fibonacci-like sequence split from `num`, or return `[]` if it cannot be done. + +**Example 1:** + +**Input:** num = "1101111" + +**Output:** [11,0,11,11] + +**Explanation:** The output [110, 1, 111] would also be accepted. + +**Example 2:** + +**Input:** num = "112358130" + +**Output:** [] + +**Explanation:** The task is impossible. + +**Example 3:** + +**Input:** num = "0123" + +**Output:** [] + +**Explanation:** Leading zeroes are not allowed, so "01", "2", "3" is not valid. + +**Constraints:** + +* `1 <= num.length <= 200` +* `num` contains only digits. + +## Solution + +```kotlin +class Solution { + fun splitIntoFibonacci(num: String): List { + val res: MutableList = ArrayList() + solve(num, res, 0) + return res + } + + private fun solve(s: String, res: MutableList, idx: Int): Boolean { + if (idx == s.length && res.size >= 3) { + return true + } + for (i in idx until s.length) { + if (s[idx] == '0' && i > idx) { + return false + } + val num = s.substring(idx, i + 1).toLong() + if (num > Int.MAX_VALUE) { + return false + } + val size = res.size + if (size >= 2 && num > res[size - 1] + res[size - 2]) { + return false + } + if (size <= 1 || num == (res[size - 1] + res[size - 2]).toLong()) { + res.add(num.toInt()) + if (solve(s, res, i + 1)) { + return true + } + res.removeAt(res.size - 1) + } + } + return false + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0843_guess_the_word/readme.md b/src/main/kotlin/g0801_0900/s0843_guess_the_word/readme.md new file mode 100644 index 00000000..e5d6105d --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0843_guess_the_word/readme.md @@ -0,0 +1,105 @@ +[![](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) + +## 843\. Guess the Word + +Hard + +This is an **_interactive problem_**. + +You are given an array of **unique** strings `wordlist` where `wordlist[i]` is `6` letters long, and one word in this list is chosen as `secret`. + +You may call `Master.guess(word)` to guess a word. The guessed word should have type `string` and must be from the original list with `6` lowercase letters. + +This function returns an `integer` type, representing the number of exact matches (value and position) of your guess to the `secret` word. Also, if your guess is not in the given wordlist, it will return `-1` instead. + +For each test case, you have exactly `10` guesses to guess the word. At the end of any number of calls, if you have made `10` or fewer calls to `Master.guess` and at least one of these guesses was `secret`, then you pass the test case. + +**Example 1:** + +**Input:** secret = "acckzz", wordlist = ["acckzz","ccbazz","eiowzz","abcczz"], numguesses = 10 + +**Output:** You guessed the secret word correctly. + +**Explanation:** + + master.guess("aaaaaa") returns -1, because "aaaaaa" is not in wordlist. + master.guess("acckzz") returns 6, because "acckzz" is secret and has all 6 matches. + master.guess("ccbazz") returns 3, because "ccbazz" has 3 matches. + master.guess("eiowzz") returns 2, because "eiowzz" has 2 matches. + master.guess("abcczz") returns 4, because "abcczz" has 4 matches. + We made 5 calls to master.guess and one of them was the secret, so we pass the test case. + +**Example 2:** + +**Input:** secret = "hamada", wordlist = ["hamada","khaled"], numguesses = 10 + +**Output:** You guessed the secret word correctly. + +**Constraints:** + +* `1 <= wordlist.length <= 100` +* `wordlist[i].length == 6` +* `wordlist[i]` consist of lowercase English letters. +* All the strings of `wordlist` are **unique**. +* `secret` exists in `wordlist`. +* `numguesses == 10` + +## Solution + +```kotlin +import java.util.Collections + +/* + * // This is the Master's API interface. + * // You should not implement it, or speculate about its implementation + * interface Master { + * fun guess(word: String): Int {} + * } + */ +class Solution { + interface Master { + fun guess(word: String): Int + } + + private var next = 0 + + fun findSecretWord(wordlist: Array, master: Master) { + val list = listOf(*wordlist) + Collections.shuffle(list) + val test = BooleanArray(wordlist.size) + while (true) { + val num = master.guess(list[next]) + if (num == 6) { + break + } + updateList(list, test, num) + } + } + + private fun updateList(list: List, test: BooleanArray, num: Int) { + val index = next + for (i in index + 1 until test.size) { + if (test[i]) { + continue + } + val samePart = getSame(list[index], list[i]) + if (samePart != num) { + test[i] = true + } else if (next == index) { + next = i + } + } + } + + private fun getSame(word1: String?, word2: String?): Int { + var ret = 0 + for (i in 0..5) { + if (word1!![i] == word2!![i]) { + ret++ + } + } + return ret + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0844_backspace_string_compare/readme.md b/src/main/kotlin/g0801_0900/s0844_backspace_string_compare/readme.md new file mode 100644 index 00000000..47445751 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0844_backspace_string_compare/readme.md @@ -0,0 +1,69 @@ +[![](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) + +## 844\. Backspace String Compare + +Easy + +Given two strings `s` and `t`, return `true` _if they are equal when both are typed into empty text editors_. `'#'` means a backspace character. + +Note that after backspacing an empty text, the text will continue empty. + +**Example 1:** + +**Input:** s = "ab#c", t = "ad#c" + +**Output:** true + +**Explanation:** Both s and t become "ac". + +**Example 2:** + +**Input:** s = "ab##", t = "c#d#" + +**Output:** true + +**Explanation:** Both s and t become "". + +**Example 3:** + +**Input:** s = "a#c", t = "b" + +**Output:** false + +**Explanation:** s becomes "c" while t becomes "b". + +**Constraints:** + +* `1 <= s.length, t.length <= 200` +* `s` and `t` only contain lowercase letters and `'#'` characters. + +**Follow up:** Can you solve it in `O(n)` time and `O(1)` space? + +## Solution + +```kotlin +class Solution { + fun backspaceCompare(s: String, t: String): Boolean { + return cmprStr(s) == cmprStr(t) + } + + private fun cmprStr(str: String): String { + val res = StringBuilder() + var count = 0 + for (i in str.length - 1 downTo 0) { + val currChar = str[i] + if (currChar == '#') { + count++ + } else { + if (count > 0) { + count-- + } else { + res.append(currChar) + } + } + } + return res.toString() + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0845_longest_mountain_in_array/readme.md b/src/main/kotlin/g0801_0900/s0845_longest_mountain_in_array/readme.md new file mode 100644 index 00000000..7ae515d8 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0845_longest_mountain_in_array/readme.md @@ -0,0 +1,71 @@ +[![](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) + +## 845\. Longest Mountain in Array + +Medium + +You may recall that an array `arr` is a **mountain array** if and only if: + +* `arr.length >= 3` +* There exists some index `i` (**0-indexed**) with `0 < i < arr.length - 1` such that: + * `arr[0] < arr[1] < ... < arr[i - 1] < arr[i]` + * `arr[i] > arr[i + 1] > ... > arr[arr.length - 1]` + +Given an integer array `arr`, return _the length of the longest subarray, which is a mountain_. Return `0` if there is no mountain subarray. + +**Example 1:** + +**Input:** arr = [2,1,4,7,3,2,5] + +**Output:** 5 + +**Explanation:** The largest mountain is [1,4,7,3,2] which has length 5. + +**Example 2:** + +**Input:** arr = [2,2,2] + +**Output:** 0 + +**Explanation:** There is no mountain. + +**Constraints:** + +* 1 <= arr.length <= 104 +* 0 <= arr[i] <= 104 + +**Follow up:** + +* Can you solve it using only one pass? +* Can you solve it in `O(1)` space? + +## Solution + +```kotlin +class Solution { + fun longestMountain(arr: IntArray): Int { + var s = 0 + var i = 1 + while (i < arr.size - 1) { + if (arr[i] > arr[i - 1] && arr[i] > arr[i + 1]) { + var j = i + var tem = 1 + while (j > 0 && arr[j] > arr[j - 1]) { + j-- + tem++ + } + j = i + while (j < arr.size - 1 && arr[j] > arr[j + 1]) { + j++ + tem++ + } + s = s.coerceAtLeast(tem) + i = j + } + i++ + } + return s + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0846_hand_of_straights/readme.md b/src/main/kotlin/g0801_0900/s0846_hand_of_straights/readme.md new file mode 100644 index 00000000..13906499 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0846_hand_of_straights/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) + +## 846\. Hand of Straights + +Medium + +Alice has some number of cards and she wants to rearrange the cards into groups so that each group is of size `groupSize`, and consists of `groupSize` consecutive cards. + +Given an integer array `hand` where `hand[i]` is the value written on the ith card and an integer `groupSize`, return `true` if she can rearrange the cards, or `false` otherwise. + +**Example 1:** + +**Input:** hand = [1,2,3,6,2,3,4,7,8], groupSize = 3 + +**Output:** true + +**Explanation:** Alice's hand can be rearranged as [1,2,3],[2,3,4],[6,7,8] + +**Example 2:** + +**Input:** hand = [1,2,3,4,5], groupSize = 4 + +**Output:** false + +**Explanation:** Alice's hand can not be rearranged into groups of 4. + +**Constraints:** + +* 1 <= hand.length <= 104 +* 0 <= hand[i] <= 109 +* `1 <= groupSize <= hand.length` + +**Note:** This question is the same as 1296: [https://leetcode.com/problems/divide-array-in-sets-of-k-consecutive-numbers/](https://leetcode.com/problems/divide-array-in-sets-of-k-consecutive-numbers/) + +## Solution + +```kotlin +class Solution { + fun isNStraightHand(hand: IntArray, groupSize: Int): Boolean { + val len = hand.size + if (len % groupSize != 0) { + return false + } + hand.sort() + val map: MutableMap = HashMap() + for (num in hand) { + var cnt = map.getOrDefault(num, 0) + map[num] = ++cnt + } + for (num in hand) { + var cnt = map[num]!! + if (cnt <= 0) { + continue + } + map[num] = --cnt + var loop = 1 + while (loop < groupSize) { + var curCnt = map.getOrDefault(num + loop, 0) + if (curCnt <= 0) { + return false + } + map[num + loop] = --curCnt + ++loop + } + } + return true + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0847_shortest_path_visiting_all_nodes/readme.md b/src/main/kotlin/g0801_0900/s0847_shortest_path_visiting_all_nodes/readme.md new file mode 100644 index 00000000..6468a747 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0847_shortest_path_visiting_all_nodes/readme.md @@ -0,0 +1,84 @@ +[![](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) + +## 847\. Shortest Path Visiting All Nodes + +Hard + +You have an undirected, connected graph of `n` nodes labeled from `0` to `n - 1`. You are given an array `graph` where `graph[i]` is a list of all the nodes connected with node `i` by an edge. + +Return _the length of the shortest path that visits every node_. You may start and stop at any node, you may revisit nodes multiple times, and you may reuse edges. + +**Example 1:** + +![](https://assets.leetcode.com/uploads/2021/05/12/shortest1-graph.jpg) + +**Input:** graph = \[\[1,2,3],[0],[0],[0]] + +**Output:** 4 + +**Explanation:** One possible path is [1,0,2,0,3] + +**Example 2:** + +![](https://assets.leetcode.com/uploads/2021/05/12/shortest2-graph.jpg) + +**Input:** graph = \[\[1],[0,2,4],[1,3,4],[2],[1,2]] + +**Output:** 4 + +**Explanation:** One possible path is [0,1,4,2,3] + +**Constraints:** + +* `n == graph.length` +* `1 <= n <= 12` +* `0 <= graph[i].length < n` +* `graph[i]` does not contain `i`. +* If `graph[a]` contains `b`, then `graph[b]` contains `a`. +* The input graph is always connected. + +## Solution + +```kotlin +import java.util.LinkedList +import java.util.Objects +import java.util.Queue + +class Solution { + fun shortestPathLength(graph: Array): Int { + val target = (1 shl graph.size) - 1 + val q: Queue = LinkedList() + for (i in graph.indices) { + q.offer(intArrayOf(i, 1 shl i)) + } + var steps = 0 + val visited = Array(graph.size) { + BooleanArray( + target + 1 + ) + } + while (!q.isEmpty()) { + val size = q.size + for (i in 0 until size) { + val curr = q.poll() + val currNode = Objects.requireNonNull(curr)[0] + val currState = curr[1] + if (currState == target) { + return steps + } + for (n in graph[currNode]) { + val newState = currState or (1 shl n) + if (visited[n][newState]) { + continue + } + visited[n][newState] = true + q.offer(intArrayOf(n, newState)) + } + } + ++steps + } + return -1 + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0848_shifting_letters/readme.md b/src/main/kotlin/g0801_0900/s0848_shifting_letters/readme.md new file mode 100644 index 00000000..619fa72e --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0848_shifting_letters/readme.md @@ -0,0 +1,66 @@ +[![](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) + +## 848\. Shifting Letters + +Medium + +You are given a string `s` of lowercase English letters and an integer array `shifts` of the same length. + +Call the `shift()` of a letter, the next letter in the alphabet, (wrapping around so that `'z'` becomes `'a'`). + +* For example, `shift('a') = 'b'`, `shift('t') = 'u'`, and `shift('z') = 'a'`. + +Now for each `shifts[i] = x`, we want to shift the first `i + 1` letters of `s`, `x` times. + +Return _the final string after all such shifts to s are applied_. + +**Example 1:** + +**Input:** s = "abc", shifts = [3,5,9] + +**Output:** "rpl" + +**Explanation:** We start with "abc". + +After shifting the first 1 letters of s by 3, we have "dbc". + +After shifting the first 2 letters of s by 5, we have "igc". + +After shifting the first 3 letters of s by 9, we have "rpl", the answer. + +**Example 2:** + +**Input:** s = "aaa", shifts = [1,2,3] + +**Output:** "gfd" + +**Constraints:** + +* 1 <= s.length <= 105 +* `s` consists of lowercase English letters. +* `shifts.length == s.length` +* 0 <= shifts[i] <= 109 + +## Solution + +```kotlin +class Solution { + fun shiftingLetters(s: String, shifts: IntArray): String { + val n = shifts.size + var runningSum = 0 + for (i in n - 1 downTo 0) { + shifts[i] = (shifts[i] + runningSum) % 26 + runningSum = shifts[i] + } + val str = StringBuilder() + var i = 0 + for (c in s.toCharArray()) { + val correctShift = (c.code - 'a'.code + shifts[i]) % 26 + str.append(('a'.code + correctShift).toChar()) + i++ + } + return str.toString() + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0849_maximize_distance_to_closest_person/readme.md b/src/main/kotlin/g0801_0900/s0849_maximize_distance_to_closest_person/readme.md new file mode 100644 index 00000000..53c6c39c --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0849_maximize_distance_to_closest_person/readme.md @@ -0,0 +1,101 @@ +[![](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) + +## 849\. Maximize Distance to Closest Person + +Medium + +You are given an array representing a row of `seats` where `seats[i] = 1` represents a person sitting in the ith seat, and `seats[i] = 0` represents that the ith seat is empty **(0-indexed)**. + +There is at least one empty seat, and at least one person sitting. + +Alex wants to sit in the seat such that the distance between him and the closest person to him is maximized. + +Return _that maximum distance to the closest person_. + +**Example 1:** + +![](https://assets.leetcode.com/uploads/2020/09/10/distance.jpg) + +**Input:** seats = [1,0,0,0,1,0,1] + +**Output:** 2 + +**Explanation:** + +If Alex sits in the second open seat (i.e. seats[2]), then the closest person has distance 2. + +If Alex sits in any other open seat, the closest person has distance 1. + +Thus, the maximum distance to the closest person is 2. + +**Example 2:** + +**Input:** seats = [1,0,0,0] + +**Output:** 3 + +**Explanation:** + +If Alex sits in the last seat (i.e. seats[3]), the closest person is 3 seats away. + +This is the maximum distance possible, so the answer is 3. + +**Example 3:** + +**Input:** seats = [0,1] + +**Output:** 1 + +**Constraints:** + +* 2 <= seats.length <= 2 * 104 +* `seats[i]` is `0` or `1`. +* At least one seat is **empty**. +* At least one seat is **occupied**. + +## Solution + +```kotlin +class Solution { + private var maxDist = 0 + + fun maxDistToClosest(seats: IntArray): Int { + for (i in seats.indices) { + if (seats[i] == 0) { + extend(seats, i) + } + } + return maxDist + } + + private fun extend(seats: IntArray, position: Int) { + var left = position - 1 + var right = position + 1 + var leftMinDistance = 1 + while (left >= 0) { + if (seats[left] == 0) { + leftMinDistance++ + left-- + } else { + break + } + } + var rightMinDistance = 1 + while (right < seats.size) { + if (seats[right] == 0) { + rightMinDistance++ + right++ + } else { + break + } + } + val maxReach: Int = when (position) { + 0 -> rightMinDistance + seats.size - 1 -> leftMinDistance + else -> leftMinDistance.coerceAtMost(rightMinDistance) + } + maxDist = maxDist.coerceAtLeast(maxReach) + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0850_rectangle_area_ii/readme.md b/src/main/kotlin/g0801_0900/s0850_rectangle_area_ii/readme.md new file mode 100644 index 00000000..bff9532a --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0850_rectangle_area_ii/readme.md @@ -0,0 +1,103 @@ +[![](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) + +## 850\. Rectangle Area II + +Hard + +You are given a 2D array of axis-aligned `rectangles`. Each rectangle[i] = [xi1, yi1, xi2, yi2] denotes the ith rectangle where (xi1, yi1) are the coordinates of the **bottom-left corner**, and (xi2, yi2) are the coordinates of the **top-right corner**. + +Calculate the **total area** covered by all `rectangles` in the plane. Any area covered by two or more rectangles should only be counted **once**. + +Return _the **total area**_. Since the answer may be too large, return it **modulo** 109 + 7. + +**Example 1:** + +![](https://s3-lc-upload.s3.amazonaws.com/uploads/2018/06/06/rectangle_area_ii_pic.png) + +**Input:** rectangles = \[\[0,0,2,2],[1,0,2,3],[1,0,3,1]] + +**Output:** 6 + +**Explanation:** A total area of 6 is covered by all three rectangles, as illustrated in the picture. + +From (1,1) to (2,2), the green and red rectangles overlap. + +From (1,0) to (2,3), all three rectangles overlap. + +**Example 2:** + +**Input:** rectangles = \[\[0,0,1000000000,1000000000]] + +**Output:** 49 + +**Explanation:** The answer is 1018 modulo (109 + 7), which is 49. + +**Constraints:** + +* `1 <= rectangles.length <= 200` +* `rectanges[i].length == 4` +* 0 <= xi1, yi1, xi2, yi2 <= 109 +* xi1 <= xi2 +* yi1 <= yi2 + +## Solution + +```kotlin +class Solution { + fun rectangleArea(rectangles: Array): Int { + val memo: MutableList = ArrayList() + for (rectangle in rectangles) { + helper(0, rectangle, memo) + } + var res: Long = 0 + val mod = (1e9 + 7).toInt() + for (m in memo) { + res = (res + (m[2] - m[0]).toLong() * (m[3] - m[1]).toLong()) % mod + } + return res.toInt() + } + + private fun helper(id: Int, rectangle: IntArray, memo: MutableList) { + if (id >= memo.size) { + memo.add(rectangle) + return + } + val cur = memo[id] + if (rectangle[2] <= cur[0] || rectangle[0] >= cur[2] || rectangle[1] >= cur[3] || rectangle[3] <= cur[1]) { + helper(id + 1, rectangle, memo) + return + } + if (rectangle[0] < cur[0]) { + helper(id + 1, intArrayOf(rectangle[0], rectangle[1], cur[0], rectangle[3]), memo) + } + if (rectangle[2] > cur[2]) { + helper(id + 1, intArrayOf(cur[2], rectangle[1], rectangle[2], rectangle[3]), memo) + } + if (rectangle[1] < cur[1]) { + helper( + id + 1, + intArrayOf( + rectangle[0].coerceAtLeast(cur[0]), + rectangle[1], + rectangle[2].coerceAtMost(cur[2]), + cur[1] + ), + memo + ) + } + if (rectangle[3] > cur[3]) { + helper( + id + 1, + intArrayOf( + rectangle[0].coerceAtLeast(cur[0]), + cur[3], + rectangle[2].coerceAtMost(cur[2]), + rectangle[3] + ), + memo + ) + } + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0851_loud_and_rich/readme.md b/src/main/kotlin/g0801_0900/s0851_loud_and_rich/readme.md new file mode 100644 index 00000000..b3f9492a --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0851_loud_and_rich/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) + +## 851\. Loud and Rich + +Medium + +There is a group of `n` people labeled from `0` to `n - 1` where each person has a different amount of money and a different level of quietness. + +You are given an array `richer` where richer[i] = [ai, bi] indicates that ai has more money than bi and an integer array `quiet` where `quiet[i]` is the quietness of the ith person. All the given data in richer are **logically correct** (i.e., the data will not lead you to a situation where `x` is richer than `y` and `y` is richer than `x` at the same time). + +Return _an integer array_ `answer` _where_ `answer[x] = y` _if_ `y` _is the least quiet person (that is, the person_ `y` _with the smallest value of_ `quiet[y]`_) among all people who definitely have equal to or more money than the person_ `x`. + +**Example 1:** + +**Input:** richer = \[\[1,0],[2,1],[3,1],[3,7],[4,3],[5,3],[6,3]], quiet = [3,2,5,4,6,1,7,0] + +**Output:** [5,5,2,5,4,5,6,7] + +**Explanation:** + +answer[0] = 5. + +Person 5 has more money than 3, which has more money than 1, which has more money than 0. + +The only person who is quieter (has lower quiet[x]) is person 7, but it is not clear if they have more money than person 0. + +answer[7] = 7. + +Among all people that definitely have equal to or more money than person 7 (which could be persons 3, 4, 5, 6, or 7), the person who is the quietest (has lower quiet[x]) is person 7. + +The other answers can be filled out with similar reasoning. + +**Example 2:** + +**Input:** richer = [], quiet = [0] + +**Output:** [0] + +**Constraints:** + +* `n == quiet.length` +* `1 <= n <= 500` +* `0 <= quiet[i] < n` +* All the values of `quiet` are **unique**. +* `0 <= richer.length <= n * (n - 1) / 2` +* 0 <= ai, bi < n +* ai != bi +* All the pairs of `richer` are **unique**. +* The observations in `richer` are all logically consistent. + +## Solution + +```kotlin +class Solution { + fun loudAndRich(richer: Array, quiet: IntArray): IntArray { + val result = IntArray(quiet.size) + for (i in quiet.indices) { + result[i] = i + } + for (k in quiet.indices) { + var changed = false + for (r in richer) { + if (quiet[result[r[0]]] < quiet[result[r[1]]]) { + result[r[1]] = result[r[0]] + changed = true + } + } + if (!changed) { + break + } + } + return result + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0852_peak_index_in_a_mountain_array/readme.md b/src/main/kotlin/g0801_0900/s0852_peak_index_in_a_mountain_array/readme.md new file mode 100644 index 00000000..ef7bec6d --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0852_peak_index_in_a_mountain_array/readme.md @@ -0,0 +1,56 @@ +[![](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) + +## 852\. Peak Index in a Mountain Array + +Medium + +An array `arr` a **mountain** if the following properties hold: + +* `arr.length >= 3` +* There exists some `i` with `0 < i < arr.length - 1` such that: + * `arr[0] < arr[1] < ... < arr[i - 1] < arr[i]` + * `arr[i] > arr[i + 1] > ... > arr[arr.length - 1]` + +Given a mountain array `arr`, return the index `i` such that `arr[0] < arr[1] < ... < arr[i - 1] < arr[i] > arr[i + 1] > ... > arr[arr.length - 1]`. + +You must solve it in `O(log(arr.length))` time complexity. + +**Example 1:** + +**Input:** arr = [0,1,0] + +**Output:** 1 + +**Example 2:** + +**Input:** arr = [0,2,1,0] + +**Output:** 1 + +**Example 3:** + +**Input:** arr = [0,10,5,2] + +**Output:** 1 + +**Constraints:** + +* 3 <= arr.length <= 105 +* 0 <= arr[i] <= 106 +* `arr` is **guaranteed** to be a mountain array. + +## Solution + +```kotlin +class Solution { + fun peakIndexInMountainArray(arr: IntArray): Int { + for (i in 1 until arr.size - 1) { + if (arr[i] > arr[i + 1]) { + return i + } + } + return -1 + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0853_car_fleet/readme.md b/src/main/kotlin/g0801_0900/s0853_car_fleet/readme.md new file mode 100644 index 00000000..7cc5812b --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0853_car_fleet/readme.md @@ -0,0 +1,94 @@ +[![](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) + +## 853\. Car Fleet + +Medium + +There are `n` cars going to the same destination along a one-lane road. The destination is `target` miles away. + +You are given two integer array `position` and `speed`, both of length `n`, where `position[i]` is the position of the ith car and `speed[i]` is the speed of the ith car (in miles per hour). + +A car can never pass another car ahead of it, but it can catch up to it and drive bumper to bumper **at the same speed**. The faster car will **slow down** to match the slower car's speed. The distance between these two cars is ignored (i.e., they are assumed to have the same position). + +A **car fleet** is some non-empty set of cars driving at the same position and same speed. Note that a single car is also a car fleet. + +If a car catches up to a car fleet right at the destination point, it will still be considered as one car fleet. + +Return _the **number of car fleets** that will arrive at the destination_. + +**Example 1:** + +**Input:** target = 12, position = [10,8,0,5,3], speed = [2,4,1,1,3] + +**Output:** 3 + +**Explanation:** + +The cars starting at 10 (speed 2) and 8 (speed 4) become a fleet, meeting each other at 12. + +The car starting at 0 does not catch up to any other car, so it is a fleet by itself. + +The cars starting at 5 (speed 1) and 3 (speed 3) become a fleet, meeting each other at 6. The fleet moves at speed 1 until it reaches target. + +Note that no other cars meet these fleets before the destination, so the answer is 3. + +**Example 2:** + +**Input:** target = 10, position = [3], speed = [3] + +**Output:** 1 + +**Explanation:** There is only one car, hence there is only one fleet. + +**Example 3:** + +**Input:** target = 100, position = [0,2,4], speed = [4,2,1] + +**Output:** 1 + +**Explanation:** The cars starting at 0 (speed 4) and 2 (speed 2) become a fleet, meeting each other at 4. The fleet moves at speed 2. Then, the fleet (speed 2) and the car starting at 4 (speed 1) become one fleet, meeting each other at 6. The fleet moves at speed 1 until it reaches target. + +**Constraints:** + +* `n == position.length == speed.length` +* 1 <= n <= 105 +* 0 < target <= 106 +* `0 <= position[i] < target` +* All the values of `position` are **unique**. +* 0 < speed[i] <= 106 + +## Solution + +```kotlin +class Solution { + private class Car { + var position = 0 + var speed = 0 + } + + fun carFleet(target: Int, position: IntArray, speed: IntArray): Int { + val cars: MutableList = ArrayList() + for (i in position.indices) { + val c = Car() + c.position = position[i] + c.speed = speed[i] + cars.add(c) + } + cars.sortBy { it.position } + var numFleets = 1 + var lastTime = ( + (target - cars[cars.size - 1].position).toFloat() / + cars[cars.size - 1].speed + ) + for (i in cars.size - 2 downTo 0) { + val timeToTarget = (target - cars[i].position).toFloat() / cars[i].speed + if (timeToTarget > lastTime) { + numFleets++ + lastTime = timeToTarget + } + } + return numFleets + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0854_k_similar_strings/readme.md b/src/main/kotlin/g0801_0900/s0854_k_similar_strings/readme.md new file mode 100644 index 00000000..71bc3897 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0854_k_similar_strings/readme.md @@ -0,0 +1,88 @@ +[![](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) + +## 854\. K-Similar Strings + +Hard + +Strings `s1` and `s2` are `k`**\-similar** (for some non-negative integer `k`) if we can swap the positions of two letters in `s1` exactly `k` times so that the resulting string equals `s2`. + +Given two anagrams `s1` and `s2`, return the smallest `k` for which `s1` and `s2` are `k`**\-similar**. + +**Example 1:** + +**Input:** s1 = "ab", s2 = "ba" + +**Output:** 1 + +**Explanation:** The two string are 1-similar because we can use one swap to change s1 to s2: "ab" --> "ba". + +**Example 2:** + +**Input:** s1 = "abc", s2 = "bca" + +**Output:** 2 + +**Explanation:** The two strings are 2-similar because we can use two swaps to change s1 to s2: "abc" --> "bac" --> "bca". + +**Constraints:** + +* `1 <= s1.length <= 20` +* `s2.length == s1.length` +* `s1` and `s2` contain only lowercase letters from the set `{'a', 'b', 'c', 'd', 'e', 'f'}`. +* `s2` is an anagram of `s1`. + +## Solution + +```kotlin +class Solution { + fun kSimilarity(a: String, b: String): Int { + var ans = 0 + val achars = a.toCharArray() + val bchars = b.toCharArray() + ans += getAllPerfectMatches(achars, bchars) + for (i in achars.indices) { + if (achars[i] == bchars[i]) { + continue + } + return ans + checkAllOptions(achars, bchars, i, b) + } + return ans + } + + private fun checkAllOptions(achars: CharArray, bchars: CharArray, i: Int, b: String): Int { + var ans = Int.MAX_VALUE + for (j in i + 1 until achars.size) { + if (achars[j] == bchars[i] && achars[j] != bchars[j]) { + swap(achars, i, j) + ans = Math.min(ans, 1 + kSimilarity(String(achars), b)) + swap(achars, i, j) + } + } + return ans + } + + private fun getAllPerfectMatches(achars: CharArray, bchars: CharArray): Int { + var ans = 0 + for (i in achars.indices) { + if (achars[i] == bchars[i]) { + continue + } + for (j in i + 1 until achars.size) { + if (achars[j] == bchars[i] && bchars[j] == achars[i]) { + swap(achars, i, j) + ans++ + break + } + } + } + return ans + } + + private fun swap(a: CharArray, i: Int, j: Int) { + val temp = a[i] + a[i] = a[j] + a[j] = temp + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0855_exam_room/readme.md b/src/main/kotlin/g0801_0900/s0855_exam_room/readme.md new file mode 100644 index 00000000..db739a73 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0855_exam_room/readme.md @@ -0,0 +1,125 @@ +[![](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) + +## 855\. Exam Room + +Medium + +There is an exam room with `n` seats in a single row labeled from `0` to `n - 1`. + +When a student enters the room, they must sit in the seat that maximizes the distance to the closest person. If there are multiple such seats, they sit in the seat with the lowest number. If no one is in the room, then the student sits at seat number `0`. + +Design a class that simulates the mentioned exam room. + +Implement the `ExamRoom` class: + +* `ExamRoom(int n)` Initializes the object of the exam room with the number of the seats `n`. +* `int seat()` Returns the label of the seat at which the next student will set. +* `void leave(int p)` Indicates that the student sitting at seat `p` will leave the room. It is guaranteed that there will be a student sitting at seat `p`. + +**Example 1:** + +**Input** ["ExamRoom", "seat", "seat", "seat", "seat", "leave", "seat"] [[10], [], [], [], [], [4], []] + +**Output:** [null, 0, 9, 4, 2, null, 5] + +**Explanation:** + + ExamRoom examRoom = new ExamRoom(10); + examRoom.seat(); // return 0, no one is in the room, then the student sits at seat number 0. + examRoom.seat(); // return 9, the student sits at the last seat number 9. + examRoom.seat(); // return 4, the student sits at the last seat number 4. + examRoom.seat(); // return 2, the student sits at the last seat number 2. + examRoom.leave(4); + examRoom.seat(); // return 5, the student sits at the last seat number 5. + +**Constraints:** + +* 1 <= n <= 109 +* It is guaranteed that there is a student sitting at seat `p`. +* At most 104 calls will be made to `seat` and `leave`. + +## Solution + +```kotlin +import java.util.Objects + +class ExamRoom() { + private class Node(var `val`: Int, map: MutableMap) { + var pre: Node? = null + var next: Node? = null + + init { + map[`val`] = this + } + + fun insert(left: Node?): Int { + val right = left!!.next + left.next = this + right!!.pre = this + next = right + pre = left + return `val` + } + + fun delete() { + val left = pre + val right = next + left!!.next = right + right!!.pre = left + } + } + + private val map: MutableMap = HashMap() + private val head = Node(-1, map) + private val tail = Node(-1, map) + private var n = 0 + + init { + head.next = tail + tail.pre = head + } + + constructor(n: Int) : this() { + this.n = n + } + + fun seat(): Int { + val right = n - 1 - tail.pre!!.`val` + val left = head.next!!.`val` + var max = 0 + var maxAt = -1 + var maxAtLeft: Node? = null + var cur = tail.pre + while (cur !== head && cur!!.pre !== head) { + val pre = cur!!.pre + val at = (cur.`val` + pre!!.`val`) / 2 + val distance = at - pre.`val` + if (distance >= max) { + maxAtLeft = pre + max = distance + maxAt = at + } + cur = cur.pre + } + if (head.next === tail || left >= max && left >= right) { + return Node(0, map).insert(head) + } + return if (right > max) { + Node(n - 1, map).insert(tail.pre) + } else Node(maxAt, map).insert(Objects.requireNonNull(maxAtLeft)) + } + + fun leave(p: Int) { + map[p]!!.delete() + map.remove(p) + } +} + +/* + * Your ExamRoom object will be instantiated and called as such: + * var obj = ExamRoom(n) + * var param_1 = obj.seat() + * obj.leave(p) + */ +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0856_score_of_parentheses/readme.md b/src/main/kotlin/g0801_0900/s0856_score_of_parentheses/readme.md new file mode 100644 index 00000000..a7ca3fa4 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0856_score_of_parentheses/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) + +## 856\. Score of Parentheses + +Medium + +Given a balanced parentheses string `s`, return _the **score** of the string_. + +The **score** of a balanced parentheses string is based on the following rule: + +* `"()"` has score `1`. +* `AB` has score `A + B`, where `A` and `B` are balanced parentheses strings. +* `(A)` has score `2 * A`, where `A` is a balanced parentheses string. + +**Example 1:** + +**Input:** s = "()" + +**Output:** 1 + +**Example 2:** + +**Input:** s = "(())" + +**Output:** 2 + +**Example 3:** + +**Input:** s = "()()" + +**Output:** 2 + +**Constraints:** + +* `2 <= s.length <= 50` +* `s` consists of only `'('` and `')'`. +* `s` is a balanced parentheses string. + +## Solution + +```kotlin +import java.util.Deque +import java.util.LinkedList + +class Solution { + fun scoreOfParentheses(s: String): Int { + val stack: Deque = LinkedList() + for (element in s) { + if (element == '(') { + stack.push(-1) + } else { + var curr = 0 + while (stack.peek() != -1) { + curr += stack.pop() + } + stack.pop() + stack.push(if (curr == 0) 1 else curr * 2) + } + } + var score = 0 + while (!stack.isEmpty()) { + score += stack.pop() + } + return score + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0857_minimum_cost_to_hire_k_workers/readme.md b/src/main/kotlin/g0801_0900/s0857_minimum_cost_to_hire_k_workers/readme.md new file mode 100644 index 00000000..615a4c6a --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0857_minimum_cost_to_hire_k_workers/readme.md @@ -0,0 +1,80 @@ +[![](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) + +## 857\. Minimum Cost to Hire K Workers + +Hard + +There are `n` workers. You are given two integer arrays `quality` and `wage` where `quality[i]` is the quality of the ith worker and `wage[i]` is the minimum wage expectation for the ith worker. + +We want to hire exactly `k` workers to form a paid group. To hire a group of `k` workers, we must pay them according to the following rules: + +1. Every worker in the paid group should be paid in the ratio of their quality compared to other workers in the paid group. +2. Every worker in the paid group must be paid at least their minimum wage expectation. + +Given the integer `k`, return _the least amount of money needed to form a paid group satisfying the above conditions_. Answers within 10-5 of the actual answer will be accepted. + +**Example 1:** + +**Input:** quality = [10,20,5], wage = [70,50,30], k = 2 + +**Output:** 105.00000 + +**Explanation:** We pay 70 to 0th worker and 35 to 2nd worker. + +**Example 2:** + +**Input:** quality = [3,1,10,10,1], wage = [4,8,2,2,7], k = 3 + +**Output:** 30.66667 + +**Explanation:** We pay 4 to 0th worker, 13.33333 to 2nd and 3rd workers separately. + +**Constraints:** + +* `n == quality.length == wage.length` +* 1 <= k <= n <= 104 +* 1 <= quality[i], wage[i] <= 104 + +## Solution + +```kotlin +import java.util.PriorityQueue + +class Solution { + fun mincostToHireWorkers(quality: IntArray, wage: IntArray, k: Int): Double { + val n = quality.size + val workers = arrayOfNulls(n) + for (i in 0 until n) { + workers[i] = Worker(wage[i], quality[i]) + } + workers.sortBy { it!!.ratio() } + val maxHeap = PriorityQueue { a: Int?, b: Int? -> + Integer.compare( + b!!, a!! + ) + } + var sumQuality = 0 + var result = Double.MAX_VALUE + for (i in 0 until n) { + val worker = workers[i] + sumQuality += worker!!.quality + maxHeap.add(worker.quality) + if (maxHeap.size > k) { + sumQuality -= maxHeap.remove()!! + } + val groupRatio = worker.ratio() + if (maxHeap.size == k) { + result = Math.min(sumQuality * groupRatio, result) + } + } + return result + } + + internal class Worker(var wage: Int, var quality: Int) { + fun ratio(): Double { + return wage.toDouble() / quality + } + } +} +``` \ No newline at end of file