列表

详情


1643. 第 K 条最小指令

Bob 站在单元格 (0, 0) ,想要前往目的地 destination(row, column) 。他只能向 或向 走。你可以为 Bob 提供导航 指令 来帮助他到达目的地 destination

指令 用字符串表示,其中每个字符:

能够为 Bob 导航到目的地 destination 的指令可以有多种,例如,如果目的地 destination(2, 3)"HHHVV""HVHVH" 都是有效 指令

然而,Bob 很挑剔。因为他的幸运数字是 k,他想要遵循 按字典序排列后的第 k 条最小指令 的导航前往目的地 destinationk  的编号 从 1 开始

给你一个整数数组 destination 和一个整数 k ,请你返回可以为 Bob 提供前往目的地 destination 导航的 按字典序排列后的第 k 条最小指令

 

示例 1:

输入:destination = [2,3], k = 1
输出:"HHHVV"
解释:能前往 (2, 3) 的所有导航指令 按字典序排列后 如下所示:
["HHHVV", "HHVHV", "HHVVH", "HVHHV", "HVHVH", "HVVHH", "VHHHV", "VHHVH", "VHVHH", "VVHHH"].

示例 2:

输入:destination = [2,3], k = 2
输出:"HHVHV"

示例 3:

输入:destination = [2,3], k = 3
输出:"HHVVH"

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: string kthSmallestPath(vector<int>& destination, int k) { } };

cpp 解法, 执行用时: 20 ms, 内存消耗: 16.5 MB, 提交时间: 2023-10-12 10:44:00

class Solution {
public:
    // 优先确定高位 + 组合计数
    string kthSmallestPath(vector<int>& destination, int k) {
        int h = destination[1];
        int v = destination[0];
        
        // 预处理组合数
        vector<vector<int>> comb(h + v, vector<int>(h));
        comb[0][0] = 1;
        for (int i = 1; i < h + v; ++i) {
            comb[i][0] = 1;
            for (int j = 1; j <= i && j < h; ++j) {
                comb[i][j] = comb[i - 1][j - 1] + comb[i - 1][j];
            }
        }
        
        string ans;
        for (int i = 0, imax = h + v; i < imax; ++i) {
            if (h > 0) {
                int o = comb[h + v - 1][h - 1];
                if (k > o) {
                    ans += 'V';
                    --v;
                    k -= o;
                }
                else {
                    ans += 'H';
                    --h;
                }
            }
            else {
                ans += 'V';
                --v;
            }
        }
        return ans;
    }
};

java 解法, 执行用时: 1 ms, 内存消耗: 40 MB, 提交时间: 2023-10-12 10:42:55

class Solution {
    public String kthSmallestPath(int[] destination, int k) {
        int rows = destination[0];
        int cols = destination[1];
        //字符"H"的数量
        int h = cols;
        //字符"V"的数量
        int v = rows;
        StringBuffer sb = new StringBuffer();
        //动态规划求解组合数量,乘法容易溢出
        int[][] dp = new int[h+v][h];
        dp[0][0] = 1;
        for(int i=1;i<h+v;i++){
            dp[i][0] = 1;
            for(int j=1;j<=i&&j<h;j++){
                dp[i][j] = dp[i-1][j-1] + dp[i-1][j];
            }
        }
        //依次求解各个位置的字符
        while(h>0 && v>0){
            int low = dp[h+v-1][h-1];
            if(k>low){
                sb.append("V");
                v--;
                k -= low; //更新k值
            }else{
                sb.append("H");
                h--;
            }
        }
        if(h==0){//如果"H"用完,则把剩余位置都是"V"
            for(int i=0;i<v;i++){
                sb.append("V");
            }
        }else{//如果"V"用完,则剩余位置都是"H"
            for(int i=0;i<h;i++){
                sb.append("H");
            }
        }
        return sb.toString();
    }
}

python3 解法, 执行用时: 48 ms, 内存消耗: 15.9 MB, 提交时间: 2023-10-12 10:41:14

class Solution:
    '''
    H V, 组合,全排列,
    '''
    def kthSmallestPath(self, destination: List[int], k: int) -> str:
        import math
        v, h = destination
        res = ''
        k -= 1
        while h and v and k:
            now = math.comb(h + v - 1, v)
            if now <= k:
                k -= now
                v -= 1
                res += "V"
            else:
                h -= 1
                res += "H"
        res += "H" * h + "V" * v
        return res

golang 解法, 执行用时: 0 ms, 内存消耗: 2.1 MB, 提交时间: 2023-10-12 10:38:56

func Num2Permu(V,n int) string {
	res := make([]byte,n)
	for i := 0; i < len(res); i ++ {
	    if (V >> (len(res)-i-1)) & 1 == 0 {
	        res[i] = 'H'
	    } else {
	        res[i] = 'V'
	    }
	} 
	return string(res)  
}

func kthSmallestPath(destination []int, k int) string {
	getIndex := func(V,H,K int) (int,int) {
		m,n := 0,1 
		for h := 0; h < H; h ++ {
			if K < n {
				return h, K-m
			}
			m = n
		    n = n*(V+h+1)/(h+1)
		}	
		return H,K-m
	}
	V,H := destination[0],destination[1]
	N,v,h := 0,V,H
	k --
	for {
		if v == 1{
			N |= (1 << k)
			break
		}
	    if k == 0 {
	    	N |= (1 << v) - 1
	        break
	    }
	    h,k = getIndex(v,h,k)
	    v --
	    N |= (1 << (h+v))
	}
	return Num2Permu(N,V+H)
}

golang 解法, 执行用时: 0 ms, 内存消耗: 2.1 MB, 提交时间: 2023-10-12 10:37:55

func kthSmallestPath(destination []int, k int) string {
    m, n := destination[0], destination[1]
    if m == 0 {
        return strings.Repeat("H", n)
    }
    if n == 0 {
        return strings.Repeat("V", m)
    }

    count := nCr(m + (n-1), m)

    if count >= k {
        destination[1]--
        return "H" + kthSmallestPath(destination, k)
    }
    destination[0]--
    return "V" + kthSmallestPath(destination, k - count)
}

func nCr(a, b int) int {
    if b > a - b {
        b = a - b
    }
    res := 1
    for i := 0; i < b; i++ {
        res *= (a-i)
        res /= (i+1)
    }
    return res
}

上一题