简体   繁体   English

如何通过在两个 arrays 之间交替来找到最长的交替递增子序列

[英]How to find the longest alternating increasing subsequence by alternating between two arrays

Given two arrays of numbers, how do I find the longest increasing subsequence by alternating between the elements of the two arrays?给定两个 arrays 数字,我如何通过在两个 arrays 的元素之间交替来找到最长的递增子序列? for example例如

A = [4, 1, 10, 5, 9]
B = [4, 5, 7, 14]
so the output must be [1,4,5,7,9,14]

It HAS to be in the format of element of a, element of b, element of a, element of b... so on.必须采用 a 的元素、b 的元素、a 的元素、b 的元素……的格式。

I tried finding a solution but I couldn't think of anything, I tried the LIS approach but since that code requires one array only that didnt make sense to me either sorry我试图找到一个解决方案,但我想不出任何东西,我尝试了 LIS 方法,但由于该代码只需要一个数组,这对我来说没有意义,对不起

(just in case, to make it more clear = [ 1(A), 4(B), 5(A), 7(B), 9(A), 14(B)] also, note how the order cannot be changed) Thanks and sorry if I've not phrased it properly (以防万一,为了更清楚 = [ 1(A), 4(B), 5(A), 7(B), 9(A), 14(B)] 也请注意顺序不能已更改)谢谢,如果我措辞不正确,请见谅

The simplest way would just be to do:最简单的方法就是这样做:

# lias: Longest Increasing Alternating Subsequence
def lias(curr, next, seq):
    good, elem = False, None
    while not good:
        if not curr: return seq
        elem = min(curr); curr.remove(elem)
        good = False if elem in seq or elem < max(seq, default=0) else True
    seq.append(elem)
    return lias(next, curr, seq)


if __name__ == '__main__':
    A = [4, 1, 10, 5, 9]
    B = [4, 5, 7, 14]
    print(lias(A,B, []))
    

You can define a recursive solution that builds the sequence one element at a time based on the previous element and the remaining elements of the list it came from.您可以定义一个递归解决方案,该解决方案基于前一个元素和它来自的列表的其余元素,一次构建一个元素的序列。 Each recursion can swap the parameter order so that the logic only needs to care about one of the lists.每个递归都可以交换参数顺序,以便逻辑只需要关心其中一个列表。

This can be further optimized by carrying a length target based on the longest sequence found so far.这可以通过携带基于迄今为止发现的最长序列的长度目标来进一步优化。

For example:例如:

def longAltSeq(A,B,prev=None,minLen=0):
    result = longAltSeq(B,A,min(B)-1) if prev is None else [] # inverted params
    for i,a in enumerate(A): # Start with an item from A
        if prev is not None and a<=prev: continue     # increasing from previous
        if 2*min(len(A)-i,len(B)+1)<minLen: break     # not enough items left
        seq = [a]+longAltSeq(B,A[i+1:],a,len(result)) # alternate A<->B
        if len(seq)>len(result): result = seq         # track longest
    return result

ouput:输出:

A = [4, 1, 10, 5, 9]
B = [4, 5, 7, 14]
print(longAltSeq(A,B))
[1, 4, 5, 7, 9, 14]

The solution starts with the inverted parameters so that the initial order of the lists doesn't matter解决方案从反转参数开始,因此列表的初始顺序无关紧要

Here's a solution in JavaScript that'll work.这是 JavaScript 中的一个可行的解决方案。 You should be able to replicate that logic in Python or whatever language you need.您应该能够在 Python 或您需要的任何语言中复制该逻辑。 Cheers, and welcome to the community!干杯,欢迎来到社区!

var A = [4, 1, 10, 5, 9];
var B = [4, 5, 7, 14];

run(A,B);

function getSmallest(list, limit){
    var results = [];
    list.forEach(number => {
    if (number > limit)
        results.push(number);
    });
    results.sort(function(a, b) {
        return a - b;
    });
  return results[0];
}

function run(list_a,list_b){
    var result = [];
    var current_list = 1;
    var current_limit = Number.NEGATIVE_INFINITY;
    
    while (current_limit != undefined) {
        current_limit = getSmallest((current_list) ? list_a : list_b, current_limit);
        current_list = !current_list;
        result.push(current_limit);
    }

    result.pop();
    console.log(result);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM