LeetCode in Kotlin

1643. Kth Smallest Instructions

Hard

Bob is standing at cell (0, 0), and he wants to reach destination: (row, column). He can only travel right and down. You are going to help Bob by providing instructions for him to reach destination.

The instructions are represented as a string, where each character is either:

Multiple instructions will lead Bob to destination. For example, if destination is (2, 3), both "HHHVV" and "HVHVH" are valid instructions.

However, Bob is very picky. Bob has a lucky number k, and he wants the kth lexicographically smallest instructions that will lead him to destination. k is 1-indexed.

Given an integer array destination and an integer k, return the kth lexicographically smallest instructions that will take Bob to destination.

Example 1:

Input: destination = [2,3], k = 1

Output: “HHHVV”

Explanation: All the instructions that reach (2, 3) in lexicographic order are as follows: [“HHHVV”, “HHVHV”, “HHVVH”, “HVHHV”, “HVHVH”, “HVVHH”, “VHHHV”, “VHHVH”, “VHVHH”, “VVHHH”].

Example 2:

Input: destination = [2,3], k = 2

Output: “HHVHV”

Example 3:

Input: destination = [2,3], k = 3

Output: “HHVVH”

Constraints:

Solution

@Suppress("NAME_SHADOWING")
class Solution {
    fun kthSmallestPath(destination: IntArray, k: Int): String {
        var k = k
        val sb = StringBuilder()
        var v = destination[0]
        var n = v + destination[1]
        while (true) {
            val range = choose(--n, v)
            if (k <= range) {
                sb.append('H')
            } else {
                sb.append('V')
                v--
                k -= range
            }
            if (v == 0) {
                for (i in 1..n) {
                    sb.append('H')
                }
                break
            } else if (v == n) {
                for (i in 1..v) {
                    sb.append('V')
                }
                break
            }
        }
        return sb.toString()
    }

    private fun choose(n: Int, k: Int): Int {
        var k = k
        if (n - k < k) {
            k = n - k
        }
        var answer = 1
        for (i in 1..k) {
            answer = answer * (n + 1 - i) / i
        }
        return answer
    }
}