Skip to content

Commit d61c4a2

Browse files
authored
Added tasks 3324-3327
1 parent 10d4a1a commit d61c4a2

File tree

12 files changed

+441
-0
lines changed

12 files changed

+441
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package g3301_3400.s3324_find_the_sequence_of_strings_appeared_on_the_screen
2+
3+
// #Medium #String #Simulation #2024_10_22_Time_8_ms_(100.00%)_Space_62.7_MB_(29.63%)
4+
5+
class Solution {
6+
fun stringSequence(target: String): List<String> {
7+
val ans: MutableList<String> = ArrayList<String>()
8+
val l = target.length
9+
val cur = StringBuilder()
10+
for (i in 0 until l) {
11+
val tCh = target[i]
12+
cur.append('a')
13+
ans.add(cur.toString())
14+
while (cur[i] != tCh) {
15+
val lastCh = cur[i]
16+
val nextCh = (if (lastCh == 'z') 'a'.code else lastCh.code + 1).toChar()
17+
cur.setCharAt(i, nextCh)
18+
ans.add(cur.toString())
19+
}
20+
}
21+
return ans
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
3324\. Find the Sequence of Strings Appeared on the Screen
2+
3+
Medium
4+
5+
You are given a string `target`.
6+
7+
Alice is going to type `target` on her computer using a special keyboard that has **only two** keys:
8+
9+
* Key 1 appends the character `"a"` to the string on the screen.
10+
* Key 2 changes the **last** character of the string on the screen to its **next** character in the English alphabet. For example, `"c"` changes to `"d"` and `"z"` changes to `"a"`.
11+
12+
**Note** that initially there is an _empty_ string `""` on the screen, so she can **only** press key 1.
13+
14+
Return a list of _all_ strings that appear on the screen as Alice types `target`, in the order they appear, using the **minimum** key presses.
15+
16+
**Example 1:**
17+
18+
**Input:** target = "abc"
19+
20+
**Output:** ["a","aa","ab","aba","abb","abc"]
21+
22+
**Explanation:**
23+
24+
The sequence of key presses done by Alice are:
25+
26+
* Press key 1, and the string on the screen becomes `"a"`.
27+
* Press key 1, and the string on the screen becomes `"aa"`.
28+
* Press key 2, and the string on the screen becomes `"ab"`.
29+
* Press key 1, and the string on the screen becomes `"aba"`.
30+
* Press key 2, and the string on the screen becomes `"abb"`.
31+
* Press key 2, and the string on the screen becomes `"abc"`.
32+
33+
**Example 2:**
34+
35+
**Input:** target = "he"
36+
37+
**Output:** ["a","b","c","d","e","f","g","h","ha","hb","hc","hd","he"]
38+
39+
**Constraints:**
40+
41+
* `1 <= target.length <= 400`
42+
* `target` consists only of lowercase English letters.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package g3301_3400.s3325_count_substrings_with_k_frequency_characters_i
2+
3+
// #Medium #String #Hash_Table #Sliding_Window #2024_10_22_Time_3_ms_(88.00%)_Space_35.9_MB_(76.00%)
4+
5+
class Solution {
6+
fun numberOfSubstrings(s: String, k: Int): Int {
7+
var left = 0
8+
var result = 0
9+
val count = IntArray(26)
10+
for (i in 0 until s.length) {
11+
val ch = s[i]
12+
count[ch.code - 'a'.code]++
13+
14+
while (count[ch.code - 'a'.code] == k) {
15+
result += s.length - i
16+
val atLeft = s[left]
17+
count[atLeft.code - 'a'.code]--
18+
left++
19+
}
20+
}
21+
return result
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
3325\. Count Substrings With K-Frequency Characters I
2+
3+
Medium
4+
5+
Given a string `s` and an integer `k`, return the total number of substrings of `s` where **at least one** character appears **at least** `k` times.
6+
7+
**Example 1:**
8+
9+
**Input:** s = "abacb", k = 2
10+
11+
**Output:** 4
12+
13+
**Explanation:**
14+
15+
The valid substrings are:
16+
17+
* `"aba"` (character `'a'` appears 2 times).
18+
* `"abac"` (character `'a'` appears 2 times).
19+
* `"abacb"` (character `'a'` appears 2 times).
20+
* `"bacb"` (character `'b'` appears 2 times).
21+
22+
**Example 2:**
23+
24+
**Input:** s = "abcde", k = 1
25+
26+
**Output:** 15
27+
28+
**Explanation:**
29+
30+
All substrings are valid because every character appears at least once.
31+
32+
**Constraints:**
33+
34+
* `1 <= s.length <= 3000`
35+
* `1 <= k <= s.length`
36+
* `s` consists only of lowercase English letters.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package g3301_3400.s3326_minimum_division_operations_to_make_array_non_decreasing
2+
3+
// #Medium #Array #Math #Greedy #Number_Theory
4+
// #2024_10_22_Time_24_ms_(94.12%)_Space_64.2_MB_(64.71%)
5+
6+
import kotlin.math.max
7+
8+
class Solution {
9+
fun minOperations(nums: IntArray): Int {
10+
compute()
11+
var op = 0
12+
val n = nums.size
13+
for (i in n - 2 downTo 0) {
14+
while (nums[i] > nums[i + 1]) {
15+
if (SIEVE[nums[i]] == 0) {
16+
return -1
17+
}
18+
nums[i] /= SIEVE[nums[i]]
19+
op++
20+
}
21+
if (nums[i] > nums[i + 1]) {
22+
return -1
23+
}
24+
}
25+
return op
26+
}
27+
28+
companion object {
29+
private const val MAXI = 1000001
30+
private val SIEVE = IntArray(MAXI)
31+
private var precompute = false
32+
33+
private fun compute() {
34+
if (precompute) {
35+
return
36+
}
37+
for (i in 2 until MAXI) {
38+
if (i * i > MAXI) {
39+
break
40+
}
41+
var j = i * i
42+
while (j < MAXI) {
43+
SIEVE[j] =
44+
max(SIEVE[j], max(i, (j / i)))
45+
j += i
46+
}
47+
}
48+
precompute = true
49+
}
50+
}
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
3326\. Minimum Division Operations to Make Array Non Decreasing
2+
3+
Medium
4+
5+
You are given an integer array `nums`.
6+
7+
Any **positive** divisor of a natural number `x` that is **strictly less** than `x` is called a **proper divisor** of `x`. For example, 2 is a _proper divisor_ of 4, while 6 is not a _proper divisor_ of 6.
8+
9+
You are allowed to perform an **operation** any number of times on `nums`, where in each **operation** you select any _one_ element from `nums` and divide it by its **greatest** **proper divisor**.
10+
11+
Return the **minimum** number of **operations** required to make the array **non-decreasing**.
12+
13+
If it is **not** possible to make the array _non-decreasing_ using any number of operations, return `-1`.
14+
15+
**Example 1:**
16+
17+
**Input:** nums = [25,7]
18+
19+
**Output:** 1
20+
21+
**Explanation:**
22+
23+
Using a single operation, 25 gets divided by 5 and `nums` becomes `[5, 7]`.
24+
25+
**Example 2:**
26+
27+
**Input:** nums = [7,7,6]
28+
29+
**Output:** \-1
30+
31+
**Example 3:**
32+
33+
**Input:** nums = [1,1,1,1]
34+
35+
**Output:** 0
36+
37+
**Constraints:**
38+
39+
* <code>1 <= nums.length <= 10<sup>5</sup></code>
40+
* <code>1 <= nums[i] <= 10<sup>6</sup></code>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package g3301_3400.s3327_check_if_dfs_strings_are_palindromes
2+
3+
// #Hard #Array #String #Hash_Table #Depth_First_Search #Tree #Hash_Function
4+
// #2024_10_22_Time_165_ms_(100.00%)_Space_88.9_MB_(66.67%)
5+
6+
import kotlin.math.min
7+
8+
class Solution {
9+
private val e: MutableList<MutableList<Int?>?> = ArrayList<MutableList<Int?>?>()
10+
private val stringBuilder = StringBuilder()
11+
private var s: String? = null
12+
private var now = 0
13+
private var n = 0
14+
private lateinit var l: IntArray
15+
private lateinit var r: IntArray
16+
private lateinit var p: IntArray
17+
private lateinit var c: CharArray
18+
19+
private fun dfs(x: Int) {
20+
l[x] = now + 1
21+
for (v in e[x]!!) {
22+
dfs(v!!)
23+
}
24+
stringBuilder.append(s!![x])
25+
r[x] = ++now
26+
}
27+
28+
private fun matcher() {
29+
c[0] = '~'
30+
c[1] = '#'
31+
for (i in 1..n) {
32+
c[2 * i + 1] = '#'
33+
c[2 * i] = stringBuilder[i - 1]
34+
}
35+
var j = 1
36+
var mid = 0
37+
var localR = 0
38+
while (j <= 2 * n + 1) {
39+
if (j <= localR) {
40+
p[j] = min(p[(mid shl 1) - j], (localR - j + 1))
41+
}
42+
while (c[j - p[j]] == c[j + p[j]]) {
43+
++p[j]
44+
}
45+
if (p[j] + j > localR) {
46+
localR = p[j] + j - 1
47+
mid = j
48+
}
49+
++j
50+
}
51+
}
52+
53+
fun findAnswer(parent: IntArray, s: String): BooleanArray {
54+
n = parent.size
55+
this.s = s
56+
for (i in 0 until n) {
57+
e.add(ArrayList<Int?>())
58+
}
59+
for (i in 1 until n) {
60+
e[parent[i]]!!.add(i)
61+
}
62+
l = IntArray(n)
63+
r = IntArray(n)
64+
dfs(0)
65+
c = CharArray(2 * n + 10)
66+
p = IntArray(2 * n + 10)
67+
matcher()
68+
val ans = BooleanArray(n)
69+
for (i in 0 until n) {
70+
val mid = (2 * r[i] - 2 * l[i] + 1) / 2 + 2 * l[i]
71+
ans[i] = p[mid] - 1 >= r[i] - l[i] + 1
72+
}
73+
return ans
74+
}
75+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
3327\. Check if DFS Strings Are Palindromes
2+
3+
Hard
4+
5+
You are given a tree rooted at node 0, consisting of `n` nodes numbered from `0` to `n - 1`. The tree is represented by an array `parent` of size `n`, where `parent[i]` is the parent of node `i`. Since node 0 is the root, `parent[0] == -1`.
6+
7+
You are also given a string `s` of length `n`, where `s[i]` is the character assigned to node `i`.
8+
9+
Consider an empty string `dfsStr`, and define a recursive function `dfs(int x)` that takes a node `x` as a parameter and performs the following steps in order:
10+
11+
* Iterate over each child `y` of `x` **in increasing order of their numbers**, and call `dfs(y)`.
12+
* Add the character `s[x]` to the end of the string `dfsStr`.
13+
14+
**Note** that `dfsStr` is shared across all recursive calls of `dfs`.
15+
16+
You need to find a boolean array `answer` of size `n`, where for each index `i` from `0` to `n - 1`, you do the following:
17+
18+
* Empty the string `dfsStr` and call `dfs(i)`.
19+
* If the resulting string `dfsStr` is a **palindrome**, then set `answer[i]` to `true`. Otherwise, set `answer[i]` to `false`.
20+
21+
Return the array `answer`.
22+
23+
A **palindrome** is a string that reads the same forward and backward.
24+
25+
**Example 1:**
26+
27+
![](https://assets.leetcode.com/uploads/2024/09/01/tree1drawio.png)
28+
29+
**Input:** parent = [-1,0,0,1,1,2], s = "aababa"
30+
31+
**Output:** [true,true,false,true,true,true]
32+
33+
**Explanation:**
34+
35+
* Calling `dfs(0)` results in the string `dfsStr = "abaaba"`, which is a palindrome.
36+
* Calling `dfs(1)` results in the string `dfsStr = "aba"`, which is a palindrome.
37+
* Calling `dfs(2)` results in the string `dfsStr = "ab"`, which is **not** a palindrome.
38+
* Calling `dfs(3)` results in the string `dfsStr = "a"`, which is a palindrome.
39+
* Calling `dfs(4)` results in the string `dfsStr = "b"`, which is a palindrome.
40+
* Calling `dfs(5)` results in the string `dfsStr = "a"`, which is a palindrome.
41+
42+
**Example 2:**
43+
44+
![](https://assets.leetcode.com/uploads/2024/09/01/tree2drawio-1.png)
45+
46+
**Input:** parent = [-1,0,0,0,0], s = "aabcb"
47+
48+
**Output:** [true,true,true,true,true]
49+
50+
**Explanation:**
51+
52+
Every call on `dfs(x)` results in a palindrome string.
53+
54+
**Constraints:**
55+
56+
* `n == parent.length == s.length`
57+
* <code>1 <= n <= 10<sup>5</sup></code>
58+
* `0 <= parent[i] <= n - 1` for all `i >= 1`.
59+
* `parent[0] == -1`
60+
* `parent` represents a valid tree.
61+
* `s` consists only of lowercase English letters.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package g3301_3400.s3324_find_the_sequence_of_strings_appeared_on_the_screen
2+
3+
import org.hamcrest.CoreMatchers.equalTo
4+
import org.hamcrest.MatcherAssert.assertThat
5+
import org.junit.jupiter.api.Test
6+
7+
internal class SolutionTest {
8+
@Test
9+
fun stringSequence() {
10+
assertThat<List<String>>(
11+
Solution().stringSequence("abc"),
12+
equalTo<List<String>>(listOf<String>("a", "aa", "ab", "aba", "abb", "abc"))
13+
)
14+
}
15+
16+
@Test
17+
fun stringSequence2() {
18+
assertThat<List<String>>(
19+
Solution().stringSequence("he"),
20+
equalTo<List<String>>(
21+
listOf<String>(
22+
"a", "b", "c", "d", "e", "f", "g", "h", "ha", "hb", "hc", "hd",
23+
"he"
24+
)
25+
)
26+
)
27+
}
28+
}

0 commit comments

Comments
 (0)