Skip to content

Instantly share code, notes, and snippets.

@misterfourtytwo
Last active July 7, 2023 17:04
Show Gist options
  • Save misterfourtytwo/a0ab7d71350a5167b48a985acbccb206 to your computer and use it in GitHub Desktop.
Save misterfourtytwo/a0ab7d71350a5167b48a985acbccb206 to your computer and use it in GitHub Desktop.
Yandex interview algo task: find longest ascending/descending segment of an array
/*
Дан массив чисел a_1, a_2, ..., a_n .
Необходимо найти монотонный подотрезок (то есть строго убывающий или строго возрастающий) максимальной длины и
вернуть пару индексов его начала и конца.
*/
void main() {
final tests = [
[1, 1], // -> {1, 3}
[2, 7, 5, 4, 4, 3], // -> {1, 1} or {0, 0}
[2, 2, 2, 1, 1, 3], // -> {2, 3} or {4, 5}
[1, 2, 3, 4, 5, 6, 7, 8, 9], // -> {0, 8}
[1, 2, 3, 4, 3, 2, 1, 8, 9, 10, 11], // -> {6, 10}
[1, 2, 3, 3, 3, 2, 3, 4, 5, 6, 8, 9, 10, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1], // -> {13, 23}
];
for (final test in tests) {
print(
solution(test).answerString,
);
}
}
class Segment {
final int start;
final int end;
int get length => end - start + 1;
final bool isAscending;
const Segment({
required this.start,
required this.end,
this.isAscending = true,
});
Segment copyWith({
int? start,
int? end,
bool? isAscending,
}) =>
Segment(
start: start ?? this.start,
end: end ?? this.end,
isAscending: isAscending ?? this.isAscending,
);
String get answerString => '{$start, $end}';
}
Segment solution(final List<int> input) {
assert(input.isNotEmpty, 'input must contain elements');
Segment answer = Segment(start: 0, end: 0);
Segment currentSegment = Segment(start: 0, end: 0);
for (int i = 1; i < input.length; i++) {
bool equalNumbers = input[i] == input[currentSegment.end];
bool resetSegment = equalNumbers ||
(input[i] < input[currentSegment.end]
? currentSegment.isAscending
: !currentSegment.isAscending);
if (resetSegment && currentSegment.length > answer.length) {
answer = currentSegment;
}
currentSegment = Segment(
start: resetSegment
? equalNumbers
? i
: currentSegment.end
: currentSegment.start,
end: i,
isAscending: input[i] > input[currentSegment.end],
);
}
if (currentSegment.length > answer.length) answer = currentSegment;
return answer;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment