2个独特元素的总和

时间:2018-09-07 01:13:06

标签: algorithm

假设您有一个数组,并且有2个框,可以在其中放入唯一元素

{a,b,b,c,b,b,c,d}

您可以从数组中的任何位置开始,但只能向右移动。在每个篮子中,您只能放置一种元素。例如,如果a在篮子中,则只有a可以覆盖它。当您不能将元素放入任一框中时,您将停止。

从这样的数组进入两个框的最大元素数量是多少。

在此数组中,答案为6,因为如果从索引1开始,则一个篮子中可以有4b,另一个篮子中可以有2c,所以总数为6。

有人可以为这样的问题解释一种有效的算法吗,因为数组会变得非常大,并且内部可能有许多不同类型的元素

3 个答案:

答案 0 :(得分:4)

您可以在仅对输入进行一次迭代的同时进行计算,而无需存储这些段。您只需要跟踪当前段中的两个字符,段的长度以及段末尾相同字符的数量。因此,时间复杂度为O(n),空间复杂度为O(1)。

function largestPair(input) {
    var len = 0;     // length of segment
    var run = 0;     // number of identical characters at end
    var max = 0;     // length of longest segment
    var cur = '';    // last character in segment
    var prv = '';    // other character in segment

    for (var i = 0; i < input.length; i++) {
        if (input[i] == cur) {      // same as last
            ++len;
            ++run;
        }
        else if (input[i] == prv) { // same as other
            prv = cur;
            cur = input[i];
            ++len;
            run = 1;
        }
        else {                      // new character
            prv = cur;
            cur = input[i];
            len = run + 1;
            run = 1;
        }
        if (len > max) max = len;
    }
    return max;
}
document.write(largestPair(['a','b','b','c','b','b','c','d']) + "<br>");
document.write(largestPair(['a','b','a','c','d','c','e','a','b']) + "<br>");
document.write(largestPair(['c','a','a','c','a','c','b','b','b']) + "<br>");
document.write(largestPair(['a','b','c','d','e','f','g','h','i']) + "<br>");
document.write(largestPair(['a','a']) + "<br>");
document.write(largestPair(['a']) + "<br>");

或更简洁,但不那么明显:

function largestPair(input) {
    var len = 0;     // length of segment
    var run = 0;     // number of identical characters at end
    var max = 0;     // length of longest segment
    var cur = '';    // last character in segment
    var prv = '';    // other character in segment

    for (var i = 0; i < input.length; i++) {
        if (input[i] == cur) {
            ++len;
            ++run;
        } else {
            len = (input[i] == prv ? len : run) + 1;
            run = 1;
            prv = cur;
            cur = input[i];
        }
        if (len > max) max = len;
    }
    return max;
}

答案 1 :(得分:3)

这是Java中的另一种解决方案,只需要一次通过,不需要额外的存储空间:

static int max2Run(String[] a)
{
    int e1 = 0; 
    int e2 = 0;
    int max = 0;
    for(int k=0, i=1; i<a.length; i++)
    {
        if(a[i] != a[i-1])
        {
            if(a[i] != a[e1] && a[i] != a[e2])
            {
                max = Math.max(max, i-e1);
                e1 = k;
                e2 = i;
            }
            k = i;
        }
    }
    return Math.max(max, a.length-e1);
}

public static void main(String[] args)
{
    String[] a1 = {"a","b","b","c","b","b","c","d"};
    System.out.println(Arrays.toString(a1) + " " + max2Run(a1));

    String[] a2 = {"c","a","a","c","a", "c", "b","b","b"};
    System.out.println(Arrays.toString(a2) + " " + max2Run(a2));

    System.out.println();

    String[] a = new String[]{"a","a","a","b","b","b","c","c","c"};
    List<String> s = new ArrayList<String>(Arrays.asList(a));
    for(int i=0; i<5; i++)
    {
        Collections.shuffle(s);
        s.toArray(a);
        System.out.println(Arrays.toString(a) + " " + max2Run(a));
    }
}

输出:

[a, b, b, c, b, b, c, d] 6
[c, a, a, c, a, c, b, b, b] 6

[a, c, b, c, b, c, a, a, b] 5
[b, b, a, c, a, a, c, b, c] 5
[a, c, b, a, b, c, b, c, a] 4
[c, a, a, b, c, b, b, c, a] 5
[a, c, a, b, b, a, c, b, c] 4

答案 2 :(得分:0)

首先,您需要创建一个循环,将每个项目用作索引。

然后,为每个起始索引可以包含的元素数量创建数组。

然后在其后创建一个循环,以检查哪个索引中元素数量最多。 例如:

elements[numElementsInArray];
for(int i=0; i<numElementsInArray; i++)
{
object element1 = array[i];
object element2 = null;
    for(int j=i; j<numElementsInArray; j++){

        if(array[j]==element1)
            elements[i]++;
        else if(element2!=null && array[j]==element2)
            elements[i]++;
        else if(element2==null){ element2=array[j]; elements[i]++; }
        else break;
    }    
}

//在该循环之后,在具有最高值的elements []上创建一个循环。 这只是一个主意,我只是输入此代码而未对其进行测试,请勿复制粘贴。创建您自己的代码。 我还为两个购物篮创建了两个对象element1和element2。 首先,我将element1设置为索引i的第一个,这样它将成为购物篮中的第一项。然后在另一个循环中,您将检查element2是否被占用或为null。如果后续项不等于element1 / 2,则它将破坏并设置另一个element1 / 2并将另一个增量设置为element []。