假设您有一个数组,并且有2个框,可以在其中放入唯一元素
{a,b,b,c,b,b,c,d}
您可以从数组中的任何位置开始,但只能向右移动。在每个篮子中,您只能放置一种元素。例如,如果a在篮子中,则只有a可以覆盖它。当您不能将元素放入任一框中时,您将停止。
从这样的数组进入两个框的最大元素数量是多少。
在此数组中,答案为6,因为如果从索引1开始,则一个篮子中可以有4b,另一个篮子中可以有2c,所以总数为6。
有人可以为这样的问题解释一种有效的算法吗,因为数组会变得非常大,并且内部可能有许多不同类型的元素
答案 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 []。