我提到的问题类似于this one。唯一的区别是1.)应该至少有一段距离' k'从当前元素到我们选择的最接近的较小元素的单位。 2.)元素可以从任一方向,向左或向右挑选。因此,例如,如果k = 4并且当前的元素旁边有一个较小的元素,我们就无法选择它,因为它太接近了。
我尝试以与其他解决方案相同的方式实现它。我所做的改变是,每次从堆栈中删除一个元素时,如果它实际上小于当前元素但是因为它比k个单位更接近而被删除,那么我将元素添加回一旦我找到当前元素的答案然后继续前进到下一个元素。这似乎有效,但我确信有更有效的方法来解决这个问题。任何建议都会非常有用。
答案 0 :(得分:2)
仅向前遍历: 以下算法是对Given an array, find out the next smaller element for each element的答案的修改,并返回输入数组的每个元素的最近的较小后继,并保证元素和后继之间的最小距离:
// Traversal in both directions:
function smaller(array, distance) {
var length = array.length,
forward = new Array(length).fill(null),
backward = new Array(length).fill(null),
stack = [];
// Forward pass:
for (var i = 0, j = distance; j < length; ++i, ++j) {
while (stack.length > 0 && array[j] < array[stack[stack.length - 1]]) {
forward[stack.pop()] = j;
}
stack.push(i);
}
// Backward pass:
stack = [];
for (var i = length - 1, j = length - distance - 1; j >= 0; --i, --j) {
while (stack.length > 0 && array[j] < array[stack[stack.length - 1]]) {
backward[stack.pop()] = j;
}
stack.push(i);
}
// Pick closest elements from both passes:
for (var i = 0; i < length; ++i) {
if (backward[i] !== null) {
if (forward[i] !== null && forward[i] - i < i - backward[i]) {
forward[i] = array[forward[i]];
} else {
forward[i] = array[backward[i]];
}
} else if (forward[i] !== null) {
forward[i] = array[forward[i]];
}
}
return forward;
}
console.log(smaller([0, 2, 1], 0)); // [null, 0, 0]
console.log(smaller([5, 2, 1, 7, 6, 0], 1)); // [1, 0, 0, 2, 1, null]
向前和向后遍历:以下算法为输入数组的每个元素返回最近的较小后继者或前任,并保证元素与后继者之间的最小距离或前任。
它的工作方式类似于第一种算法,但是在两个方向上遍历数组并存储索引,而不是较小元素的值。最近的较小元素是从最后第三遍中的两次传递的结果中选择的:
{!! Form::text('name', NULL, ['class' => 'form-control'.($errors->has("name") ? " has-error" : "").'', 'placeholder' => 'Enter your name'] ) !!}