Last active
July 7, 2023 17:04
-
-
Save misterfourtytwo/a0ab7d71350a5167b48a985acbccb206 to your computer and use it in GitHub Desktop.
Yandex interview algo task: find longest ascending/descending segment of an array
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Дан массив чисел 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