微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

按升序连接N个数组排序元素形成的第K个元素

如何解决按升序连接N个数组排序元素形成的第K个元素

给定一个长度为 N 的字符串 S。字符串 S 由 1-9 的数字组成。考虑字符串索引是基于 1 的。 您需要将字符串分成多个块,以便第 ith 块包含从 index((i-1) * X + 1) 到 min(N,(i * X) (两者都包含)。如果一个数字是有效,如果它是通过从每个块中选择一个数字并将这些数字按块编号的顺序排列形成的。

例如:

如果给定的字符串是 '123456789' 并且 X = 3,则形成的块是 [123],[456],[789]。少数有效数字为 146,159,348 等,但 124 和 396 无效。

在所有可以形成的有效数字中,如果所有唯一有效数字,我必须确定Kth数字数字按升序排列。

我的想法是对每个块进行排序,然后找出哪个数字将成为 Kth 个数字。 但是我被困在如何用数学方法或任何其他方法来查找 Kth 元素。

def getK(N:int,X:int,K:int,S:str):
    from math import ceil
    i = 1
    N = len(S)
    S = list(S)
    while i <= ceil(N / X):
        start = (i - 1) * X
        end = min(N,i * X) - 1
        S[start:end+1] = sorted(S[start:end+1])
        print(S[start:end+1])
        i += 1
    print(S)

请帮我找出解决这个问题的方法

解决方法

首先将字符串分成块:

132 | 444 | 675 | 89

注意最后一个块可能少于 X 个数字*。另请注意,无论您从第二个块中选择哪个数字,它始终是 4。对块进行排序并清除重复项**:

123 | 4 | 567 | 89

现在,当您按顺序枚举可能的数字时:

1458
1459
1468
1469
1478
1479
2458
...

你可以观察到一个模式:

  • 最后一位数字以 1 的频率变化,即:每转一次。
  • 倒数第二个数字以 2 的频率变化,这是最后一个块的“循环长度”。
  • 如果还有任何其他数字要更改为,则第三个但最后一个数字的更改频率为 6。六是最后两个块组合的循环长度。
  • 第一位数字以 6 的频率变化,这是最后三个块的组合循环长度。

因此,计算唯一块的长度:

3 | 1 | 3 | 2

对于每个块,找到从该块到最后的计数的乘积:

18 | 6 | 6 | 2

第一个数字是组合的总数,N。如果 k > N,则表示失败。 (返回 None 或引发异常。)否则,将其从数组中弹出并在末尾添加 1。现在您有了每个数字的“更新频率”:

6 | 6 | 2 | 1

现在,让 k 成为一个从零开始的索引,K = k − 1,因为它使计算更容易。假设 K = 8:

  • 第一个数字随着第 6 个数字的变化而变化。 K div 6 = 1,这是要从第一个块中选取的数字的从零开始的索引:“2”。取该除法的剩余部分:KK mod 6.
  • 第二位数字也随着每 6 位数字而变化。 K div 6 = 0:选择索引 0 处的数字。(反正这里只有数字,“4”。)余数是 2。
  • 第三个数字随着第二个数字的变化而变化:K div 2 = 1:选择索引 1 处的数字:“6”。还押为0。
  • 最后一位数字总是随着每个数字的变化而变化。取索引 K = 0 处的数字:“8”

号码是多少?第2468章!

__________
* 您不需要来自 ceil mosule 的 math。您可以使用 s 轻松拆分字符串 range,它还可以处理不完整的结束块:

blocks = [s[i:i + X] for i in range(0,n,X)]

** 您可以使用 set 删除重复条目:

digits = [sorted(set(i)) for i in blocks]

*** 这里,div 表示整数除法,mod 表示取模。各自的 Python 运算符是 //%p == (p // q) * q + p % q.

,

基于 @M Oem approach,这里是我针对上述问题的代码。

def Find_It(N,X,K,S):
    S = list(S)
    blocks = [S[i:i + X] for i in range(0,N,X)]
    digits = [sorted(set(i)) for i in blocks]
    freq = [len(x) for x in digits]
    for i in range(len(freq) - 2,-1,-1):
        freq[i] = freq[i] * freq[i + 1]
    if K > freq[0]:
        return -1
    freq.append(1)
    ans = []
    K = K - 1
    for i in range(1,len(freq)):
        div = K // freq[i]
        ans.append(digits[i - 1][div])
        K = K % freq[i]
    print(''.join(ans))


Find_It(11,3,9,'13244467589')
Find_It(10,5,10,'1234567891')
Output: 2468,29

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。