Skip to content

Commit ddc89ce

Browse files
authored
Added tasks 1041, 1042, 1043, 1044
1 parent 051bd03 commit ddc89ce

File tree

13 files changed

+478
-0
lines changed

13 files changed

+478
-0
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1779,6 +1779,10 @@ implementation 'com.github.javadev:leetcode-in-kotlin:1.12'
17791779
| 1155 |[Number of Dice Rolls With Target Sum](src/main/kotlin/g1101_1200/s1155_number_of_dice_rolls_with_target_sum/Solution.kt)| Medium | Dynamic_Programming | 158 | 80.95
17801780
| 1154 |[Day of the Year](src/main/kotlin/g1101_1200/s1154_day_of_the_year/Solution.kt)| Easy | String, Math | 317 | 70.00
17811781
| 1143 |[Longest Common Subsequence](src/main/kotlin/g1101_1200/s1143_longest_common_subsequence/Solution.kt)| 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
1782+
| 1044 |[Longest Duplicate Substring](src/main/kotlin/g1001_1100/s1044_longest_duplicate_substring/Solution.kt)| Hard | String, Binary_Search, Sliding_Window, Hash_Function, Rolling_Hash, Suffix_Array | 592 | 100.00
1783+
| 1043 |[Partition Array for Maximum Sum](src/main/kotlin/g1001_1100/s1043_partition_array_for_maximum_sum/Solution.kt)| Medium | Array, Dynamic_Programming | 194 | 71.43
1784+
| 1042 |[Flower Planting With No Adjacent](src/main/kotlin/g1001_1100/s1042_flower_planting_with_no_adjacent/Solution.kt)| Medium | Depth_First_Search, Breadth_First_Search, Graph | 396 | 85.71
1785+
| 1041 |[Robot Bounded In Circle](src/main/kotlin/g1001_1100/s1041_robot_bounded_in_circle/Solution.kt)| Medium | String, Math, Simulation | 121 | 100.00
17821786
| 1040 |[Moving Stones Until Consecutive II](src/main/kotlin/g1001_1100/s1040_moving_stones_until_consecutive_ii/Solution.kt)| Medium | Array, Math, Sorting, Two_Pointers | 287 | 50.00
17831787
| 1039 |[Minimum Score Triangulation of Polygon](src/main/kotlin/g1001_1100/s1039_minimum_score_triangulation_of_polygon/Solution.kt)| Medium | Array, Dynamic_Programming | 147 | 100.00
17841788
| 1038 |[Binary Search Tree to Greater Sum Tree](src/main/kotlin/g1001_1100/s1038_binary_search_tree_to_greater_sum_tree/Solution.kt)| Medium | Depth_First_Search, Tree, Binary_Tree, Binary_Search_Tree | 123 | 91.67
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package g1001_1100.s1041_robot_bounded_in_circle
2+
3+
// #Medium #String #Math #Simulation #2023_05_27_Time_121_ms_(100.00%)_Space_34.3_MB_(66.67%)
4+
5+
class Solution {
6+
fun isRobotBounded(instructions: String): Boolean {
7+
val dir = arrayOf(intArrayOf(0, 1), intArrayOf(-1, 0), intArrayOf(0, -1), intArrayOf(1, 0))
8+
var i = 0
9+
var x = 0
10+
var y = 0
11+
for (s in instructions.indices) {
12+
if (instructions[s] == 'L') {
13+
i = (i + 1) % 4
14+
} else if (instructions[s] == 'R') {
15+
i = (i + 3) % 4
16+
} else {
17+
x += dir[i][0]
18+
y += dir[i][1]
19+
}
20+
}
21+
return x == 0 && y == 0 || i != 0
22+
}
23+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
1041\. Robot Bounded In Circle
2+
3+
Medium
4+
5+
On an infinite plane, a robot initially stands at `(0, 0)` and faces north. Note that:
6+
7+
* The **north direction** is the positive direction of the y-axis.
8+
* The **south direction** is the negative direction of the y-axis.
9+
* The **east direction** is the positive direction of the x-axis.
10+
* The **west direction** is the negative direction of the x-axis.
11+
12+
The robot can receive one of three instructions:
13+
14+
* `"G"`: go straight 1 unit.
15+
* `"L"`: turn 90 degrees to the left (i.e., anti-clockwise direction).
16+
* `"R"`: turn 90 degrees to the right (i.e., clockwise direction).
17+
18+
The robot performs the `instructions` given in order, and repeats them forever.
19+
20+
Return `true` if and only if there exists a circle in the plane such that the robot never leaves the circle.
21+
22+
**Example 1:**
23+
24+
**Input:** instructions = "GGLLGG"
25+
26+
**Output:** true
27+
28+
**Explanation:** The robot is initially at (0, 0) facing the north direction.
29+
30+
"G": move one step. Position: (0, 1). Direction: North.
31+
32+
"G": move one step. Position: (0, 2). Direction: North.
33+
34+
"L": turn 90 degrees anti-clockwise. Position: (0, 2). Direction: West.
35+
36+
"L": turn 90 degrees anti-clockwise. Position: (0, 2). Direction: South.
37+
38+
"G": move one step. Position: (0, 1). Direction: South.
39+
40+
"G": move one step. Position: (0, 0). Direction: South.
41+
42+
Repeating the instructions, the robot goes into the cycle: (0, 0) --> (0, 1) --> (0, 2) --> (0, 1) --> (0, 0).
43+
44+
Based on that, we return true.
45+
46+
**Example 2:**
47+
48+
**Input:** instructions = "GG"
49+
50+
**Output:** false
51+
52+
**Explanation:** The robot is initially at (0, 0) facing the north direction.
53+
54+
"G": move one step. Position: (0, 1). Direction: North.
55+
56+
"G": move one step. Position: (0, 2). Direction: North.
57+
58+
Repeating the instructions, keeps advancing in the north direction and does not go into cycles.
59+
60+
Based on that, we return false.
61+
62+
**Example 3:**
63+
64+
**Input:** instructions = "GL"
65+
66+
**Output:** true
67+
68+
**Explanation:** The robot is initially at (0, 0) facing the north direction.
69+
70+
"G": move one step. Position: (0, 1). Direction: North.
71+
72+
"L": turn 90 degrees anti-clockwise. Position: (0, 1). Direction: West.
73+
74+
"G": move one step. Position: (-1, 1). Direction: West.
75+
76+
"L": turn 90 degrees anti-clockwise. Position: (-1, 1). Direction: South.
77+
78+
"G": move one step. Position: (-1, 0). Direction: South.
79+
80+
"L": turn 90 degrees anti-clockwise. Position: (-1, 0). Direction: East.
81+
82+
"G": move one step. Position: (0, 0). Direction: East.
83+
84+
"L": turn 90 degrees anti-clockwise. Position: (0, 0). Direction: North.
85+
86+
Repeating the instructions, the robot goes into the cycle: (0, 0) --> (0, 1) --> (-1, 1) --> (-1, 0) --> (0, 0).
87+
88+
Based on that, we return true.
89+
90+
**Constraints:**
91+
92+
* `1 <= instructions.length <= 100`
93+
* `instructions[i]` is `'G'`, `'L'` or, `'R'`.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package g1001_1100.s1042_flower_planting_with_no_adjacent
2+
3+
// #Medium #Depth_First_Search #Breadth_First_Search #Graph
4+
// #2023_05_27_Time_396_ms_(85.71%)_Space_82.5_MB_(42.86%)
5+
6+
class Solution {
7+
private lateinit var graph: Array<ArrayList<Int>?>
8+
private lateinit var color: IntArray
9+
private lateinit var visited: BooleanArray
10+
11+
fun gardenNoAdj(n: Int, paths: Array<IntArray>): IntArray {
12+
buildGraph(n, paths)
13+
color = IntArray(n)
14+
visited = BooleanArray(n)
15+
for (i in 0 until n) {
16+
if (!visited[i]) {
17+
dfs(i)
18+
}
19+
}
20+
return color
21+
}
22+
23+
private fun dfs(at: Int) {
24+
visited[at] = true
25+
var used = 0
26+
for (to in graph[at]!!) {
27+
if (color[to] != 0) {
28+
used = used or (1 shl color[to] - 1)
29+
}
30+
}
31+
32+
// use available color
33+
for (i in 0..3) {
34+
if (used and (1 shl i) == 0) {
35+
color[at] = i + 1
36+
break
37+
}
38+
}
39+
}
40+
41+
private fun buildGraph(n: Int, paths: Array<IntArray>) {
42+
graph = arrayOfNulls(n)
43+
for (i in 0 until n) {
44+
graph[i] = ArrayList()
45+
}
46+
for (path in paths) {
47+
val u = path[0] - 1
48+
val v = path[1] - 1
49+
graph[u]!!.add(v)
50+
graph[v]!!.add(u)
51+
}
52+
}
53+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
1042\. Flower Planting With No Adjacent
2+
3+
Medium
4+
5+
You have `n` gardens, labeled from `1` to `n`, and an array `paths` where <code>paths[i] = [x<sub>i</sub>, y<sub>i</sub>]</code> describes a bidirectional path between garden <code>x<sub>i</sub></code> to garden <code>y<sub>i</sub></code>. In each garden, you want to plant one of 4 types of flowers.
6+
7+
All gardens have **at most 3** paths coming into or leaving it.
8+
9+
Your task is to choose a flower type for each garden such that, for any two gardens connected by a path, they have different types of flowers.
10+
11+
Return _**any** such a choice as an array_ `answer`_, where_ `answer[i]` _is the type of flower planted in the_ <code>(i+1)<sup>th</sup></code> _garden. The flower types are denoted_ `1`_,_ `2`_,_ `3`_, or_ `4`_. It is guaranteed an answer exists._
12+
13+
**Example 1:**
14+
15+
**Input:** n = 3, paths = [[1,2],[2,3],[3,1]]
16+
17+
**Output:** [1,2,3]
18+
19+
**Explanation:**
20+
21+
Gardens 1 and 2 have different types.
22+
23+
Gardens 2 and 3 have different types.
24+
25+
Gardens 3 and 1 have different types.
26+
27+
Hence, [1,2,3] is a valid answer. Other valid answers include [1,2,4], [1,4,2], and [3,2,1].
28+
29+
**Example 2:**
30+
31+
**Input:** n = 4, paths = [[1,2],[3,4]]
32+
33+
**Output:** [1,2,1,2]
34+
35+
**Example 3:**
36+
37+
**Input:** n = 4, paths = [[1,2],[2,3],[3,4],[4,1],[1,3],[2,4]]
38+
39+
**Output:** [1,2,3,4]
40+
41+
**Constraints:**
42+
43+
* <code>1 <= n <= 10<sup>4</sup></code>
44+
* <code>0 <= paths.length <= 2 * 10<sup>4</sup></code>
45+
* `paths[i].length == 2`
46+
* <code>1 <= x<sub>i</sub>, y<sub>i</sub> <= n</code>
47+
* <code>x<sub>i</sub> != y<sub>i</sub></code>
48+
* Every garden has **at most 3** paths coming into or leaving it.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package g1001_1100.s1043_partition_array_for_maximum_sum
2+
3+
// #Medium #Array #Dynamic_Programming #2023_05_27_Time_194_ms_(71.43%)_Space_38.2_MB_(57.14%)
4+
5+
class Solution {
6+
fun maxSumAfterPartitioning(arr: IntArray, k: Int): Int {
7+
val n = arr.size
8+
val dp = IntArray(n)
9+
for (right in 0 until n) {
10+
var localMax = arr[right]
11+
for (left in right downTo (-1).coerceAtLeast(right - k) + 1) {
12+
localMax = localMax.coerceAtLeast(arr[left])
13+
if (left == 0) {
14+
dp[right] = dp[right].coerceAtLeast((right + 1) * localMax)
15+
} else {
16+
dp[right] = dp[right].coerceAtLeast(dp[left - 1] + (right - left + 1) * localMax)
17+
}
18+
}
19+
}
20+
return dp[n - 1]
21+
}
22+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
1043\. Partition Array for Maximum Sum
2+
3+
Medium
4+
5+
Given an integer array `arr`, partition the array into (contiguous) subarrays of length **at most** `k`. After partitioning, each subarray has their values changed to become the maximum value of that subarray.
6+
7+
Return _the largest sum of the given array after partitioning. Test cases are generated so that the answer fits in a **32-bit** integer._
8+
9+
**Example 1:**
10+
11+
**Input:** arr = [1,15,7,9,2,5,10], k = 3
12+
13+
**Output:** 84
14+
15+
**Explanation:** arr becomes [15,15,15,9,10,10,10]
16+
17+
**Example 2:**
18+
19+
**Input:** arr = [1,4,1,5,7,3,6,1,9,9,3], k = 4
20+
21+
**Output:** 83
22+
23+
**Example 3:**
24+
25+
**Input:** arr = [1], k = 1
26+
27+
**Output:** 1
28+
29+
**Constraints:**
30+
31+
* `1 <= arr.length <= 500`
32+
* <code>0 <= arr[i] <= 10<sup>9</sup></code>
33+
* `1 <= k <= arr.length`
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package g1001_1100.s1044_longest_duplicate_substring
2+
3+
// #Hard #String #Binary_Search #Sliding_Window #Hash_Function #Rolling_Hash #Suffix_Array
4+
// #2023_05_27_Time_592_ms_(100.00%)_Space_106.4_MB_(100.00%)
5+
6+
class Solution {
7+
private lateinit var hsh: LongArray
8+
private lateinit var pw: LongArray
9+
private val cnt: Array<MutableList<Int>?> = arrayOfNulls(26)
10+
11+
fun longestDupSubstring(s: String): String {
12+
val n = s.length
13+
val base = 131
14+
for (i in 0..25) {
15+
cnt[i] = ArrayList()
16+
}
17+
hsh = LongArray(n + 1)
18+
pw = LongArray(n + 1)
19+
pw[0] = 1
20+
for (j in 1..n) {
21+
hsh[j] = (hsh[j - 1] * base + s[j - 1].code.toLong()) % MOD
22+
pw[j] = pw[j - 1] * base % MOD
23+
cnt[s[j - 1].code - 'a'.code]!!.add(j - 1)
24+
}
25+
var ans = ""
26+
for (i in 0..25) {
27+
if (cnt[i]!!.isEmpty()) {
28+
continue
29+
}
30+
val idx: MutableList<Int>? = cnt[i]
31+
var set: MutableSet<Long?>
32+
var lo = 1
33+
var hi = n - idx!![0]
34+
while (lo <= hi) {
35+
val len = (lo + hi) / 2
36+
set = HashSet()
37+
var found = false
38+
for (nxt in idx) {
39+
if (nxt + len <= n) {
40+
val substrHash = getSubstrHash(nxt, nxt + len)
41+
if (set.contains(substrHash)) {
42+
found = true
43+
if (len + 1 > ans.length) {
44+
ans = s.substring(nxt, nxt + len)
45+
}
46+
break
47+
}
48+
set.add(substrHash)
49+
}
50+
}
51+
if (found) {
52+
lo = len + 1
53+
} else {
54+
hi = len - 1
55+
}
56+
}
57+
}
58+
return ans
59+
}
60+
61+
private fun getSubstrHash(l: Int, r: Int): Long {
62+
return (hsh[r] - hsh[l] * pw[r - l] % MOD + MOD) % MOD
63+
}
64+
65+
companion object {
66+
private const val MOD = 1e9.toInt() + 7
67+
}
68+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
1044\. Longest Duplicate Substring
2+
3+
Hard
4+
5+
Given a string `s`, consider all _duplicated substrings_: (contiguous) substrings of s that occur 2 or more times. The occurrences may overlap.
6+
7+
Return **any** duplicated substring that has the longest possible length. If `s` does not have a duplicated substring, the answer is `""`.
8+
9+
**Example 1:**
10+
11+
**Input:** s = "banana"
12+
13+
**Output:** "ana"
14+
15+
**Example 2:**
16+
17+
**Input:** s = "abcd"
18+
19+
**Output:** ""
20+
21+
**Constraints:**
22+
23+
* <code>2 <= s.length <= 3 * 10<sup>4</sup></code>
24+
* `s` consists of lowercase English letters.

0 commit comments

Comments
 (0)