找到一个列表中具有相同重复次数的两个整数的序列的方法是什么?

huangapple go评论59阅读模式
英文:

way to find a sequence in a list with the same number of repetitions of two integers?

问题

我有这个函数,它以整数列表和两个整数作为参数。我需要找到两个整数重复相同次数的最长序列。

例如,如果列表是

[9, 5, 7, 33, 9, 5, 5, 5, 8, 5, 33, 33, 6, 15, 8, 5, 6]

并且 i1 = 33i2 = 5,那么该函数必须返回9,因为最长的序列是 8, 5, 33, 33, 6, 15, 8, 5, 6(事实上,33和5都重复两次)。

我考虑创建一个计数器从0开始,并在列表的元素上使用for循环。然后,如果当前元素等于 i1i2,计数器增加1。我现在需要控制重复的次数,但我卡住了。

英文:

I have this function that takes as arguments a list of integers and two integers. I have to find the longest sequence where the two integers repeat the same number of times.
For example if the list is

[9, 5, 7, 33, 9, 5, 5, 5, 8, 5, 33, 33, 6, 15, 8, 5, 6]

and i1 = 33 and i2 = 5, the function must return 9, because the longest sequence is 8, 5, 33, 33, 6, 15, 8, 5, 6 (in fact 33 and 5 both repeat twice).

I thought about creating a count from 0 and using a for loop on the elements of the list. Then, if the current element equals i1 or i2, the count goes up by 1.
I now need to control the number of repetitions, but I'm stuck.

答案1

得分: 1

以下是代码的中文翻译部分:

这是一个递归解决方案虽然不高效但简洁明了),它从更大的子范围递归检查到更小的范围直到找到一个具有相同数量的每个数字的子范围

def getMaxSeq(L, a, b):
    if L.count(a) == L.count(b): return L
    return max(getMaxSeq(L[1:], a, b), getMaxSeq(L[:-1], a, b), key=len)
    
输出

L = [9, 5, 7, 33, 9, 5, 5, 5, 8, 5, 33, 33, 6, 15, 8, 5, 6]
        
print(getMaxSeq(L, 5, 33))      # [8, 5, 33, 33, 6, 15, 8, 5, 6]
print(len(getMaxSeq(L, 5, 33))) # 9

使用队列来实现按长度递减的子范围的广度优先遍历可能会更高效一些:

from collections import deque
def getMaxSeq(L, a, b):
    ranges = deque([L])
    while L.count(a) != L.count(b):
        ranges.extend((L[1:], L[:-1]))
        L = ranges.popleft()
    return L
英文:

Here's a recursive solution (not efficient but short and simple) that checks subranges from larger to smaller recursing until it finds one that has the same count of each number in it:

def getMaxSeq(L,a,b):
    if L.count(a) == L.count(b): return L
    return max(getMaxSeq(L[1:],a,b),getMaxSeq(L[:-1],a,b),key=len)

output:

L = [9, 5, 7, 33, 9, 5, 5, 5, 8, 5, 33, 33, 6, 15, 8, 5, 6]
        
print(getMaxSeq(L,5,33))      # [8, 5, 33, 33, 6, 15, 8, 5, 6]
print(len(getMaxSeq(L,5,33))) # 9 

Using a queue to implement a breadth first traversal of subranges in decreasing order of length would be a bit more efficient:

from collections import deque
def getMaxSeq(L,a,b):
    ranges = deque([L])
    while L.count(a) != L.count(b):
        ranges.extend((L[1:],L[:-1]))
        L = ranges.popleft()
    return L

答案2

得分: 0

我会通过将列表转换为平衡列表来解决这个问题,并查看何时数字互相平衡。然后,我将循环遍历所有的起始索引,并检查每个在此之后的序列,并在平衡为0且序列长度大于之前的记录时更新我的记录。

l = [9, 5, 7, 33, 9, 5, 5, 5, 8, 5, 33, 33, 6, 15, 8, 5, 6]
num1 = 5
num2 = 33

# 创建一个列表,其中num1 = 1,num2 = -1,否则为0
balance_list = [(1 if x == num1 else -1) if x in [num1, num2] else 0 for x in l]
record = (0, 0)

print(balance_list)

for seq_start in range(len(balance_list)):
    # 如果从seq_start到末尾的长度小于记录长度,则无需继续搜索
    if (len(balance_list) - 1 - seq_start) <= (record[1] - record[0]):
        break

    balance = 0
    for seq_end, val in enumerate(balance_list[seq_start:], seq_start):
        balance += val

        # num1出现的频率与num2相同,且序列长度较长
        if balance == 0 and (seq_end - seq_start) > (record[1] - record[0]):
            record = (seq_start, seq_end)
        # 如果需要更多数字来使平衡为0,我们已经陷入了死胡同
        elif abs(balance) > len(balance_list[seq_start:]) - 1:
            break

print(record)

输出:

(8, 16)

这绝不是一个完美的解决方案,采用动态规划方法会更高效,但我已经尝试添加优化以加快搜索速度(例如,当找不到新的记录时退出搜索)。

英文:

I would approach this by converting the list to a balance list and see when the numbers balance each other out. I would then loop through all the starting indices and check each sequence that comes after that, and update my record when the balance is 0 and the sequence length is longer than the previous record.

l = [9, 5, 7, 33, 9, 5, 5, 5, 8, 5, 33, 33, 6, 15, 8, 5, 6]
num1 = 5
num2 = 33

# create list where num1 = 1, num2 = -1, else 0
balance_list = [(1 if x == num1 else -1) if x in [num1, num2] else 0 for x in l]
record = (0, 0)

print(balance_list)

for seq_start in range(len(balance_list)):
    # if length of seq_start to end is less than record length, no need to search further
    if (len(balance_list)-1 - seq_start) &lt;= (record[1] - record[0]):
        break
    
    balance = 0
    for seq_end, val in enumerate(balance_list[seq_start:], seq_start):
        balance += val
        
        # num1 occurs as frequently as num2, and the sequence length is longer
        if balance == 0 and (seq_end - seq_start) &gt; (record[1] - record[0]):
            record = (seq_start, seq_end)
        # if more numbers are required to get balance to 0, we&#39;ve hit a dead end
        elif abs(balance) &gt; len(balance_list[seq_start:])-1:
            break
    
print(record)

Output:

(8, 16)

This is by no means a perfect solution and a dynamic programming approach would be much more efficient, but I've tried to add optimizations to speed up the search (e.g. quitting the search when no new record can be found).

答案3

得分: 0

这不是最优雅也不是最高性能的代码,但对于这个示例来说,它能正常工作。

def longest_sequence(lst, x, y):
    def helper(lst, x):
        n = len(lst)
        seqs = []
        for i in range(0, n):
            if lst[i] == x:
                j = 0
                sq = []
                while i + j < n:
                    if lst[i + j] == x:
                        sq.append(i + j)
                        j = j + 1
                        seqs.append(sq)
                    else:
                        break
        return seqs

    x_seqs = helper(lst, x)
    y_seqs = helper(lst, y)
    x_max_seq = max(x_seqs, key=len)
    y_max_seq = max(y_seqs, key=len)

    max_len = min(len(x_max_seq), len(y_max_seq)

    return x_max_seq[:max_len], y_max_seq[:max_len]

my_list = [9, 5, 7, 33, 9, 5, 5, 5, 8, 5, 33, 33, 6, 15, 8, 5, 6]
x = 33
y = 5
xsq, ysq = longest_sequence(my_list, x, y)
print(xsq, ysq)

它会返回 x 和 y 的最长序列的索引。

英文:

Neither the most elegant nor the most performant code but it works fine for this example.

def longest_sequence(lst,x,y):
    def helper(lst,x):
        n = len(lst)
        seqs = []
        for i in range(0,n):
            if lst[i]==x:
                j=0
                sq=[]
                while i+j&lt;n:
                    if lst[i+j]==x:
                        sq.append(i+j)
                        j=j+1
                        seqs.append(sq)
                    else:
                        break
        return seqs
    x_seqs = helper(lst,x)
    y_seqs = helper(lst,y)
    x_max_seq = max(x_seqs, key = len)
    y_max_seq = max(y_seqs, key = len)

    max_len = min(len(x_max_seq),len(y_max_seq))

    return x_max_seq[:max_len],y_max_seq[:max_len]

my_list=[9, 5, 7, 33, 9, 5, 5, 5, 8, 5, 33, 33, 6, 15, 8, 5, 6]
x = 33
y = 5
xsq,ysq=longest_sequence(my_list,x,y)
print(xsq,ysq)

and it returns the indices for the longest sequence for both x an y.

huangapple
  • 本文由 发表于 2023年2月8日 22:30:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/75387257.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定