From df45382a1905600ec6fbca4cb2bb6ffc62c1c6c9 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sat, 25 Mar 2023 07:27:55 +0200 Subject: [PATCH] Added tasks 805-821 --- README.md | 17 +++ .../readme.md | 84 +++++++++++ .../readme.md | 93 +++++++++++++ .../g0801_0900/s0808_soup_servings/readme.md | 81 +++++++++++ .../s0809_expressive_words/readme.md | 96 +++++++++++++ .../s0810_chalkboard_xor_game/readme.md | 67 +++++++++ .../s0811_subdomain_visit_count/readme.md | 84 +++++++++++ .../s0812_largest_triangle_area/readme.md | 64 +++++++++ .../s0813_largest_sum_of_averages/readme.md | 66 +++++++++ .../s0814_binary_tree_pruning/readme.md | 74 ++++++++++ .../g0801_0900/s0815_bus_routes/readme.md | 130 ++++++++++++++++++ .../s0816_ambiguous_coordinates/readme.md | 126 +++++++++++++++++ .../s0817_linked_list_components/readme.md | 79 +++++++++++ .../g0801_0900/s0818_race_car/readme.md | 75 ++++++++++ .../s0819_most_common_word/readme.md | 60 ++++++++ .../s0820_short_encoding_of_words/readme.md | 78 +++++++++++ .../readme.md | 73 ++++++++++ 17 files changed, 1347 insertions(+) create mode 100644 src/main/kotlin/g0801_0900/s0806_number_of_lines_to_write_string/readme.md create mode 100644 src/main/kotlin/g0801_0900/s0807_max_increase_to_keep_city_skyline/readme.md create mode 100644 src/main/kotlin/g0801_0900/s0808_soup_servings/readme.md create mode 100644 src/main/kotlin/g0801_0900/s0809_expressive_words/readme.md create mode 100644 src/main/kotlin/g0801_0900/s0810_chalkboard_xor_game/readme.md create mode 100644 src/main/kotlin/g0801_0900/s0811_subdomain_visit_count/readme.md create mode 100644 src/main/kotlin/g0801_0900/s0812_largest_triangle_area/readme.md create mode 100644 src/main/kotlin/g0801_0900/s0813_largest_sum_of_averages/readme.md create mode 100644 src/main/kotlin/g0801_0900/s0814_binary_tree_pruning/readme.md create mode 100644 src/main/kotlin/g0801_0900/s0815_bus_routes/readme.md create mode 100644 src/main/kotlin/g0801_0900/s0816_ambiguous_coordinates/readme.md create mode 100644 src/main/kotlin/g0801_0900/s0817_linked_list_components/readme.md create mode 100644 src/main/kotlin/g0801_0900/s0818_race_car/readme.md create mode 100644 src/main/kotlin/g0801_0900/s0819_most_common_word/readme.md create mode 100644 src/main/kotlin/g0801_0900/s0820_short_encoding_of_words/readme.md create mode 100644 src/main/kotlin/g0801_0900/s0821_shortest_distance_to_a_character/readme.md diff --git a/README.md b/README.md index 53606439..e805fa5d 100644 --- a/README.md +++ b/README.md @@ -347,6 +347,7 @@ | | | | | | |-|-|-|-|-|- | 0210 |[Course Schedule II](src/main/kotlin/g0201_0300/s0210_course_schedule_ii)| Medium | Top_Interview_Questions, Depth_First_Search, Breadth_First_Search, Graph, Topological_Sort | 266 | 96.32 +| 0815 |[Bus Routes](src/main/kotlin/g0801_0900/s0815_bus_routes)| Hard | Array, Hash_Table, Breadth_First_Search | 429 | 100.00 #### Day 12 Dynamic Programming @@ -1679,6 +1680,22 @@ | 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 +| 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 +| 0818 |[Race Car](src/main/kotlin/g0801_0900/s0818_race_car)| Hard | Dynamic_Programming | 123 | 100.00 +| 0817 |[Linked List Components](src/main/kotlin/g0801_0900/s0817_linked_list_components)| Medium | Hash_Table, Linked_List | 239 | 100.00 +| 0816 |[Ambiguous Coordinates](src/main/kotlin/g0801_0900/s0816_ambiguous_coordinates)| Medium | String, Backtracking | 231 | 100.00 +| 0815 |[Bus Routes](src/main/kotlin/g0801_0900/s0815_bus_routes)| Hard | Array, Hash_Table, Breadth_First_Search, Level_2_Day_11_Graph/BFS/DFS | 429 | 100.00 +| 0814 |[Binary Tree Pruning](src/main/kotlin/g0801_0900/s0814_binary_tree_pruning)| Medium | Depth_First_Search, Tree, Binary_Tree | 127 | 100.00 +| 0813 |[Largest Sum of Averages](src/main/kotlin/g0801_0900/s0813_largest_sum_of_averages)| Medium | Array, Dynamic_Programming | 160 | 100.00 +| 0812 |[Largest Triangle Area](src/main/kotlin/g0801_0900/s0812_largest_triangle_area)| Easy | Array, Math, Geometry | 156 | 71.43 +| 0811 |[Subdomain Visit Count](src/main/kotlin/g0801_0900/s0811_subdomain_visit_count)| Medium | Array, String, Hash_Table, Counting | 220 | 100.00 +| 0810 |[Chalkboard XOR Game](src/main/kotlin/g0801_0900/s0810_chalkboard_xor_game)| Hard | Array, Math, Bit_Manipulation, Game_Theory, Brainteaser | 172 | 100.00 +| 0809 |[Expressive Words](src/main/kotlin/g0801_0900/s0809_expressive_words)| Medium | Array, String, Two_Pointers | 158 | 100.00 +| 0808 |[Soup Servings](src/main/kotlin/g0801_0900/s0808_soup_servings)| Medium | Dynamic_Programming, Math, Probability_and_Statistics | 112 | 100.00 +| 0807 |[Max Increase to Keep City Skyline](src/main/kotlin/g0801_0900/s0807_max_increase_to_keep_city_skyline)| Medium | Array, Greedy, Matrix | 158 | 100.00 +| 0806 |[Number of Lines To Write String](src/main/kotlin/g0801_0900/s0806_number_of_lines_to_write_string)| Easy | Array, String | 134 | 100.00 | 0805 |[Split Array With Same Average](src/main/kotlin/g0801_0900/s0805_split_array_with_same_average)| Hard | Array, Dynamic_Programming, Math, Bit_Manipulation, Bitmask | 142 | 100.00 | 0804 |[Unique Morse Code Words](src/main/kotlin/g0801_0900/s0804_unique_morse_code_words)| Easy | Array, String, Hash_Table | 158 | 80.00 | 0803 |[Bricks Falling When Hit](src/main/kotlin/g0801_0900/s0803_bricks_falling_when_hit)| Hard | Array, Matrix, Union_Find | 742 | 100.00 diff --git a/src/main/kotlin/g0801_0900/s0806_number_of_lines_to_write_string/readme.md b/src/main/kotlin/g0801_0900/s0806_number_of_lines_to_write_string/readme.md new file mode 100644 index 00000000..9f8bd724 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0806_number_of_lines_to_write_string/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) + +## 806\. Number of Lines To Write String + +Easy + +You are given a string `s` of lowercase English letters and an array `widths` denoting **how many pixels wide** each lowercase English letter is. Specifically, `widths[0]` is the width of `'a'`, `widths[1]` is the width of `'b'`, and so on. + +You are trying to write `s` across several lines, where **each line is no longer than** `100` **pixels**. Starting at the beginning of `s`, write as many letters on the first line such that the total width does not exceed `100` pixels. Then, from where you stopped in `s`, continue writing as many letters as you can on the second line. Continue this process until you have written all of `s`. + +Return _an array_ `result` _of length 2 where:_ + +* `result[0]` _is the total number of lines._ +* `result[1]` _is the width of the last line in pixels._ + +**Example 1:** + +**Input:** widths = [10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10], s = "abcdefghijklmnopqrstuvwxyz" + +**Output:** [3,60] + +**Explanation:** You can write s as follows: + +abcdefghij // 100 pixels wide + +klmnopqrst // 100 pixels wide + +uvwxyz // 60 pixels wide + +There are a total of 3 lines, and the last line is 60 pixels wide. + +**Example 2:** + +**Input:** widths = [4,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10], s = "bbbcccdddaaa" + +**Output:** [2,4] + +**Explanation:** You can write s as follows: + +bbbcccdddaa // 98 pixels wide + +a // 4 pixels wide + +There are a total of 2 lines, and the last line is 4 pixels wide. + +**Constraints:** + +* `widths.length == 26` +* `2 <= widths[i] <= 10` +* `1 <= s.length <= 1000` +* `s` contains only lowercase English letters. + +## Solution + +```kotlin +class Solution { + fun numberOfLines(widths: IntArray, s: String): IntArray { + var count = 0 + var line = 0 + var i = 0 + while (i < s.length) { + count += widths[s[i].code - 'a'.code] + if (count == 100) { + line++ + count = 0 + } + if (count > 100) { + line++ + i-- + count = 0 + } + i++ + } + if (count in 1..99) { + line++ + } + if (count == 0) { + count = 100 + } + return intArrayOf(line, count) + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0807_max_increase_to_keep_city_skyline/readme.md b/src/main/kotlin/g0801_0900/s0807_max_increase_to_keep_city_skyline/readme.md new file mode 100644 index 00000000..5c9c14a7 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0807_max_increase_to_keep_city_skyline/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) + +## 807\. Max Increase to Keep City Skyline + +Medium + +There is a city composed of `n x n` blocks, where each block contains a single building shaped like a vertical square prism. You are given a **0-indexed** `n x n` integer matrix `grid` where `grid[r][c]` represents the **height** of the building located in the block at row `r` and column `c`. + +A city's **skyline** is the the outer contour formed by all the building when viewing the side of the city from a distance. The **skyline** from each cardinal direction north, east, south, and west may be different. + +We are allowed to increase the height of **any number of buildings by any amount** (the amount can be different per building). The height of a `0`\-height building can also be increased. However, increasing the height of a building should **not** affect the city's **skyline** from any cardinal direction. + +Return _the **maximum total sum** that the height of the buildings can be increased by **without** changing the city's **skyline** from any cardinal direction_. + +**Example 1:** + +![](https://assets.leetcode.com/uploads/2021/06/21/807-ex1.png) + +**Input:** grid = \[\[3,0,8,4],[2,4,5,7],[9,2,6,3],[0,3,1,0]] + +**Output:** 35 + +**Explanation:** The building heights are shown in the center of the above image. + +The skylines when viewed from each cardinal direction are drawn in red. + +The grid after increasing the height of buildings without affecting skylines is: + + gridNew = [ [8, 4, 8, 7], + [7, 4, 7, 7], + [9, 4, 8, 7], + [3, 3, 3, 3] ] + +**Example 2:** + +**Input:** grid = \[\[0,0,0],[0,0,0],[0,0,0]] + +**Output:** 0 + +**Explanation:** Increasing the height of any building will result in the skyline changing. + +**Constraints:** + +* `n == grid.length` +* `n == grid[r].length` +* `2 <= n <= 50` +* `0 <= grid[r][c] <= 100` + +## Solution + +```kotlin +class Solution { + fun maxIncreaseKeepingSkyline(grid: Array): Int { + val rows = grid.size + val cols = grid[0].size + val tallestR = IntArray(rows) + val tallestC = IntArray(cols) + var max: Int + for (i in 0 until rows) { + max = 0 + for (j in 0 until cols) { + if (grid[i][j] > max) { + max = grid[i][j] + } + } + tallestR[i] = max + } + for (i in 0 until cols) { + max = 0 + for (ints in grid) { + if (ints[i] > max) { + max = ints[i] + } + } + tallestC[i] = max + } + var increase = 0 + for (i in 0 until rows) { + for (j in 0 until cols) { + if (tallestR[i] < tallestC[j]) { + increase += tallestR[i] - grid[i][j] + grid[i][j] += tallestR[i] - grid[i][j] + } else { + increase += tallestC[j] - grid[i][j] + grid[i][j] += tallestC[j] - grid[i][j] + } + } + } + return increase + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0808_soup_servings/readme.md b/src/main/kotlin/g0801_0900/s0808_soup_servings/readme.md new file mode 100644 index 00000000..224a1762 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0808_soup_servings/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) + +## 808\. Soup Servings + +Medium + +There are two types of soup: **type A** and **type B**. Initially, we have `n` ml of each type of soup. There are four kinds of operations: + +1. Serve `100` ml of **soup A** and `0` ml of **soup B**, +2. Serve `75` ml of **soup A** and `25` ml of **soup B**, +3. Serve `50` ml of **soup A** and `50` ml of **soup B**, and +4. Serve `25` ml of **soup A** and `75` ml of **soup B**. + +When we serve some soup, we give it to someone, and we no longer have it. Each turn, we will choose from the four operations with an equal probability `0.25`. If the remaining volume of soup is not enough to complete the operation, we will serve as much as possible. We stop once we no longer have some quantity of both types of soup. + +**Note** that we do not have an operation where all `100` ml's of **soup B** are used first. + +Return _the probability that **soup A** will be empty first, plus half the probability that **A** and **B** become empty at the same time_. Answers within 10-5 of the actual answer will be accepted. + +**Example 1:** + +**Input:** n = 50 + +**Output:** 0.62500 + +**Explanation:** If we choose the first two operations, A will become empty first. + +For the third operation, A and B will become empty at the same time. + +For the fourth operation, B will become empty first. + +So the total probability of A becoming empty first plus half the probability that A and B become empty at the same time, is 0.25 \* (1 + 1 + 0.5 + 0) = 0.625. + +**Example 2:** + +**Input:** n = 100 + +**Output:** 0.71875 + +**Constraints:** + +* 0 <= n <= 109 + +## Solution + +```kotlin +@Suppress("NAME_SHADOWING") +class Solution { + fun soupServings(n: Int): Double { + return solve(n) + } + + private fun solve(n: Int): Double { + var n = n + n = n / 25 + if (n % 25 > 0) 1 else 0 + return if (n >= 500) { + 1.0 + } else find(n, n, Array(n + 1) { arrayOfNulls(n + 1) }) + } + + private fun find(a: Int, b: Int, mem: Array>): Double { + if (a <= 0 && b <= 0) { + return 0.5 + } else if (a <= 0) { + return 1.0 + } else if (b <= 0) { + return 0.0 + } + if (mem[a][b] != null) { + return mem[a][b]!! + } + var prob: Double = find(a - 4, b, mem) + prob += find(a - 3, b - 1, mem) + prob += find(a - 2, b - 2, mem) + prob += find(a - 1, b - 3, mem) + mem[a][b] = 0.25 * prob + return mem[a][b]!! + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0809_expressive_words/readme.md b/src/main/kotlin/g0801_0900/s0809_expressive_words/readme.md new file mode 100644 index 00000000..35826217 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0809_expressive_words/readme.md @@ -0,0 +1,96 @@ +[![](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) + +## 809\. Expressive Words + +Medium + +Sometimes people repeat letters to represent extra feeling. For example: + +* `"hello" -> "heeellooo"` +* `"hi" -> "hiiii"` + +In these strings like `"heeellooo"`, we have groups of adjacent letters that are all the same: `"h"`, `"eee"`, `"ll"`, `"ooo"`. + +You are given a string `s` and an array of query strings `words`. A query word is **stretchy** if it can be made to be equal to `s` by any number of applications of the following extension operation: choose a group consisting of characters `c`, and add some number of characters `c` to the group so that the size of the group is **three or more**. + +* For example, starting with `"hello"`, we could do an extension on the group `"o"` to get `"hellooo"`, but we cannot get `"helloo"` since the group `"oo"` has a size less than three. Also, we could do another extension like `"ll" -> "lllll"` to get `"helllllooo"`. If `s = "helllllooo"`, then the query word `"hello"` would be **stretchy** because of these two extension operations: `query = "hello" -> "hellooo" -> "helllllooo" = s`. + +Return _the number of query strings that are **stretchy**_. + +**Example 1:** + +**Input:** s = "heeellooo", words = ["hello", "hi", "helo"] + +**Output:** 1 + +**Explanation:** + +We can extend "e" and "o" in the word "hello" to get "heeellooo". + +We can't extend "helo" to get "heeellooo" because the group "ll" is not size 3 or more. + +**Example 2:** + +**Input:** s = "zzzzzyyyyy", words = ["zzyy","zy","zyy"] + +**Output:** 3 + +**Constraints:** + +* `1 <= s.length, words.length <= 100` +* `1 <= words[i].length <= 100` +* `s` and `words[i]` consist of lowercase letters. + +## Solution + +```kotlin +@Suppress("NAME_SHADOWING") +class Solution { + fun expressiveWords(s: String, words: Array): Int { + var ans = 0 + for (w in words) { + if (check(s, w)) { + ans++ + } + } + return ans + } + + private fun check(s: String, w: String): Boolean { + var i = 0 + var j = 0 + while (i < s.length && j < w.length) { + val ch1 = s[i] + val ch2 = w[j] + val len1 = getLen(s, i) + val len2 = getLen(w, j) + if (ch1 == ch2) { + if (len1 == len2 || len1 >= 3 && len2 < len1) { + i += len1 + j += len2 + } else { + return false + } + } else { + return false + } + } + return i == s.length && j == w.length + } + + private fun getLen(value: String, i: Int): Int { + var i = i + i += 1 + var count = 1 + for (j in i until value.length) { + if (value[j] == value[i - 1]) { + count++ + } else { + break + } + } + return count + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0810_chalkboard_xor_game/readme.md b/src/main/kotlin/g0801_0900/s0810_chalkboard_xor_game/readme.md new file mode 100644 index 00000000..e855d87e --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0810_chalkboard_xor_game/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) + +## 810\. Chalkboard XOR Game + +Hard + +You are given an array of integers `nums` represents the numbers written on a chalkboard. + +Alice and Bob take turns erasing exactly one number from the chalkboard, with Alice starting first. If erasing a number causes the bitwise XOR of all the elements of the chalkboard to become `0`, then that player loses. The bitwise XOR of one element is that element itself, and the bitwise XOR of no elements is `0`. + +Also, if any player starts their turn with the bitwise XOR of all the elements of the chalkboard equal to `0`, then that player wins. + +Return `true` _if and only if Alice wins the game, assuming both players play optimally_. + +**Example 1:** + +**Input:** nums = [1,1,2] + +**Output:** false + +**Explanation:** + +Alice has two choices: erase 1 or erase 2. + +If she erases 1, the nums array becomes [1, 2]. + +The bitwise XOR of all the elements of the chalkboard is 1 XOR 2 = 3. + +Now Bob can remove any element he wants, because Alice will be the one to erase the last element and she will lose. + +If Alice erases 2 first, now nums become [1, 1]. + +The bitwise XOR of all the elements of the chalkboard is 1 XOR 1 = 0. + +Alice will lose. + +**Example 2:** + +**Input:** nums = [0,1] + +**Output:** true + +**Example 3:** + +**Input:** nums = [1,2,3] + +**Output:** true + +**Constraints:** + +* `1 <= nums.length <= 1000` +* 0 <= nums[i] < 216 + +## Solution + +```kotlin +class Solution { + fun xorGame(nums: IntArray): Boolean { + var xor = 0 + for (i in nums) { + xor = xor xor i + } + return xor == 0 || nums.size and 1 == 0 + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0811_subdomain_visit_count/readme.md b/src/main/kotlin/g0801_0900/s0811_subdomain_visit_count/readme.md new file mode 100644 index 00000000..babc195c --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0811_subdomain_visit_count/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) + +## 811\. Subdomain Visit Count + +Medium + +A website domain `"discuss.leetcode.com"` consists of various subdomains. At the top level, we have `"com"`, at the next level, we have `"leetcode.com"` and at the lowest level, `"discuss.leetcode.com"`. When we visit a domain like `"discuss.leetcode.com"`, we will also visit the parent domains `"leetcode.com"` and `"com"` implicitly. + +A **count-paired domain** is a domain that has one of the two formats `"rep d1.d2.d3"` or `"rep d1.d2"` where `rep` is the number of visits to the domain and `d1.d2.d3` is the domain itself. + +* For example, `"9001 discuss.leetcode.com"` is a **count-paired domain** that indicates that `discuss.leetcode.com` was visited `9001` times. + +Given an array of **count-paired domains** `cpdomains`, return _an array of the **count-paired domains** of each subdomain in the input_. You may return the answer in **any order**. + +**Example 1:** + +**Input:** cpdomains = ["9001 discuss.leetcode.com"] + +**Output:** ["9001 leetcode.com","9001 discuss.leetcode.com","9001 com"] + +**Explanation:** We only have one website domain: "discuss.leetcode.com". As discussed above, the subdomain "leetcode.com" and "com" will also be visited. So they will all be visited 9001 times. + +**Example 2:** + +**Input:** cpdomains = ["900 google.mail.com", "50 yahoo.com", "1 intel.mail.com", "5 wiki.org"] + +**Output:** ["901 mail.com","50 yahoo.com","900 google.mail.com","5 wiki.org","5 org","1 intel.mail.com","951 com"] + +**Explanation:** We will visit "google.mail.com" 900 times, "yahoo.com" 50 times, "intel.mail.com" once and "wiki.org" 5 times. For the subdomains, we will visit "mail.com" 900 + 1 = 901 times, "com" 900 + 50 + 1 = 951 times, and "org" 5 times. + +**Constraints:** + +* `1 <= cpdomain.length <= 100` +* `1 <= cpdomain[i].length <= 100` +* `cpdomain[i]` follows either the "repi d1i.d2i.d3i" format or the "repi d1i.d2i" format. +* repi is an integer in the range [1, 104]. +* d1i, d2i, and d3i consist of lowercase English letters. + +## Solution + +```kotlin +class Solution { + fun subdomainVisits(d: Array): List { + val fmap: MutableMap = HashMap() + for (s in d) { + var rep = 0 + var i: Int = 0 + while (i < s.length) { + val c = s[i] + rep = if (c in '0'..'9') { + rep * 10 + (c.code - '0'.code) + } else { + break + } + i++ + } + val str = s.substring(i + 1) + seperate(rep, str, fmap) + } + val res: MutableList = ArrayList() + for (entry in fmap.entries.iterator()) { + var comp = "" + comp += entry.value + comp += " " + comp += entry.key + res.add(comp) + } + return res + } + + private fun seperate(rep: Int, s: String, fmap: MutableMap) { + var i = s.length - 1 + while (i >= 0) { + while (i >= 0 && s[i] != '.') { + i-- + } + val toHash: String = s.substring(i + 1) + fmap[toHash] = fmap.getOrDefault(toHash, 0) + rep + i-- + } + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0812_largest_triangle_area/readme.md b/src/main/kotlin/g0801_0900/s0812_largest_triangle_area/readme.md new file mode 100644 index 00000000..24bdef9b --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0812_largest_triangle_area/readme.md @@ -0,0 +1,64 @@ +[![](https://img.shields.io/github/stars/javadev/LeetCode-in-Kotlin?label=Stars&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin) +[![](https://img.shields.io/github/forks/javadev/LeetCode-in-Kotlin?label=Fork%20me%20on%20GitHub%20&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin/fork) + +## 812\. Largest Triangle Area + +Easy + +Given an array of points on the **X-Y** plane `points` where points[i] = [xi, yi], return _the area of the largest triangle that can be formed by any three different points_. Answers within 10-5 of the actual answer will be accepted. + +**Example 1:** + +![](https://s3-lc-upload.s3.amazonaws.com/uploads/2018/04/04/1027.png) + +**Input:** points = \[\[0,0],[0,1],[1,0],[0,2],[2,0]] + +**Output:** 2.00000 + +**Explanation:** The five points are shown in the above figure. The red triangle is the largest. + +**Example 2:** + +**Input:** points = \[\[1,0],[0,0],[0,1]] + +**Output:** 0.50000 + +**Constraints:** + +* `3 <= points.length <= 50` +* -50 <= xi, yi <= 50 +* All the given points are **unique**. + +## Solution + +```kotlin +import kotlin.math.abs + +class Solution { + fun largestTriangleArea(points: Array): Double { + val n = points.size + var max = 0.0 + for (i in 0 until n) { + for (j in i + 1 until n) { + for (k in j + 1 until n) { + var area: Double + val a = points[i] + val b = points[j] + val c = points[k] + area = abs(area(a, b) + area(b, c) + area(c, a)) + if (area > max) { + max = area + } + } + } + } + return max + } + + private fun area(a: IntArray, b: IntArray): Double { + val l = b[0] - a[0] + val h = (a[1] + b[1] + 200) / 2.0 + return l * h + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0813_largest_sum_of_averages/readme.md b/src/main/kotlin/g0801_0900/s0813_largest_sum_of_averages/readme.md new file mode 100644 index 00000000..1e3c2fbb --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0813_largest_sum_of_averages/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) + +## 813\. Largest Sum of Averages + +Medium + +You are given an integer array `nums` and an integer `k`. You can partition the array into **at most** `k` non-empty adjacent subarrays. The **score** of a partition is the sum of the averages of each subarray. + +Note that the partition must use every integer in `nums`, and that the score is not necessarily an integer. + +Return _the maximum **score** you can achieve of all the possible partitions_. Answers within 10-6 of the actual answer will be accepted. + +**Example 1:** + +**Input:** nums = [9,1,2,3,9], k = 3 + +**Output:** 20.00000 + +**Explanation:** + +The best choice is to partition nums into [9], [1, 2, 3], [9]. The answer is 9 + (1 + 2 + 3) / 3 + 9 = 20. + +We could have also partitioned nums into [9, 1], [2], [3, 9], for example. + +That partition would lead to a score of 5 + 2 + 6 = 13, which is worse. + +**Example 2:** + +**Input:** nums = [1,2,3,4,5,6,7], k = 4 + +**Output:** 20.50000 + +**Constraints:** + +* `1 <= nums.length <= 100` +* 1 <= nums[i] <= 104 +* `1 <= k <= nums.length` + +## Solution + +```kotlin +class Solution { + fun largestSumOfAverages(nums: IntArray, k: Int): Double { + return helper(nums, k, 0, Array(k + 1) { arrayOfNulls(nums.size) }) + } + + private fun helper(nums: IntArray, k: Int, idx: Int, memo: Array>): Double { + if (memo[k][idx] != null) { + return memo[k][idx]!! + } + var maxAvg = 0.0 + var sum = 0.0 + for (i in idx..nums.size - k) { + sum += nums[i].toDouble() + if (k - 1 > 0) { + maxAvg = maxAvg.coerceAtLeast(sum / (i - idx + 1) + helper(nums, k - 1, i + 1, memo)) + } else if (i == nums.size - 1) { + maxAvg = maxAvg.coerceAtLeast(sum / (i - idx + 1)) + } + } + memo[k][idx] = maxAvg + return maxAvg + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0814_binary_tree_pruning/readme.md b/src/main/kotlin/g0801_0900/s0814_binary_tree_pruning/readme.md new file mode 100644 index 00000000..b1aac0a2 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0814_binary_tree_pruning/readme.md @@ -0,0 +1,74 @@ +[![](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) + +## 814\. Binary Tree Pruning + +Medium + +Given the `root` of a binary tree, return _the same tree where every subtree (of the given tree) not containing a_ `1` _has been removed_. + +A subtree of a node `node` is `node` plus every node that is a descendant of `node`. + +**Example 1:** + +![](https://s3-lc-upload.s3.amazonaws.com/uploads/2018/04/06/1028_2.png) + +**Input:** root = [1,null,0,0,1] + +**Output:** [1,null,0,null,1] + +**Explanation:** + +Only the red nodes satisfy the property "every subtree not containing a 1". + +The diagram on the right represents the answer. + +**Example 2:** + +![](https://s3-lc-upload.s3.amazonaws.com/uploads/2018/04/06/1028_1.png) + +**Input:** root = [1,0,1,0,0,0,1] + +**Output:** [1,null,1,null,1] + +**Example 3:** + +![](https://s3-lc-upload.s3.amazonaws.com/uploads/2018/04/05/1028.png) + +**Input:** root = [1,1,0,1,1,0,1,0] + +**Output:** [1,1,0,1,1,null,1] + +**Constraints:** + +* The number of nodes in the tree is in the range `[1, 200]`. +* `Node.val` is either `0` or `1`. + +## Solution + +```kotlin +import com_github_leetcode.TreeNode + +/** + * Example: + * var ti = TreeNode(5) + * var v = ti.`val` + * Definition for a binary tree node. + * class TreeNode(var `val`: Int) { + * var left: TreeNode? = null + * var right: TreeNode? = null + * } + */ +class Solution { + fun pruneTree(root: TreeNode?): TreeNode? { + if (root == null) { + return root + } + root.left = pruneTree(root.left) + root.right = pruneTree(root.right) + return if (root.left == null && root.right == null && root.`val` == 0) { + null + } else root + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0815_bus_routes/readme.md b/src/main/kotlin/g0801_0900/s0815_bus_routes/readme.md new file mode 100644 index 00000000..bc20ed82 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0815_bus_routes/readme.md @@ -0,0 +1,130 @@ +[![](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) + +## 815\. Bus Routes + +Hard + +You are given an array `routes` representing bus routes where `routes[i]` is a bus route that the ith bus repeats forever. + +* For example, if `routes[0] = [1, 5, 7]`, this means that the 0th bus travels in the sequence `1 -> 5 -> 7 -> 1 -> 5 -> 7 -> 1 -> ...` forever. + +You will start at the bus stop `source` (You are not on any bus initially), and you want to go to the bus stop `target`. You can travel between bus stops by buses only. + +Return _the least number of buses you must take to travel from_ `source` _to_ `target`. Return `-1` if it is not possible. + +**Example 1:** + +**Input:** routes = \[\[1,2,7],[3,6,7]], source = 1, target = 6 + +**Output:** 2 + +**Explanation:** The best strategy is take the first bus to the bus stop 7, then take the second bus to the bus stop 6. + +**Example 2:** + +**Input:** routes = \[\[7,12],[4,5,15],[6],[15,19],[9,12,13]], source = 15, target = 12 + +**Output:** -1 + +**Constraints:** + +* `1 <= routes.length <= 500`. +* 1 <= routes[i].length <= 105 +* All the values of `routes[i]` are **unique**. +* sum(routes[i].length) <= 105 +* 0 <= routes[i][j] < 106 +* 0 <= source, target < 106 + +## Solution + +```kotlin +import java.util.Arrays +import java.util.LinkedList +import java.util.Queue +import kotlin.collections.ArrayList +import kotlin.collections.HashSet +import kotlin.collections.MutableSet + +class Solution { + fun numBusesToDestination(routes: Array, source: Int, target: Int): Int { + if (source == target) { + return 0 + } + val targetRoutes: MutableSet = HashSet() + val queue: Queue = LinkedList() + val taken = BooleanArray(routes.size) + val graph = buildGraph(routes, source, target, queue, targetRoutes, taken) + if (targetRoutes.isEmpty()) { + return -1 + } + var bus = 1 + while (!queue.isEmpty()) { + val size = queue.size + for (i in 0 until size) { + val route = queue.poll() + if (targetRoutes.contains(route)) { + return bus + } + for (nextRoute in graph[route]!!) { + if (!taken[nextRoute]) { + queue.offer(nextRoute) + taken[nextRoute] = true + } + } + } + bus++ + } + return -1 + } + + private fun buildGraph( + routes: Array, + source: Int, + target: Int, + queue: Queue, + targetRoutes: MutableSet, + taken: BooleanArray + ): Array?> { + val len = routes.size + val graph: Array?> = arrayOfNulls(len) + for (i in 0 until len) { + Arrays.sort(routes[i]) + graph[i] = ArrayList() + var id = Arrays.binarySearch(routes[i], source) + if (id >= 0) { + queue.offer(i) + taken[i] = true + } + id = Arrays.binarySearch(routes[i], target) + if (id >= 0) { + targetRoutes.add(i) + } + } + for (i in 0 until len) { + for (j in i + 1 until len) { + if (commonStop(routes[i], routes[j])) { + graph[i]?.add(j) + graph[j]?.add(i) + } + } + } + return graph + } + + private fun commonStop(routeA: IntArray, routeB: IntArray): Boolean { + var idA = 0 + var idB = 0 + while (idA < routeA.size && idB < routeB.size) { + if (routeA[idA] == routeB[idB]) { + return true + } else if (routeA[idA] < routeB[idB]) { + idA++ + } else { + idB++ + } + } + return false + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0816_ambiguous_coordinates/readme.md b/src/main/kotlin/g0801_0900/s0816_ambiguous_coordinates/readme.md new file mode 100644 index 00000000..10da930a --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0816_ambiguous_coordinates/readme.md @@ -0,0 +1,126 @@ +[![](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) + +## 816\. Ambiguous Coordinates + +Medium + +We had some 2-dimensional coordinates, like `"(1, 3)"` or `"(2, 0.5)"`. Then, we removed all commas, decimal points, and spaces and ended up with the string s. + +* For example, `"(1, 3)"` becomes `s = "(13)"` and `"(2, 0.5)"` becomes `s = "(205)"`. + +Return _a list of strings representing all possibilities for what our original coordinates could have been_. + +Our original representation never had extraneous zeroes, so we never started with numbers like `"00"`, `"0.0"`, `"0.00"`, `"1.0"`, `"001"`, `"00.01"`, or any other number that can be represented with fewer digits. Also, a decimal point within a number never occurs without at least one digit occurring before it, so we never started with numbers like `".1"`. + +The final answer list can be returned in any order. All coordinates in the final answer have exactly one space between them (occurring after the comma.) + +**Example 1:** + +**Input:** s = "(123)" + +**Output:** ["(1, 2.3)","(1, 23)","(1.2, 3)","(12, 3)"] + +**Example 2:** + +**Input:** s = "(0123)" + +**Output:** ["(0, 1.23)","(0, 12.3)","(0, 123)","(0.1, 2.3)","(0.1, 23)","(0.12, 3)"] + +**Explanation:** 0.0, 00, 0001 or 00.01 are not allowed. + +**Example 3:** + +**Input:** s = "(00011)" + +**Output:** ["(0, 0.011)","(0.001, 1)"] + +**Constraints:** + +* `4 <= s.length <= 12` +* `s[0] == '('` and `s[s.length - 1] == ')'`. +* The rest of `s` are digits. + +## Solution + +```kotlin +@Suppress("kotlin:S107") +class Solution { + fun ambiguousCoordinates(s: String): List { + val sc = s.toCharArray() + val result: MutableList = ArrayList() + val sb = StringBuilder() + for (commaPos in 2 until sc.size - 1) { + if (isValidNum(sc, 1, commaPos - 1)) { + if (isValidNum(sc, commaPos, sc.size - 2)) { + buildNumbs(result, sb, sc, commaPos - 1, 0, commaPos, sc.size - 2, 0) + } + for (dp2Idx in commaPos + 1 until sc.size - 1) { + if (isValidDPNum(sc, commaPos, sc.size - 2, dp2Idx)) { + buildNumbs(result, sb, sc, commaPos - 1, 0, commaPos, sc.size - 2, dp2Idx) + } + } + } + for (dp1Idx in 2 until commaPos) { + if (isValidDPNum(sc, 1, commaPos - 1, dp1Idx)) { + if (isValidNum(sc, commaPos, sc.size - 2)) { + buildNumbs(result, sb, sc, commaPos - 1, dp1Idx, commaPos, sc.size - 2, 0) + } + for (dp2Idx in commaPos + 1 until sc.size - 1) { + if (isValidDPNum(sc, commaPos, sc.size - 2, dp2Idx)) { + buildNumbs( + result, + sb, + sc, + commaPos - 1, + dp1Idx, + commaPos, + sc.size - 2, + dp2Idx + ) + } + } + } + } + } + return result + } + + private fun isValidNum(sc: CharArray, startIdx: Int, lastIdx: Int): Boolean { + return sc[startIdx] != '0' || lastIdx - startIdx == 0 + } + + private fun isValidDPNum(sc: CharArray, startIdx: Int, lastIdx: Int, dpIdx: Int): Boolean { + return (sc[startIdx] != '0' || dpIdx - startIdx == 1) && sc[lastIdx] != '0' + } + + private fun buildNumbs( + result: MutableList, + sb: StringBuilder, + sc: CharArray, + last1Idx: Int, + dp1Idx: Int, + start2Idx: Int, + last2Idx: Int, + dp2Idx: Int + ) { + sb.setLength(0) + sb.append('(') + if (dp1Idx == 0) { + sb.append(sc, 1, last1Idx - 1 + 1) + } else { + sb.append(sc, 1, dp1Idx - 1).append('.').append(sc, dp1Idx, last1Idx - dp1Idx + 1) + } + sb.append(',').append(' ') + if (dp2Idx == 0) { + sb.append(sc, start2Idx, last2Idx - start2Idx + 1) + } else { + sb.append(sc, start2Idx, dp2Idx - start2Idx) + .append('.') + .append(sc, dp2Idx, last2Idx - dp2Idx + 1) + } + sb.append(')') + result.add(sb.toString()) + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0817_linked_list_components/readme.md b/src/main/kotlin/g0801_0900/s0817_linked_list_components/readme.md new file mode 100644 index 00000000..5778754e --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0817_linked_list_components/readme.md @@ -0,0 +1,79 @@ +[![](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) + +## 817\. Linked List Components + +Medium + +You are given the `head` of a linked list containing unique integer values and an integer array `nums` that is a subset of the linked list values. + +Return _the number of connected components in_ `nums` _where two values are connected if they appear **consecutively** in the linked list_. + +**Example 1:** + +![](https://assets.leetcode.com/uploads/2021/07/22/lc-linkedlistcom1.jpg) + +**Input:** head = [0,1,2,3], nums = [0,1,3] + +**Output:** 2 + +**Explanation:** 0 and 1 are connected, so [0, 1] and [3] are the two connected components. + +**Example 2:** + +![](https://assets.leetcode.com/uploads/2021/07/22/lc-linkedlistcom2.jpg) + +**Input:** head = [0,1,2,3,4], nums = [0,3,1,4] + +**Output:** 2 + +**Explanation:** 0 and 1 are connected, 3 and 4 are connected, so [0, 1] and [3, 4] are the two connected components. + +**Constraints:** + +* The number of nodes in the linked list is `n`. +* 1 <= n <= 104 +* `0 <= Node.val < n` +* All the values `Node.val` are **unique**. +* `1 <= nums.length <= n` +* `0 <= nums[i] < n` +* All the values of `nums` are **unique**. + +## Solution + +```kotlin +import com_github_leetcode.ListNode + +/** + * Example: + * var li = ListNode(5) + * var v = li.`val` + * Definition for singly-linked list. + * class ListNode(var `val`: Int) { + * var next: ListNode? = null + * } + */ + +@Suppress("NAME_SHADOWING") +class Solution { + fun numComponents(head: ListNode?, nums: IntArray): Int { + var head = head + val set: HashSet = HashSet() + for (i in nums) { + set.add(i) + } + var result = 0 + while (head != null) { + if (set.contains(head.`val`)) { + while (head != null && set.contains(head.`val`)) { + head = head.next + } + result++ + } else { + head = head.next + } + } + return result + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0818_race_car/readme.md b/src/main/kotlin/g0801_0900/s0818_race_car/readme.md new file mode 100644 index 00000000..15d430b7 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0818_race_car/readme.md @@ -0,0 +1,75 @@ +[![](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) + +## 818\. Race Car + +Hard + +Your car starts at position `0` and speed `+1` on an infinite number line. Your car can go into negative positions. Your car drives automatically according to a sequence of instructions `'A'` (accelerate) and `'R'` (reverse): + +* When you get an instruction `'A'`, your car does the following: + * `position += speed` + * `speed *= 2` +* When you get an instruction `'R'`, your car does the following: + * If your speed is positive then `speed = -1` + * otherwise `speed = 1`Your position stays the same. + +For example, after commands `"AAR"`, your car goes to positions `0 --> 1 --> 3 --> 3`, and your speed goes to `1 --> 2 --> 4 --> -1`. + +Given a target position `target`, return _the length of the shortest sequence of instructions to get there_. + +**Example 1:** + +**Input:** target = 3 + +**Output:** 2 + +**Explanation:** + +The shortest instruction sequence is "AA". + +Your position goes from 0 --> 1 --> 3. + +**Example 2:** + +**Input:** target = 6 + +**Output:** 5 + +**Explanation:** + +The shortest instruction sequence is "AAARA". + +Your position goes from 0 --> 1 --> 3 --> 7 --> 7 --> 6. + +**Constraints:** + +* 1 <= target <= 104 + +## Solution + +```kotlin +import java.util.LinkedList +import java.util.Queue + +class Solution { + fun racecar(target: Int): Int { + val queue: Queue = LinkedList() + queue.add(intArrayOf(0, 1, 0)) + while (!queue.isEmpty()) { + val arr = queue.poll() + if (arr[0] == target) { + return arr[2] + } + queue.add(intArrayOf(arr[0] + arr[1], 2 * arr[1], 1 + arr[2])) + if (arr[0] + arr[1] > target && arr[1] > 0) { + queue.add(intArrayOf(arr[0], -1, 1 + arr[2])) + } + if (arr[0] + arr[1] < target && arr[1] < 0) { + queue.add(intArrayOf(arr[0], 1, 1 + arr[2])) + } + } + return -1 + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0819_most_common_word/readme.md b/src/main/kotlin/g0801_0900/s0819_most_common_word/readme.md new file mode 100644 index 00000000..5bec2b32 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0819_most_common_word/readme.md @@ -0,0 +1,60 @@ +[![](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) + +## 819\. Most Common Word + +Easy + +Given a string `paragraph` and a string array of the banned words `banned`, return _the most frequent word that is not banned_. It is **guaranteed** there is **at least one word** that is not banned, and that the answer is **unique**. + +The words in `paragraph` are **case-insensitive** and the answer should be returned in **lowercase**. + +**Example 1:** + +**Input:** paragraph = "Bob hit a ball, the hit BALL flew far after it was hit.", banned = ["hit"] + +**Output:** "ball" + +**Explanation:** "hit" occurs 3 times, but it is a banned word. "ball" occurs twice (and no other word does), so it is the most frequent non-banned word in the paragraph. Note that words in the paragraph are not case sensitive, that punctuation is ignored (even if adjacent to words, such as "ball,"), and that "hit" isn't the answer even though it occurs more because it is banned. + +**Example 2:** + +**Input:** paragraph = "a.", banned = [] + +**Output:** "a" + +**Constraints:** + +* `1 <= paragraph.length <= 1000` +* paragraph consists of English letters, space `' '`, or one of the symbols: `"!?',;."`. +* `0 <= banned.length <= 100` +* `1 <= banned[i].length <= 10` +* `banned[i]` consists of only lowercase English letters. + +## Solution + +```kotlin +import java.util.Locale + +@Suppress("NAME_SHADOWING") +class Solution { + fun mostCommonWord(paragraph: String, banned: Array): String { + var paragraph = paragraph + paragraph = paragraph.replace("\\p{Punct}".toRegex(), " ").lowercase(Locale.getDefault()) + val a = paragraph.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + for (i in banned.indices) { + banned[i] = banned[i].lowercase(Locale.getDefault()) + } + val map: MutableMap = HashMap() + for (s in a) { + val x = map.getOrDefault(s, 0) + map[s] = x + 1 + } + for (s in banned) { + map.remove(s) + map.remove("") + } + return map.maxBy { it.value }.key + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0820_short_encoding_of_words/readme.md b/src/main/kotlin/g0801_0900/s0820_short_encoding_of_words/readme.md new file mode 100644 index 00000000..ed78aaa8 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0820_short_encoding_of_words/readme.md @@ -0,0 +1,78 @@ +[![](https://img.shields.io/github/stars/javadev/LeetCode-in-Kotlin?label=Stars&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin) +[![](https://img.shields.io/github/forks/javadev/LeetCode-in-Kotlin?label=Fork%20me%20on%20GitHub%20&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin/fork) + +## 820\. Short Encoding of Words + +Medium + +A **valid encoding** of an array of `words` is any reference string `s` and array of indices `indices` such that: + +* `words.length == indices.length` +* The reference string `s` ends with the `'#'` character. +* For each index `indices[i]`, the **substring** of `s` starting from `indices[i]` and up to (but not including) the next `'#'` character is equal to `words[i]`. + +Given an array of `words`, return _the **length of the shortest reference string**_ `s` _possible of any **valid encoding** of_ `words`_._ + +**Example 1:** + +**Input:** words = ["time", "me", "bell"] + +**Output:** 10 + +**Explanation:** A valid encoding would be s = `"time#bell#" and indices = [0, 2, 5`]. + +words[0] = "time", the substring of s starting from indices[0] = 0 to the next '#' is underlined in "time#bell#" + +words[1] = "me", the substring of s starting from indices[1] = 2 to the next '#' is underlined in "time#bell#" + +words[2] = "bell", the substring of s starting from indices[2] = 5 to the next '#' is underlined in "time#bell#" + +**Example 2:** + +**Input:** words = ["t"] + +**Output:** 2 + +**Explanation:** A valid encoding would be s = "t#" and indices = [0]. + +**Constraints:** + +* `1 <= words.length <= 2000` +* `1 <= words[i].length <= 7` +* `words[i]` consists of only lowercase letters. + +## Solution + +```kotlin +class Solution { + private class Node { + var nodes = arrayOfNulls(26) + } + + private fun insert(node: Node, word: String): Boolean { + var current: Node? = node + val n = word.length + var flag = false + for (i in n - 1 downTo 0) { + if (current!!.nodes[word[i].code - 'a'.code] == null) { + current.nodes[word[i].code - 'a'.code] = Node() + flag = true + } + current = current.nodes[word[i].code - 'a'.code] + } + return flag + } + + fun minimumLengthEncoding(words: Array): Int { + var out = 0 + words.sortWith { a: String, b: String -> b.length - a.length } + val node = Node() + for (word in words) { + if (insert(node, word)) { + out += word.length + 1 + } + } + return out + } +} +``` \ No newline at end of file diff --git a/src/main/kotlin/g0801_0900/s0821_shortest_distance_to_a_character/readme.md b/src/main/kotlin/g0801_0900/s0821_shortest_distance_to_a_character/readme.md new file mode 100644 index 00000000..5310eb70 --- /dev/null +++ b/src/main/kotlin/g0801_0900/s0821_shortest_distance_to_a_character/readme.md @@ -0,0 +1,73 @@ +[![](https://img.shields.io/github/stars/javadev/LeetCode-in-Kotlin?label=Stars&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin) +[![](https://img.shields.io/github/forks/javadev/LeetCode-in-Kotlin?label=Fork%20me%20on%20GitHub%20&style=flat-square)](https://github.com/javadev/LeetCode-in-Kotlin/fork) + +## 821\. Shortest Distance to a Character + +Easy + +Given a string `s` and a character `c` that occurs in `s`, return _an array of integers_ `answer` _where_ `answer.length == s.length` _and_ `answer[i]` _is the **distance** from index_ `i` _to the **closest** occurrence of character_ `c` _in_ `s`. + +The **distance** between two indices `i` and `j` is `abs(i - j)`, where `abs` is the absolute value function. + +**Example 1:** + +**Input:** s = "loveleetcode", c = "e" + +**Output:** [3,2,1,0,1,0,0,1,2,2,1,0] + +**Explanation:** The character 'e' appears at indices 3, 5, 6, and 11 (0-indexed). + +The closest occurrence of 'e' for index 0 is at index 3, so the distance is abs(0 - 3) = 3. + +The closest occurrence of 'e' for index 1 is at index 3, so the distance is abs(1 - 3) = 2. + +For index 4, there is a tie between the 'e' at index 3 and the 'e' at index 5, but the distance is still the same: abs(4 - 3) == abs(4 - 5) = 1. + +The closest occurrence of 'e' for index 8 is at index 6, so the distance is abs(8 - 6) = 2. + +**Example 2:** + +**Input:** s = "aaab", c = "b" + +**Output:** [3,2,1,0] + +**Constraints:** + +* 1 <= s.length <= 104 +* `s[i]` and `c` are lowercase English letters. +* It is guaranteed that `c` occurs at least once in `s`. + +## Solution + +```kotlin +class Solution { + fun shortestToChar(s: String, c: Char): IntArray { + val result = IntArray(s.length) + result.fill(Int.MAX_VALUE) + for (i in s.indices) { + if (s[i] == c) { + result[i] = 0 + } + } + for (i in s.indices) { + if (result[i] != 0) { + var j = i - 1 + while (j >= 0 && result[j] != 0) { + j-- + } + if (j >= 0) { + result[i] = i - j + } + j = i + 1 + while (j < s.length && result[j] != 0) { + j++ + } + if (j < s.length) { + result[i] = result[i].coerceAtMost(j - i) + } + } + } + return result + } +} +``` \ No newline at end of file