Skip to content

Commit 3aa902a

Browse files
committed
Improved tasks 1659, 3435
1 parent 19734f2 commit 3aa902a

File tree

3 files changed

+172
-137
lines changed
  • src/main/kotlin
    • g1601_1700/s1659_maximize_grid_happiness
    • g3401_3500/s3435_frequencies_of_shortest_supersequences

3 files changed

+172
-137
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2150,7 +2150,7 @@
21502150
| 3439 |[Reschedule Meetings for Maximum Free Time I](src/main/kotlin/g3401_3500/s3439_reschedule_meetings_for_maximum_free_time_i)| Medium | Array, Greedy, Sliding_Window | 5 | 80.00
21512151
| 3438 |[Find Valid Pair of Adjacent Digits in String](src/main/kotlin/g3401_3500/s3438_find_valid_pair_of_adjacent_digits_in_string)| Easy | String, Hash_Table, Counting | 2 | 93.18
21522152
| 3436 |[Find Valid Emails](src/main/kotlin/g3401_3500/s3436_find_valid_emails)| Easy | Database | 451 | 70.84
2153-
| 3435 |[Frequencies of Shortest Supersequences](src/main/kotlin/g3401_3500/s3435_frequencies_of_shortest_supersequences)| Hard | Array, String, Bit_Manipulation, Graph, Enumeration, Topological_Sort | 35 | 100.00
2153+
| 3435 |[Frequencies of Shortest Supersequences](src/main/kotlin/g3401_3500/s3435_frequencies_of_shortest_supersequences)| Hard | Array, String, Bit_Manipulation, Graph, Enumeration, Topological_Sort | 275 | 100.00
21542154
| 3434 |[Maximum Frequency After Subarray Operation](src/main/kotlin/g3401_3500/s3434_maximum_frequency_after_subarray_operation)| Medium | Array, Hash_Table, Dynamic_Programming, Greedy, Prefix_Sum | 51 | 100.00
21552155
| 3433 |[Count Mentions Per User](src/main/kotlin/g3401_3500/s3433_count_mentions_per_user)| Medium | Array, Math, Sorting, Simulation | 52 | 100.00
21562156
| 3432 |[Count Partitions with Even Sum Difference](src/main/kotlin/g3401_3500/s3432_count_partitions_with_even_sum_difference)| Easy | Array, Math, Prefix_Sum | 2 | 100.00
@@ -3539,7 +3539,7 @@
35393539
| 1663 |[Smallest String With A Given Numeric Value](src/main/kotlin/g1601_1700/s1663_smallest_string_with_a_given_numeric_value)| Medium | String, Greedy | 202 | 100.00
35403540
| 1662 |[Check If Two String Arrays are Equivalent](src/main/kotlin/g1601_1700/s1662_check_if_two_string_arrays_are_equivalent)| Easy | Array, String | 144 | 86.84
35413541
| 1661 |[Average Time of Process per Machine](src/main/kotlin/g1601_1700/s1661_average_time_of_process_per_machine)| Easy | Database | 429 | 71.35
3542-
| 1659 |[Maximize Grid Happiness](src/main/kotlin/g1601_1700/s1659_maximize_grid_happiness)| Hard | Dynamic_Programming, Bit_Manipulation, Bitmask, Memoization | 181 | 100.00
3542+
| 1659 |[Maximize Grid Happiness](src/main/kotlin/g1601_1700/s1659_maximize_grid_happiness)| Hard | Dynamic_Programming, Bit_Manipulation, Bitmask, Memoization | 44 | 100.00
35433543
| 1658 |[Minimum Operations to Reduce X to Zero](src/main/kotlin/g1601_1700/s1658_minimum_operations_to_reduce_x_to_zero)| Medium | Array, Hash_Table, Binary_Search, Prefix_Sum, Sliding_Window | 532 | 50.00
35443544
| 1657 |[Determine if Two Strings Are Close](src/main/kotlin/g1601_1700/s1657_determine_if_two_strings_are_close)| Medium | String, Hash_Table, Sorting | 287 | 100.00
35453545
| 1656 |[Design an Ordered Stream](src/main/kotlin/g1601_1700/s1656_design_an_ordered_stream)| Easy | Array, Hash_Table, Design, Data_Stream | 487 | 91.67

src/main/kotlin/g1601_1700/s1659_maximize_grid_happiness/readme.md

Lines changed: 95 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -70,79 +70,111 @@ The grid happiness is 90 + 80 + 90 = 260.
7070
## Solution
7171

7272
```kotlin
73-
class Solution {
74-
private var m = 0
75-
private var n = 0
76-
private lateinit var dp: Array<Array<Array<Array<IntArray>>>>
77-
private val notPlace = 0
78-
private val intro = 1
79-
private val extro = 2
80-
private var mod = 0
73+
import kotlin.math.max
8174

82-
fun getMaxGridHappiness(m: Int, n: Int, introvertsCount: Int, extrovertsCount: Int): Int {
83-
this.m = m
84-
this.n = n
85-
val numOfState = Math.pow(3.0, n.toDouble()).toInt()
86-
dp = Array(m) {
87-
Array(n) {
88-
Array(introvertsCount + 1) {
89-
Array(extrovertsCount + 1) { IntArray(numOfState) }
90-
}
91-
}
75+
@Suppress("kotlin:S107")
76+
class Solution {
77+
private fun maxHappiness(
78+
index: Int,
79+
m: Int,
80+
n: Int,
81+
introverts: Int,
82+
extroverts: Int,
83+
board: Int,
84+
dp: Array<Array<Array<IntArray>>>,
85+
tmask: Int,
86+
): Int {
87+
if (index >= m * n) {
88+
return 0
89+
}
90+
if (dp[index][introverts][extroverts][board] != 0) {
91+
return dp[index][introverts][extroverts][board]
92+
}
93+
var introScore = -1
94+
var extroScore = -1
95+
if (introverts > 0) {
96+
val newBoard = ((board shl 2) or INTROVERT) and tmask
97+
introScore =
98+
(
99+
120 +
100+
adjust(board, INTROVERT, n, index) +
101+
maxHappiness(
102+
index + 1,
103+
m,
104+
n,
105+
introverts - 1,
106+
extroverts,
107+
newBoard,
108+
dp,
109+
tmask,
110+
)
111+
)
112+
}
113+
if (extroverts > 0) {
114+
val newBoard = ((board shl 2) or EXTROVERT) and tmask
115+
extroScore =
116+
(
117+
40 +
118+
adjust(board, EXTROVERT, n, index) +
119+
maxHappiness(
120+
index + 1,
121+
m,
122+
n,
123+
introverts,
124+
extroverts - 1,
125+
newBoard,
126+
dp,
127+
tmask,
128+
)
129+
)
92130
}
93-
mod = numOfState / 3
94-
return dfs(0, 0, introvertsCount, extrovertsCount, 0)
131+
val newBoard = ((board shl 2) or NONE) and tmask
132+
val skip = maxHappiness(index + 1, m, n, introverts, extroverts, newBoard, dp, tmask)
133+
dp[index][introverts][extroverts][board] =
134+
max(skip, max(introScore, extroScore))
135+
return dp[index][introverts][extroverts][board]
95136
}
96137

97-
private fun dfs(x: Int, y: Int, ic: Int, ec: Int, state: Int): Int {
98-
if (x == m) {
99-
return 0
100-
} else if (y == n) {
101-
return dfs(x + 1, 0, ic, ec, state)
102-
}
103-
if (dp[x][y][ic][ec][state] != 0) {
104-
return dp[x][y][ic][ec][state]
138+
private fun adjust(board: Int, thisIs: Int, col: Int, index: Int): Int {
139+
val shiftBy = 2 * (col - 1)
140+
var left = board and 0x03
141+
if (index % col == 0) {
142+
left = NONE
105143
}
106-
// 1 - not place
107-
var max = dfs(x, y + 1, ic, ec, state % mod * 3)
108-
val up = state / mod
109-
val left = state % 3
110-
// 2 - place intro
111-
if (ic > 0) {
112-
var temp = 120
113-
if (x > 0 && up != notPlace) {
114-
temp -= 30
115-
temp += if (up == intro) -30 else 20
144+
val up = (board shr shiftBy) and 0x03
145+
val combination = intArrayOf(left, up)
146+
var adjustment = 0
147+
for (neighbor in combination) {
148+
if (neighbor == NONE) {
149+
continue
116150
}
117-
if (y > 0 && left != notPlace) {
118-
temp -= 30
119-
temp += if (left == intro) -30 else 20
151+
if (neighbor == INTROVERT && thisIs == INTROVERT) {
152+
adjustment -= 60
153+
} else if (neighbor == INTROVERT && thisIs == EXTROVERT) {
154+
adjustment -= 10
155+
} else if (neighbor == EXTROVERT && thisIs == INTROVERT) {
156+
adjustment -= 10
157+
} else if (neighbor == EXTROVERT && thisIs == EXTROVERT) {
158+
adjustment += 40
120159
}
121-
var nextState = state
122-
nextState %= mod
123-
nextState *= 3
124-
nextState += intro
125-
max = Math.max(max, temp + dfs(x, y + 1, ic - 1, ec, nextState))
126160
}
127-
// 3 - place extro
128-
if (ec > 0) {
129-
var temp = 40
130-
if (x > 0 && up != notPlace) {
131-
temp += 20
132-
temp += if (up == intro) -30 else 20
133-
}
134-
if (y > 0 && left != notPlace) {
135-
temp += 20
136-
temp += if (left == intro) -30 else 20
161+
return adjustment
162+
}
163+
164+
fun getMaxGridHappiness(m: Int, n: Int, introvertsCount: Int, extrovertsCount: Int): Int {
165+
val dp = Array<Array<Array<IntArray>>>(m * n) {
166+
Array<Array<IntArray>>(introvertsCount + 1) {
167+
Array<IntArray>(extrovertsCount + 1) { IntArray((1 shl (2 * n))) }
137168
}
138-
var nextState = state
139-
nextState %= mod
140-
nextState *= 3
141-
nextState += extro
142-
max = Math.max(max, temp + dfs(x, y + 1, ic, ec - 1, nextState))
143169
}
144-
dp[x][y][ic][ec][state] = max
145-
return max
170+
val tmask = (1 shl (2 * n)) - 1
171+
return maxHappiness(0, m, n, introvertsCount, extrovertsCount, 0, dp, tmask)
172+
}
173+
174+
companion object {
175+
private const val NONE = 0
176+
private const val INTROVERT = 1
177+
private const val EXTROVERT = 2
146178
}
147179
}
148180
```

src/main/kotlin/g3401_3500/s3435_frequencies_of_shortest_supersequences/readme.md

Lines changed: 75 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -58,100 +58,103 @@ The two SCSs are `"aac"` and `"aca"`. Since they are permutations of each other,
5858

5959
```kotlin
6060
class Solution {
61-
private var m = 0
62-
private var forcedMask = 0
63-
private lateinit var adj: IntArray
64-
private val idxToChar = CharArray(26)
65-
private val charToIdx = IntArray(26)
66-
private val used = BooleanArray(26)
61+
private var min = Int.Companion.MAX_VALUE
62+
private var lists: MutableList<IntArray> = ArrayList<IntArray>()
6763

6864
fun supersequences(words: Array<String>): List<List<Int>> {
69-
charToIdx.fill(-1)
70-
for (w in words) {
71-
used[w[0].code - 'a'.code] = true
72-
used[w[1].code - 'a'.code] = true
65+
val pairs = Array<BooleanArray>(26) { BooleanArray(26) }
66+
val counts = IntArray(26)
67+
for (word in words) {
68+
val a = word[0].code - 'a'.code
69+
val b = word[1].code - 'a'.code
70+
if (!pairs[a][b]) {
71+
pairs[a][b] = true
72+
counts[a]++
73+
counts[b]++
74+
}
7375
}
74-
// Map each used letter to an index [0..m-1]
75-
for (c in 0..25) {
76-
if (used[c]) {
77-
idxToChar[m] = (c + 'a'.code).toChar()
78-
charToIdx[c] = m++
76+
val links: Array<ArrayList<Int>> = Array<ArrayList<Int>>(26) { ArrayList<Int>() }
77+
val counts1 = IntArray(26)
78+
val sides = IntArray(26)
79+
for (i in 0..25) {
80+
for (j in 0..25) {
81+
if (pairs[i][j]) {
82+
links[i].add(j)
83+
counts1[j]++
84+
sides[i] = sides[i] or 1
85+
sides[j] = sides[j] or 2
86+
}
7987
}
8088
}
81-
adj = IntArray(m)
82-
// Build graph and record forced duplicates
83-
for (w in words) {
84-
val u = charToIdx[w[0].code - 'a'.code]
85-
val v = charToIdx[w[1].code - 'a'.code]
86-
if (u == v) {
87-
forcedMask = forcedMask or (1 shl u)
89+
val arr = IntArray(26)
90+
for (i in 0..25) {
91+
if (counts[i] <= 1) {
92+
arr[i] = counts[i]
93+
} else if (counts1[i] == 0 || sides[i] != 3) {
94+
arr[i] = 1
95+
} else if (pairs[i][i]) {
96+
arr[i] = 2
8897
} else {
89-
adj[u] = adj[u] or (1 shl v)
98+
arr[i] = -1
9099
}
91100
}
92-
// Try all supersets of forcedMask; keep those that kill all cycles
93-
var best = 9999
94-
val goodSets: MutableList<Int> = ArrayList<Int>()
95-
for (s in 0..<(1 shl m)) {
96-
if ((s and forcedMask) != forcedMask) {
97-
continue
98-
}
99-
val size = Integer.bitCount(s)
100-
if (size <= best && !hasCycle(s)) {
101-
if (size < best) {
102-
best = size
103-
goodSets.clear()
104-
}
105-
goodSets.add(s)
101+
dfs(links, 0, arr, IntArray(26), 0)
102+
val res: MutableList<MutableList<Int>> = ArrayList<MutableList<Int>>()
103+
for (arr1 in lists) {
104+
val list: MutableList<Int> = ArrayList<Int>()
105+
for (n in arr1) {
106+
list.add(n)
106107
}
108+
res.add(list)
109+
}
110+
return res
111+
}
112+
113+
private fun dfs(links: Array<ArrayList<Int>>, i: Int, arr1: IntArray, arr: IntArray, n: Int) {
114+
if (n > min) {
115+
return
107116
}
108-
// Build distinct freq arrays from these sets
109-
val seen: MutableSet<String> = HashSet<String>()
110-
val ans: MutableList<MutableList<Int>> = ArrayList<MutableList<Int>>()
111-
for (s in goodSets) {
112-
val freq = IntArray(26)
113-
for (i in 0..<m) {
114-
freq[idxToChar[i].code - 'a'.code] = if ((s and (1 shl i)) != 0) 2 else 1
117+
if (i == 26) {
118+
if (!chk(links, arr)) {
119+
return
115120
}
116-
val key = freq.contentToString()
117-
if (seen.add(key)) {
118-
val tmp: MutableList<Int> = ArrayList<Int>()
119-
for (f in freq) {
120-
tmp.add(f)
121-
}
122-
ans.add(tmp)
121+
if (n < min) {
122+
min = n
123+
lists = ArrayList<IntArray>()
124+
lists.add(arr.clone())
125+
} else if (n == min) {
126+
lists.add(arr.clone())
123127
}
128+
return
129+
}
130+
if (arr1[i] >= 0) {
131+
arr[i] = arr1[i]
132+
dfs(links, i + 1, arr1, arr, n + arr1[i])
133+
} else {
134+
arr[i] = 1
135+
dfs(links, i + 1, arr1, arr, n + 1)
136+
arr[i] = 2
137+
dfs(links, i + 1, arr1, arr, n + 2)
124138
}
125-
return ans
126139
}
127140

128-
private fun hasCycle(mask: Int): Boolean {
129-
val color = IntArray(m)
130-
for (i in 0..<m) {
131-
if (((mask shr i) and 1) == 0 && color[i] == 0 && dfs(i, color, mask)) {
132-
return true
141+
private fun chk(links: Array<ArrayList<Int>>, arr: IntArray): Boolean {
142+
for (i in 0..25) {
143+
if (arr[i] == 1 && dfs1(links, arr, BooleanArray(26), i)) {
144+
return false
133145
}
134146
}
135-
return false
147+
return true
136148
}
137149

138-
private fun dfs(u: Int, color: IntArray, mask: Int): Boolean {
139-
color[u] = 1
140-
var nxt = adj[u]
141-
while (nxt != 0) {
142-
val v = Integer.numberOfTrailingZeros(nxt)
143-
nxt = nxt and (nxt - 1)
144-
if (((mask shr v) and 1) == 1) {
145-
continue
146-
}
147-
if (color[v] == 1) {
148-
return true
149-
}
150-
if (color[v] == 0 && dfs(v, color, mask)) {
150+
private fun dfs1(links: Array<ArrayList<Int>>, arr: IntArray, seens: BooleanArray, i: Int): Boolean {
151+
seens[i] = true
152+
for (next in links[i]) {
153+
if (arr[next] == 1 && (seens[next] || dfs1(links, arr, seens, next))) {
151154
return true
152155
}
153156
}
154-
color[u] = 2
157+
seens[i] = false
155158
return false
156159
}
157160
}

0 commit comments

Comments
 (0)