首页 > 其他分享 >LeetCode 1643. 第 K 条最小指令

LeetCode 1643. 第 K 条最小指令

时间:2023-04-25 22:25:23浏览次数:42  
标签:1643 ed sum destination st 指令 aligned LeetCode 康托

康托展开

一开始无脑枚举全排列, 果断超时, 还是得看看如果降低计算量。

题目destination = [2,3], 相当于2个V, 3个H, 输出全排列去重后的对应位置字典序列内容。

忽略去重

则问题为全排列, 所有可能为:

\[(\sum destination)! = (2+3)! = 5! \]

k恰好为康托展开结果+1, 直接逆向还原排列。

为了偷懒, 下标从最大值递减, k相比原值-1。
HHVHV对应的康托展开为:

\[k = \sum_{i=4}^{1} (n_i*i!) \]

\(n_i\)为后续小于当前元素的数量, 由于题目只有2种元素, 将原始表达式稍加改造

定义\(v_i\) \(h_i\)为从当前位置往右, 剩余的VH对应数量, 其总量分别定义为V H

则在无去重情况下的表达式为:

\[\begin{aligned} k &= \sum (h_i*i!) \\ &= \sum (h_i*(v_i+h_i-1)!) \\ \end{aligned} \]

其中i ∈ (0, V+H), 且 \(n_i\) = V

H不存在小于它的项, 因此只关注V

考虑去重

此时表达式与题意只相差相同元素的去重, 根据排列组合知识, \(v_i\)个V提供\(v_i!\)种排列, \(h_i\)个H提供\(h_i!\)种排列。

将上述原始的康托展开去掉重复项就能得到最终表达式:

(为了观感, \(x_i\)替换为\(x\))

\[\begin{aligned} k &= \sum \frac{h*(v+h-1)!}{v!*h!} \\ &= \sum \frac{h* \Pi_{j=h+1}^{v+h-1} j}{v!} \\ &= \sum \frac{\Pi_{j=h}^{v+h-1} j}{v!} \end{aligned} \]

还原时从前往后, 计算将V放置在当前位置后提供的k值是否溢出, 生成最终输出。过程与逆康托展开一致。

中途连乘计算可能越界, 没想出足够优雅的处理方法, 转Double摆烂了。

Kotlin

private val cache = Array(30) { Array<Double?>(30) { null } }
private fun pai(st: Int, ed: Int): Double = cache[st][ed] ?: run {
    val v = if (st == ed) st.toDouble() else pai(st, ed - 1) * ed.toDouble()
    cache[st][ed] = v
    return@run v
}

class Solution {

    fun kthSmallestPath(destination: IntArray, k: Int): String {
        var currentK = 0
        return String(CharArray(destination.sum()) {
            val (v, h) = destination
            if (v <= 0) return@CharArray 'H'
            if (h <= 0) return@CharArray 'V'

            val n = (pai(h, v + h - 1) / pai(1, v)).toInt()
            if (n + currentK < k) {
                currentK += n
                destination[0] -= 1
                return@CharArray 'V'
            }

            destination[1] -= 1
            return@CharArray 'H'
        })
    }
}

标签:1643,ed,sum,destination,st,指令,aligned,LeetCode,康托
From: https://www.cnblogs.com/Simon-X/p/17354118.html

相关文章

  • leetcode调研version0
     这是我第一次发博客,所以许多功能还不太会使用。前几次的随笔既当作记录,也当作自己的练习。 最近想要刷leetcode,纠结用哪种语言(我自己学过c/c++,python,fortran,Java),所以前期做了一些调研,在此记录一下。 c语言: 网址:https://github.com/begeekmyfriend/leetcode ......
  • leetcode 607 銷售員
    銷售員 selects.`name`fromsalespersonsleftjoinordersoons.sales_id=o.sales_idleftjoincompanycono.com_id=c.com_idandc.name='RED'groupbys.sales_idhavingcount(c.`name`)=0 ===selects.`name`fromsalespersonswheres.sa......
  • 【DP】LeetCode 213. 打家劫舍 II
    题目链接213.打家劫舍II思路分析动态规划题目的时候只需要考虑最后一个阶段,因为所有的阶段转化都是相同的,考虑最后一个阶段容易发现规律在数组的动态规划问题中,一般dp[i]都是表示以nums以前i个元素组成(即nums[i-1])的状态;dp[i][j]分别表示以nums1前i个元素(即n......
  • leetcode 570 至少有5名直接下屬的經理
    至少有5名直接下屬的經理 子查詢select`name`fromEmployeewhereidin(selectmanagerIdfromEmployeegroupbymanagerIdhavingcount(managerId)>=5) 自連接selecte2.namefromEmployeee1,Employeee2wheree1.managerId=e2.idgr......
  • [LeetCode] 1342. Number of Steps to Reduce a Number to Zero 将数字变成 0 的操作
    Givenaninteger num,return thenumberofstepstoreduceittozero.Inonestep,ifthecurrentnumberiseven,youhavetodivideitby 2,otherwise,youhavetosubtract 1 fromit.Example1:Input:num=14Output:6Explanation: Step1)14ise......
  • LeetCode 131.分割回文串
    1.题目:给你一个字符串s,请你将s分割成一些子串,使每个子串都是回文串。返回s所有可能的分割方案。回文串是正着读和反着读都一样的字符串。示例1:输入:s="aab"输出:[["a","a","b"],["aa","b"]]示例2:输入:s="a"输出:[["a"]]来源:力扣(LeetCode)链接:https......
  • 【DP】LeetCode 198. 打家劫舍
    题目链接198.打家劫舍思路分析动态规划题目的时候只需要考虑最后一个阶段,因为所有的阶段转化都是相同的,考虑最后一个阶段容易发现规律在数组的动态规划问题中,一般dp[i]都是表示以nums以前i个元素组成(即nums[i-1])的状态;dp[i][j]分别表示以nums1前i个元素(即nums......
  • leetcode(2)
    Given n pointsona2Dplane,findthemaximumnumberofpointsthatlieonthesamestraightline.在一条直线上最多的点。理解错了:理解成一条直线上距离最长的点(自己见过类似题,务必审题要细!!!!)4.1hash_map和map的区别在哪里?构造函数。hash_map需要hash函数,......
  • 【DP】LeetCode 1277. 统计全为 1 的正方形子矩阵
    题目链接1277.统计全为1的正方形子矩阵思路分析动态规划题目的时候只需要考虑最后一个阶段,因为所有的阶段转化都是相同的,考虑最后一个阶段容易发现规律在数组的动态规划问题中,一般dp[i]都是表示以nums以前i个元素组成(即nums[i-1])的状态;dp[i][j]分别表示以nums1......
  • 【LeetCode动态规划#12】详解买卖股票I~IV,经典dp题型
    买卖股票的最佳时机力扣题目链接(opensnewwindow)给定一个数组prices,它的第i个元素prices[i]表示一支给定股票第i天的价格。你只能选择某一天买入这只股票,并选择在未来的某一个不同的日子卖出该股票。设计一个算法来计算你所能获取的最大利润。返回你可以从这笔......