【问题标题】:Maxsubsequence - What are the key insights for this problem?Maxsubsequence - 这个问题的关键见解是什么?
【发布时间】:2020-12-12 15:24:57
【问题描述】:

以下是使用树递归方法的问题分配:

最大子序列 数字的子序列是数字的一系列(不一定是连续的)数字。例如,12345 的子序列包括 123、234、124、245 等。您的任务是获取低于一定长度的最大子序列。

def max_subseq(n, l):
    """
    Return the maximum subsequence of length at most l that can be found in the given number n.
    For example, for n = 20125 and l = 3, we have that the subsequences are
        2
        0
        1
        2
        5
        20
        21
        22
        25
        01
        02
        05
        12
        15
        25
        201
        202
        205
        212
        215
        225
        012
        015
        025
        125
    and of these, the maxumum number is 225, so our answer is 225.

    >>> max_subseq(20125, 3)
    225
    >>> max_subseq(20125, 5)
    20125
    >>> max_subseq(20125, 6) # note that 20125 == 020125
    20125
    >>> max_subseq(12345, 3)
    345
    >>> max_subseq(12345, 0) # 0 is of length 0
    0
    >>> max_subseq(12345, 1)
    5
    """
    "*** YOUR CODE HERE ***"

这个问题有两个关键的见解

  • 您需要区分使用个位和不使用的情况。在它是的情况下,我们想要减少 l,因为我们使用了其中一个数字,而在它不是的情况下,我们不这样做。
  • 在我们使用个位的情况下,您需要将数字放回末尾,将数字d附加到数字n的末尾的方法是10 * n + d。

看不懂这个问题的见解,下面提到2点:

  1. 分为使用个位和不使用个位的情况

  2. 如果我们使用个位数,你需要把数字放回末尾


我对这个问题的理解:

这个问题的解决方案看起来生成所有子序列到l,伪代码如下:

digitSequence := strconv.Itoa(n) // "20125"

printSubSequence = func(digitSequence string, currenSubSequenceSize int) { // digitSequence is "20125" and currenSubSequenceSize is say 3
        printNthSubSequence(digitSequence, currenSubSequenceSize) + printSubSequence(digitSequence, currenSubSequenceSize-1)
    }

其中printNthSubSequence 打印(20125, 3) 或(20125, 2) 等的子序列...

在所有这些序列中找到max_subseq 变得很容易


你能通过一个例子帮助我理解这个问题中给出的见解吗(比如20125, 1)? here 是完整的问题

【问题讨论】:

    标签: go recursion divide-and-conquer


    【解决方案1】:

    这样的?按照说明建议,尝试使用和不使用当前数字:

    function f(s, i, l){
      if (i + 1 <= l)
        return Number(s.substr(0, l));
    
      if (!l)
        return 0;
        
      return Math.max(
        // With
        Number(s[i]) + 10 * f(s, i - 1, l - 1),
        // Without
        f(s, i - 1, l)
      );
    }
    
    var input = [
      ['20125', 3],
      ['20125', 5],
      ['20125', 6],
      ['12345', 3],
      ['12345', 0],
      ['12345', 1]
    ];
    
    for (let [s, l] of input){
      console.log(s + ', l: ' + l);
      console.log(f(s, s.length-1, l));
      console.log('');
    }

    【讨论】:

    • 我没有得到带案例: Number(s[i]) + 10 * f(s, i - 1, l - 1)
    • @overexchange Number(s[i]) 是我们尝试从字符转换为数字的数字。我们想把它附加到一个数字“前缀”上,这是递归的结果。但是前缀需要向左“移动”一次,以便我们以数字方式附加数字。我们通过将前缀乘以 10 来实现这种转变。
    • 这个基本案例的目的是什么? if (i + 1 &lt;= l)
    • @overexchange (i + 1 == l) 表示当前字符串的长度(ith 索引加 1)等于 l 所以位数少于整个字符串长度的数字只能更小,所以我们将整个字符串作为数字返回。但说明也给出了字符串小于l 的示例,在前面加上零,因此是&lt;=。我会发布一个关于获取特定长度的所有子序列的单独问题。
    • 如果这段代码需要打印所有大小为 3 的子序列,它会是什么样子?而不是找到大小为 3 的最大子序列
    猜你喜欢
    • 2016-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-03
    • 1970-01-01
    • 2019-11-14
    • 1970-01-01
    相关资源
    最近更新 更多