The task is:
A non-empty zero-indexed string S is given. String S consists of N characters from the set of upper-case English letters A, C, G, T.
<
I implemented a Segment Tree solution in Kotlin
import kotlin.math.*
fun solution(S: String, P: IntArray, Q: IntArray): IntArray {
val a = IntArray(S.length)
for (i in S.indices) {
a[i] = when (S[i]) {
'A' -> 1
'C' -> 2
'G' -> 3
'T' -> 4
else -> throw IllegalStateException()
}
}
val segmentTree = IntArray(2*nextPowerOfTwo(S.length)-1)
constructSegmentTree(a, segmentTree, 0, a.size-1, 0)
val result = IntArray(P.size)
for (i in P.indices) {
result[i] = rangeMinQuery(segmentTree, P[i], Q[i], 0, a.size-1, 0)
}
return result
}
fun constructSegmentTree(input: IntArray, segmentTree: IntArray, low: Int, high: Int, pos: Int) {
if (low == high) {
segmentTree[pos] = input[low]
return
}
val mid = (low + high)/2
constructSegmentTree(input, segmentTree, low, mid, 2*pos+1)
constructSegmentTree(input, segmentTree, mid+1, high, 2*pos+2)
segmentTree[pos] = min(segmentTree[2*pos+1], segmentTree[2*pos+2])
}
fun rangeMinQuery(segmentTree: IntArray, qlow:Int, qhigh:Int ,low:Int, high:Int, pos:Int): Int {
if (qlow <= low && qhigh >= high) {
return segmentTree[pos]
}
if (qlow > high || qhigh < low) {
return Int.MAX_VALUE
}
val mid = (low + high)/2
return min(rangeMinQuery(segmentTree, qlow, qhigh, low, mid, 2*pos+1), rangeMinQuery(segmentTree, qlow, qhigh, mid+1, high, 2*pos+2))
}
fun nextPowerOfTwo(n:Int): Int {
var count = 0
var number = n
if (number > 0 && (number and (number - 1)) == 0) return number
while (number != 0) {
number = number shr 1
count++
}
return 1 shl count
}