找到最大切片数组|使用Javascript

时间:2017-03-14 12:35:22

标签: javascript arrays

我需要找到包含不超过两个不同数字的数组的最大切片。

这是我的数组[1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 6, 2, 1, 8]

我的思考过程就是找到不重复的数字并在新数组中返回它们的索引。

这是我到目前为止所做的:

function goThroughInteger(number) {
    var array = [];
    //iterate the array and check if number is not repeated   
  number.filter(function (element, index, number) {
    if(element != number[index-1] && element != number[index+1]) {
        array.push(index);
      return element;
    }
  })

    console.log(array);
}
goThroughInteger([1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 6, 2, 1, 8]);

我不确定下一步该去哪里,我很难理解这样一个问题 - 找到包含不超过两个不同数字的最大切片 - 让我感到困惑。

4 个答案:

答案 0 :(得分:5)

具有单个循环的解决方案,它检查最后的值并递增计数器。

function getLongestSlice(array) {
    var count = 0,
        max = 0,
        temp = [];

    array.forEach(function (a) {
        var last = temp[temp.length - 1];

        if (temp.length < 2 || temp[0].value === a || temp[1].value === a) {
            ++count;
        } else {
            count = last.count + 1;
        }
        if (last && last.value === a) {
            last.count++;
        } else {
            temp.push({ value: a, count: 1 });
            temp = temp.slice(-2);
        }
        if (count > max) {
            max = count;
        }
    });
    return max;
}

console.log(getLongestSlice([58, 800, 0, 0, 0, 356, 8988, 1, 1]));        //  4
console.log(getLongestSlice([58, 800, 0, 0, 0, 356, 356, 8988, 1, 1]));   //  5
console.log(getLongestSlice([1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 6, 2, 1, 8])); // 10

答案 1 :(得分:3)

这是一个可能的解决方案,复杂度为O(n²)(正如评论中@le_m所指出的那样)

goThroughInteger = list => {
	let scores = list.reduce((slices, num, pos) => {
		let valid = [num]
		let count = 0;
		for (let i=pos; i<list.length; i++) {
			if (valid.indexOf(list[i]) == -1) {
				if (valid.length < 2) {
					valid.push(list[i])
					count++
				} else {
					break
				}
			} else {
				count++
			}
		}
		slices[pos] = {pos, count}
		return slices
	}, [])

	scores.sort((a,b) => b.count - a.count)
	let max = scores[0]
	return list.slice(max.pos, max.pos + max.count)
}

console.log(goThroughInteger([1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 6, 2, 1, 8]))
console.log(goThroughInteger([58, 800, 0, 0, 0, 356, 8988, 1, 1]))

它计算输入列表每个位置的“得分”,计算不超过2个不同值的序列的长度。 比较获得得分最高的结果,并根据该信息从原始列表中提取切片。

它绝对可以清理和优化,但我认为这是一个很好的起点。

答案 2 :(得分:3)

 function goThroughInteger(array) {  
   var solutionArray = [];
   var max = 0;
    for (var i = 0; i <= array.length; i++) {
       for (var j = i + 1; j <= array.length; j++) {
         var currentSlice= array.slice(i,j);
         var uniqSet = [...new Set(currentSlice)];
      if(uniqSet.length <3) {
        if(currentSlice.length>max) {
        max= currentSlice.length;
        }
      }
     }      
  }
 console.log(max);
}

goThroughInteger([1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 6, 2, 1, 8]);

此解决方案检查数组的每个可能切片,检查它是否具有不超过2个不同的数字,最后打印出最长切片的长度。

答案 3 :(得分:0)

在O(n)时间内使用滑动窗口算法:

const arr = [1, 1, 1, 2, 2, 2, 1, 1, 2, 2, 6, 2, 1, 8, 1, 1 ,1 ,1, 8, 1, 1, 8, 8];

const map = {
   length: 0
};

let required = [];
for(start = 0, end = 0; end <= arr.length; ){

if(map.length > 2){
    if(map[arr[start]] === 1){
        delete map[arr[start]];
        map.length --;
    }else{
        map[arr[start]]--;
    };
    start++;

}else{
    if(end - start > required.length){
        required = arr.slice(start, end);
    };

    if(map[arr[end]]){
        map[arr[end]]++;
    }else{
        map[arr[end]] = 1;
        map.length++;
    }
    end++;
}
}

console.log(required);