Skip to content

Added tasks 3527-3534 #804

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package g3501_3600.s3527_find_the_most_common_response

// #Medium #Array #String #Hash_Table #Counting
// #2025_04_27_Time_73_ms_(100.00%)_Space_243.97_MB_(50.00%)

class Solution {
private fun compareStrings(str1: String, str2: String): Boolean {
val n = str1.length
val m = str2.length
var i = 0
var j = 0
while (i < n && j < m) {
if (str1[i] < str2[j]) {
return true
} else if (str1[i] > str2[j]) {
return false
}
i++
j++
}
return n < m
}

fun findCommonResponse(responses: List<List<String>>): String {
val n = responses.size
val mp: MutableMap<String, IntArray> = HashMap()
var ans = responses[0][0]
var maxFreq = 0
for (row in 0..<n) {
val m = responses[row].size
for (col in 0..<m) {
val resp = responses[row][col]
val arr = mp.getOrDefault(resp, intArrayOf(0, -1))
if (arr[1] != row) {
arr[0]++
arr[1] = row
mp.put(resp, arr)
}
if (arr[0] > maxFreq ||
(ans != resp) && arr[0] == maxFreq && compareStrings(resp, ans)
) {
ans = resp
maxFreq = arr[0]
}
}
}
return ans
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
3527\. Find the Most Common Response

Medium

You are given a 2D string array `responses` where each `responses[i]` is an array of strings representing survey responses from the <code>i<sup>th</sup></code> day.

Return the **most common** response across all days after removing **duplicate** responses within each `responses[i]`. If there is a tie, return the _lexicographically smallest_ response.

**Example 1:**

**Input:** responses = [["good","ok","good","ok"],["ok","bad","good","ok","ok"],["good"],["bad"]]

**Output:** "good"

**Explanation:**

* After removing duplicates within each list, `responses = [["good", "ok"], ["ok", "bad", "good"], ["good"], ["bad"]]`.
* `"good"` appears 3 times, `"ok"` appears 2 times, and `"bad"` appears 2 times.
* Return `"good"` because it has the highest frequency.

**Example 2:**

**Input:** responses = [["good","ok","good"],["ok","bad"],["bad","notsure"],["great","good"]]

**Output:** "bad"

**Explanation:**

* After removing duplicates within each list we have `responses = [["good", "ok"], ["ok", "bad"], ["bad", "notsure"], ["great", "good"]]`.
* `"bad"`, `"good"`, and `"ok"` each occur 2 times.
* The output is `"bad"` because it is the lexicographically smallest amongst the words with the highest frequency.

**Constraints:**

* `1 <= responses.length <= 1000`
* `1 <= responses[i].length <= 1000`
* `1 <= responses[i][j].length <= 10`
* `responses[i][j]` consists of only lowercase English letters
16 changes: 16 additions & 0 deletions src/main/kotlin/g3501_3600/s3528_unit_conversion_i/Solution.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package g3501_3600.s3528_unit_conversion_i

// #Medium #Depth_First_Search #Breadth_First_Search #Graph
// #2025_04_27_Time_3_ms_(100.00%)_Space_128.33_MB_(100.00%)

class Solution {
fun baseUnitConversions(conversions: Array<IntArray>): IntArray {
val arr = IntArray(conversions.size + 1)
arr[0] = 1
for (conversion in conversions) {
val `val` = (arr[conversion[0]].toLong() * conversion[2]) % 1000000007
arr[conversion[1]] = `val`.toInt()
}
return arr
}
}
44 changes: 44 additions & 0 deletions src/main/kotlin/g3501_3600/s3528_unit_conversion_i/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
3528\. Unit Conversion I

Medium

There are `n` types of units indexed from `0` to `n - 1`. You are given a 2D integer array `conversions` of length `n - 1`, where <code>conversions[i] = [sourceUnit<sub>i</sub>, targetUnit<sub>i</sub>, conversionFactor<sub>i</sub>]</code>. This indicates that a single unit of type <code>sourceUnit<sub>i</sub></code> is equivalent to <code>conversionFactor<sub>i</sub></code> units of type <code>targetUnit<sub>i</sub></code>.

Return an array `baseUnitConversion` of length `n`, where `baseUnitConversion[i]` is the number of units of type `i` equivalent to a single unit of type 0. Since the answer may be large, return each `baseUnitConversion[i]` **modulo** <code>10<sup>9</sup> + 7</code>.

**Example 1:**

**Input:** conversions = [[0,1,2],[1,2,3]]

**Output:** [1,2,6]

**Explanation:**

* Convert a single unit of type 0 into 2 units of type 1 using `conversions[0]`.
* Convert a single unit of type 0 into 6 units of type 2 using `conversions[0]`, then `conversions[1]`.

![](https://assets.leetcode.com/uploads/2025/03/12/example1.png)

**Example 2:**

**Input:** conversions = [[0,1,2],[0,2,3],[1,3,4],[1,4,5],[2,5,2],[4,6,3],[5,7,4]]

**Output:** [1,2,3,8,10,6,30,24]

**Explanation:**

* Convert a single unit of type 0 into 2 units of type 1 using `conversions[0]`.
* Convert a single unit of type 0 into 3 units of type 2 using `conversions[1]`.
* Convert a single unit of type 0 into 8 units of type 3 using `conversions[0]`, then `conversions[2]`.
* Convert a single unit of type 0 into 10 units of type 4 using `conversions[0]`, then `conversions[3]`.
* Convert a single unit of type 0 into 6 units of type 5 using `conversions[1]`, then `conversions[4]`.
* Convert a single unit of type 0 into 30 units of type 6 using `conversions[0]`, `conversions[3]`, then `conversions[5]`.
* Convert a single unit of type 0 into 24 units of type 7 using `conversions[1]`, `conversions[4]`, then `conversions[6]`.

**Constraints:**

* <code>2 <= n <= 10<sup>5</sup></code>
* `conversions.length == n - 1`
* <code>0 <= sourceUnit<sub>i</sub>, targetUnit<sub>i</sub> < n</code>
* <code>1 <= conversionFactor<sub>i</sub> <= 10<sup>9</sup></code>
* It is guaranteed that unit 0 can be converted into any other unit through a **unique** combination of conversions without using any conversions in the opposite direction.
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package g3501_3600.s3529_count_cells_in_overlapping_horizontal_and_vertical_substrings

// #Medium #Array #String #Matrix #Hash_Function #String_Matching #Rolling_Hash
// #2025_04_27_Time_51_ms_(100.00%)_Space_85.31_MB_(100.00%)

class Solution {
fun countCells(grid: Array<CharArray>, pattern: String): Int {
val k = pattern.length
val lps = makeLps(pattern)
val m = grid.size
val n = grid[0].size
val horiPats = Array(m) { IntArray(n) }
val vertPats = Array(m) { IntArray(n) }
var i = 0
var j = 0
while (i < m * n) {
if (grid[i / n][i % n] == pattern[j]) {
i++
if (++j == k) {
val d = i - j
horiPats[d / n][d % n] = horiPats[d / n][d % n] + 1
if (i < m * n) {
horiPats[i / n][i % n] = horiPats[i / n][i % n] - 1
}
j = lps[j - 1]
}
} else if (j != 0) {
j = lps[j - 1]
} else {
i++
}
}
i = 0
j = 0
// now do vert pattern, use i = 0 to m*n -1 but instead index as grid[i % m][i/m]
while (i < m * n) {
if (grid[i % m][i / m] == pattern[j]) {
i++
if (++j == k) {
val d = i - j
vertPats[d % m][d / m] = vertPats[d % m][d / m] + 1
if (i < m * n) {
vertPats[i % m][i / m] = vertPats[i % m][i / m] - 1
}
j = lps[j - 1]
}
} else if (j != 0) {
j = lps[j - 1]
} else {
i++
}
}
i = 1
while (i < m * n) {
vertPats[i % m][i / m] += vertPats[(i - 1) % m][(i - 1) / m]
horiPats[i / n][i % n] += horiPats[(i - 1) / n][(i - 1) % n]
i++
}
var res = 0
i = 0
while (i < m) {
j = 0
while (j < n) {
if (horiPats[i][j] > 0 && vertPats[i][j] > 0) {
res++
}
j++
}
i++
}
return res
}

private fun makeLps(pattern: String): IntArray {
val n = pattern.length
val lps = IntArray(n)
var len = 0
var i = 1
lps[0] = 0
while (i < n) {
if (pattern[i] == pattern[len]) {
lps[i++] = ++len
} else if (len != 0) {
len = lps[len - 1]
} else {
lps[i++] = 0
}
}
return lps
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
3529\. Count Cells in Overlapping Horizontal and Vertical Substrings

Medium

You are given an `m x n` matrix `grid` consisting of characters and a string `pattern`.

A **horizontal substring** is a contiguous sequence of characters read from left to right. If the end of a row is reached before the substring is complete, it wraps to the first column of the next row and continues as needed. You do **not** wrap from the bottom row back to the top.

A **vertical substring** is a contiguous sequence of characters read from top to bottom. If the bottom of a column is reached before the substring is complete, it wraps to the first row of the next column and continues as needed. You do **not** wrap from the last column back to the first.

Count the number of cells in the matrix that satisfy the following condition:

* The cell must be part of **at least** one horizontal substring and **at least** one vertical substring, where **both** substrings are equal to the given `pattern`.

Return the count of these cells.

**Example 1:**

![](https://assets.leetcode.com/uploads/2025/03/03/gridtwosubstringsdrawio.png)

**Input:** grid = [["a","a","c","c"],["b","b","b","c"],["a","a","b","a"],["c","a","a","c"],["a","a","c","c"]], pattern = "abaca"

**Output:** 1

**Explanation:**

The pattern `"abaca"` appears once as a horizontal substring (colored blue) and once as a vertical substring (colored red), intersecting at one cell (colored purple).

**Example 2:**

![](https://assets.leetcode.com/uploads/2025/03/03/gridexample2fixeddrawio.png)

**Input:** grid = [["c","a","a","a"],["a","a","b","a"],["b","b","a","a"],["a","a","b","a"]], pattern = "aba"

**Output:** 4

**Explanation:**

The cells colored above are all part of at least one horizontal and one vertical substring matching the pattern `"aba"`.

**Example 3:**

**Input:** grid = [["a"]], pattern = "a"

**Output:** 1

**Constraints:**

* `m == grid.length`
* `n == grid[i].length`
* `1 <= m, n <= 1000`
* <code>1 <= m * n <= 10<sup>5</sup></code>
* `1 <= pattern.length <= m * n`
* `grid` and `pattern` consist of only lowercase English letters.
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package g3501_3600.s3530_maximum_profit_from_valid_topological_order_in_dag

// #Hard #Array #Dynamic_Programming #Bit_Manipulation #Graph #Bitmask #Topological_Sort
// #2025_04_27_Time_833_ms_(100.00%)_Space_78.65_MB_(100.00%)

import kotlin.math.max

class Solution {
private fun helper(
mask: Int,
pos: Int,
inDegree: IntArray,
adj: List<List<Int>>,
score: IntArray,
dp: IntArray,
n: Int,
): Int {
if (mask == (1 shl n) - 1) {
return 0
}
if (dp[mask] != -1) {
return dp[mask]
}
var res = 0
for (i in 0..<n) {
if ((mask and (1 shl i)) == 0 && inDegree[i] == 0) {
for (ng in adj[i]) {
inDegree[ng]--
}
val `val` =
(
pos * score[i] +
helper(mask or (1 shl i), pos + 1, inDegree, adj, score, dp, n)
)
res = max(res, `val`)
for (ng in adj[i]) {
inDegree[ng]++
}
}
}
dp[mask] = res
return res
}

fun maxProfit(n: Int, edges: Array<IntArray>, score: IntArray): Int {
val adj: MutableList<MutableList<Int>> = ArrayList<MutableList<Int>>()
for (i in 0..<n) {
adj.add(ArrayList<Int>())
}
val inDegree = IntArray(n)
for (e in edges) {
adj[e[0]].add(e[1])
inDegree[e[1]]++
}
val dp = IntArray(1 shl n)
dp.fill(-1)
return helper(0, 1, inDegree, adj, score, dp, n)
}
}
Loading