Medium
You are given a deck of cards represented by a string array cards, and each card displays two lowercase letters.
You are also given a letter x. You play a game with the following rules:
x in any position.Return the maximum number of points you can gain with optimal play.
Two cards are compatible if the strings differ in exactly 1 position.
Example 1:
Input: cards = [“aa”,”ab”,”ba”,”ac”], x = “a”
Output: 2
Explanation:
"ab" and "ac", which are compatible because they differ at only index 1."aa" and "ba", which are compatible because they differ at only index 0.Because there are no more compatible pairs, the total score is 2.
Example 2:
Input: cards = [“aa”,”ab”,”ba”], x = “a”
Output: 1
Explanation:
"aa" and "ba".Because there are no more compatible pairs, the total score is 1.
Example 3:
Input: cards = [“aa”,”ab”,”ba”,”ac”], x = “b”
Output: 0
Explanation:
The only cards that contain the character 'b' are "ab" and "ba". However, they differ in both indices, so they are not compatible. Thus, the output is 0.
Constraints:
2 <= cards.length <= 105cards[i].length == 2cards[i] is composed of only lowercase English letters between 'a' and 'j'.x is a lowercase English letter between 'a' and 'j'.import kotlin.math.min
class Solution {
fun score(cards: Array<String>, x: Char): Int {
// store input midway as required
// counts for "x?" group by second char and "?x" group by first char
val left = IntArray(10)
val right = IntArray(10)
var xx = 0
for (c in cards) {
val a = c[0]
val b = c[1]
if (a == x && b == x) {
xx++
} else if (a == x) {
left[b.code - 'a'.code]++
} else if (b == x) {
right[a.code - 'a'.code]++
}
}
// max pairs inside a group where pairs must come from different buckets:
// pairs = min(total/2, total - maxBucket)
var l = 0
var maxL = 0
for (v in left) {
l += v
if (v > maxL) {
maxL = v
}
}
var r = 0
var maxR = 0
for (v in right) {
r += v
if (v > maxR) {
maxR = v
}
}
val pairsLeft = min(l / 2, l - maxL)
val pairsRight = min(r / 2, r - maxR)
// leftovers after internal pairing
val leftoverL = l - 2 * pairsLeft
val leftoverR = r - 2 * pairsRight
val leftovers = leftoverL + leftoverR
// First, use "xx" to pair with any leftovers
val useWithXX = min(xx, leftovers)
val xxLeft = xx - useWithXX
// If "xx" still remain, we can break existing internal pairs:
// breaking 1 internal pair frees 2 cards, which can pair with 2 "xx" to gain +1 net point
val extraByBreaking = min(xxLeft / 2, pairsLeft + pairsRight)
return pairsLeft + pairsRight + useWithXX + extraByBreaking
}
}