Учитывая массив A, вычислите B s.t B[i] хранит ближайший элемент слева от A[i], который меньше a[i]
дан массив A[1..n]
, мы хотим вычислить другой массив B[1..n]
такое, что B[i]
хранит ближайший элемент слева от A[i]
меньше, чем A[i]
.
Время сложности должно быть O(n)
.
(для i>1
, если слева нет таких меньших элементов, то B[i]
содержит A[i]
и B[1]=A[1]
.)
пример :
вход : 6,9,12,17,11
выход:6,6, 9, 12, 9
Я думал о реализации стека,
положи A[1]
на B[1]
, затем нажмите на стек.
для заполнения B[i]
сравнить A[i]
С ЭЛЕМЕНТАМИ стека и поп, пока вы получите меньший элемент.
наконец, нажимаем A[i]
в стек.
выше подход правильный, и есть более дешевое решение?
3 ответов
ваш подход к стеку правильный. Это работает, потому что если вы поп-элемент больше, чем A[i]
, этот элемент никогда не понадобится для любых элементов, следующих за A[i]
, потому что вы можете просто использовать .
каждый элемент доступен только дважды, так что это O(n)
.
подход стека неверен. просто посмотрим, что произойдет, если у вас на входе 6, 9, 12, 17, 11, 15. Когда вы будете работать с 15, ваш стек будет забыт о 12 и 17. Но ближайший маленький левый элемент A[5] равен 12.
алгоритм Saeed тоже не прав. Просто попробуй вычислить.
правильный ответ может быть что-то вроде этого
b[1] = a[1];
s[1] = 1;
for (i=2; i<=n; i+=1) {
j = i - 1;
while (j>1){
if (a[j]<a[i]) {
b[i] = a[j];
s[i] = j;
break;
} else {
j = s[j];
}
}
if (j = 1) {
b[i] = a[j];
s[i] = j;
}
}
Я не уверен, но он имеет сложность O (n).
B[1]=A[1]
push(B[1])
for i=2 to n do
{
while(A[i] > stack_top ANS stack_top!=NULL)
pop()
if(stack_top=NULL)
B[i]=A[i]
else
B[i]=stack_top
push(A[i])
}
Как указал Ивлад, каждый элемент толкается и всплывает atmost один раз, время O(n).
pl исправьте меня, если есть какая-то ошибка, и мне любопытно любое альтернативное решение, которое избегает стека и дешевле.