A non-empty array A consisting of N integers is given. A pair of integers (P, Q), such that 0 ≤ P < Q < N, is called a slice of array A (notice that the slice contains at least two elements). The average of a slice (P, Q) is the sum of A[P] + A[P + 1] + ... + A[Q] divided by the length of the slice. To be precise, the average equals (A[P] + A[P + 1] + ... + A[Q]) / (Q − P + 1).
For example, array A such that:
A[0] = 4 A[1] = 2 A[2] = 2 A[3] = 5 A[4] = 1 A[5] = 5 A[6] = 8contains the following example slices:
- slice (1, 2), whose average is (2 + 2) / 2 = 2;
- slice (3, 4), whose average is (5 + 1) / 2 = 3;
- slice (1, 4), whose average is (2 + 2 + 5 + 1) / 4 = 2.5.
The goal is to find the starting position of a slice whose average is minimal.
Write a function:
function solution(A);
that, given a non-empty array A consisting of N integers, returns the starting position of the slice with the minimal average. If there is more than one slice with a minimal average, you should return the smallest starting position of such a slice.
For example, given array A such that:
A[0] = 4 A[1] = 2 A[2] = 2 A[3] = 5 A[4] = 1 A[5] = 5 A[6] = 8the function should return 1, as explained above.
Write an efficient algorithm for the following assumptions:
- N is an integer within the range [2..100,000];
- each element of array A is an integer within the range [−10,000..10,000].
// you can write to stdout for debugging purposes, e.g.
// console.log('this is a debug message');
function solution(A) {
/* Consider a slice of size 4. You can always break it down into two slices of size 2. One of two cases may happen. First, the averages of the two slices are the same, in which case, you could just use the first average. Second, the averages are different, in which case, your original slice cannot be the min-average slice. So the slice of size 4 is either duplicated with a shorter slice, or not the min. You cannot make this argument with a slice of size 3.*/
const N = A.length;
let lowestIndex = 0;
let lowestAvg = Number.MAX_SAFE_INTEGER;
let last = undefined;
let lastButOne = undefined;
for (let i = 0; i < N; i ++) {
if (last !== undefined) {
const avg = (last + A[i]) / 2;
if (avg < lowestAvg) {
lowestAvg = avg;
lowestIndex = i - 1;
}
}
if (lastButOne !== undefined) {
const avg = (lastButOne + last + A[i]) / 3;
if (avg < lowestAvg) {
lowestAvg = avg;
lowestIndex = i - 2;
}
}
last = A[i];
lastButOne = last;
}
return lowestIndex;
}
// you can write to stdout for debugging purposes, e.g.
// console.log('this is a debug message');
function solution(A) {
/* Consider a slice of size 4. You can always break it down into two slices of size 2. One of two cases may happen. First, the averages of the two slices are the same, in which case, you could just use the first average. Second, the averages are different, in which case, your original slice cannot be the min-average slice. So the slice of size 4 is either duplicated with a shorter slice, or not the min. You cannot make this argument with a slice of size 3.*/
const N = A.length;
let lowestIndex = 0;
let lowestAvg = Number.MAX_SAFE_INTEGER;
let last = undefined;
let lastButOne = undefined;
for (let i = 0; i < N; i++) {
if (last !== undefined) {
const avg = (last + A[i]) / 2;
if (avg < lowestAvg) {
lowestAvg = avg;
lowestIndex = i - 1;
}
}
if (lastButOne !== undefined) {
const avg = (lastButOne + last + A[i]) / 3;
if (avg < lowestAvg) {
lowestAvg = avg;
lowestIndex = i - 2;
}
}
last = A[i];
lastButOne = last;
}
return lowestIndex;
}
// you can write to stdout for debugging purposes, e.g.
// console.log('this is a debug message');
function solution(A) {
/* Consider a slice of size 4. You can always break it down into two slices of size 2. One of two cases may happen. First, the averages of the two slices are the same, in which case, you could just use the first average. Second, the averages are different, in which case, your original slice cannot be the min-average slice. So the slice of size 4 is either duplicated with a shorter slice, or not the min. You cannot make this argument with a slice of size 3.*/
const N = A.length;
let lowestIndex = 0;
let lowestAvg = Number.MAX_SAFE_INTEGER;
let last = undefined;
let lastButOne = undefined;
for (let i = 0; i < N; i++) {
if (last !== undefined) {
const avg = (last + A[i]) / 2;
if (avg < lowestAvg) {
lowestAvg = avg;
lowestIndex = i - 1;
}
}
last = A[i];
lastButOne = last;
}
return lowestIndex;
}
// you can write to stdout for debugging purposes, e.g.
// console.log('this is a debug message');
function solution(A) {
/* Consider a slice of size 4. You can always break it down into two slices of size 2. One of two cases may happen. First, the averages of the two slices are the same, in which case, you could just use the first average. Second, the averages are different, in which case, your original slice cannot be the min-average slice. So the slice of size 4 is either duplicated with a shorter slice, or not the min. You cannot make this argument with a slice of size 3.*/
const N = A.length;
let lowestIndex = 0;
let lowestAvg = Number.MAX_SAFE_INTEGER;
let last = undefined;
let lastButOne = undefined;
for (let i = 0; i < N; i++) {
if (lastButOne !== undefined) {
const avg = (lastButOne + last + A[i]) / 3;
if (avg < lowestAvg) {
lowestAvg = avg;
lowestIndex = i - 2;
}
}
if (last !== undefined) {
const avg = (last + A[i]) / 2;
if (avg < lowestAvg) {
lowestAvg = avg;
lowestIndex = i - 1;
}
}
last = A[i];
lastButOne = last;
}
return lowestIndex;
}
// you can write to stdout for debugging purposes, e.g.
// console.log('this is a debug message');
function solution(A) {
/* Consider a slice of size 4. You can always break it down into two slices of size 2. One of two cases may happen. First, the averages of the two slices are the same, in which case, you could just use the first average. Second, the averages are different, in which case, your original slice cannot be the min-average slice. So the slice of size 4 is either duplicated with a shorter slice, or not the min. You cannot make this argument with a slice of size 3.*/
const N = A.length;
let lowestIndex = 0;
let lowestAvg = Number.MAX_SAFE_INTEGER;
let last = undefined;
let lastButOne = undefined;
for (let i = 0; i < N; i++) {
if (lastButOne !== undefined) {
const avg = (lastButOne + last + A[i]) / 3;
if (avg < lowestAvg) {
lowestAvg = avg;
lowestIndex = i - 2;
}
}
if (last !== undefined) {
const avg = (last + A[i]) / 2;
if (avg < lowestAvg) {
lowestAvg = avg;
lowestIndex = i - 1;
}
}
last = A[i];
lastButOne = last;
}
return lowestIndex;
}
// you can write to stdout for debugging purposes, e.g.
// console.log('this is a debug message');
function solution(A) {
/* Consider a slice of size 4. You can always break it down into two slices of size 2. One of two cases may happen. First, the averages of the two slices are the same, in which case, you could just use the first average. Second, the averages are different, in which case, your original slice cannot be the min-average slice. So the slice of size 4 is either duplicated with a shorter slice, or not the min. You cannot make this argument with a slice of size 3.*/
const N = A.length;
let lowestIndex = 0;
let lowestAvg = Number.MAX_SAFE_INTEGER;
let last = undefined;
let lastButOne = undefined;
for (let i = 0; i < N; i++) {
if (lastButOne !== undefined) {
const avg = (lastButOne + last + A[i]) / 3;
if (avg < lowestAvg) {
lowestAvg = avg;
lowestIndex = i - 2;
}
}
if (last !== undefined) {
const avg = (last + A[i]) / 2;
if (avg < lowestAvg) {
lowestAvg = avg;
lowestIndex = i - 1;
}
}
last = A[i];
lastButOne = last;
}
return lowestIndex;
}
// you can write to stdout for debugging purposes, e.g.
// console.log('this is a debug message');
function solution(A) {
/* Consider a slice of size 4. You can always break it down into two slices of size 2. One of two cases may happen. First, the averages of the two slices are the same, in which case, you could just use the first average. Second, the averages are different, in which case, your original slice cannot be the min-average slice. So the slice of size 4 is either duplicated with a shorter slice, or not the min. You cannot make this argument with a slice of size 3.*/
const N = A.length;
let lowestIndex = 0;
let lowestAvg = Number.MAX_SAFE_INTEGER;
let last = undefined;
let lastButOne = undefined;
for (let i = 0; i < N; i++) {
if (lastButOne !== undefined) {
const avg = (lastButOne + last + A[i]) / 3;
if (avg < lowestAvg) {
lowestAvg = avg;
lowestIndex = i - 2;
}
}
if (last !== undefined) {
const avg = (last + A[i]) / 2;
if (avg < lowestAvg) {
lowestAvg = avg;
lowestIndex = i - 1;
}
}
lastButOne = last;
}
return lowestIndex;
}
// you can write to stdout for debugging purposes, e.g.
// console.log('this is a debug message');
function solution(A) {
/* Consider a slice of size 4. You can always break it down into two slices of size 2. One of two cases may happen. First, the averages of the two slices are the same, in which case, you could just use the first average. Second, the averages are different, in which case, your original slice cannot be the min-average slice. So the slice of size 4 is either duplicated with a shorter slice, or not the min. You cannot make this argument with a slice of size 3.*/
const N = A.length;
let lowestIndex = 0;
let lowestAvg = Number.MAX_SAFE_INTEGER;
let last = undefined;
let lastButOne = undefined;
for (let i = 0; i < N; i++) {
if (lastButOne !== undefined) {
const avg = (lastButOne + last + A[i]) / 3;
if (avg < lowestAvg) {
lowestAvg = avg;
lowestIndex = i - 2;
}
}
if (last !== undefined) {
const avg = (last + A[i]) / 2;
if (avg < lowestAvg) {
lowestAvg = avg;
lowestIndex = i - 1;
}
}
lastButOne = last;
last = A[i];
}
return lowestIndex;
}
// you can write to stdout for debugging purposes, e.g.
// console.log('this is a debug message');
function solution(A) {
/* Consider a slice of size 4. You can always break it down into two slices of size 2. One of two cases may happen. First, the averages of the two slices are the same, in which case, you could just use the first average. Second, the averages are different, in which case, your original slice cannot be the min-average slice. So the slice of size 4 is either duplicated with a shorter slice, or not the min. You cannot make this argument with a slice of size 3.*/
const N = A.length;
let lowestIndex = 0;
let lowestAvg = Number.MAX_SAFE_INTEGER;
let last = undefined;
let lastButOne = undefined;
for (let i = 0; i < N; i++) {
if (last !== undefined) {
const avg = (last + A[i]) / 2;
if (avg < lowestAvg) {
lowestAvg = avg;
lowestIndex = i - 1;
}
}
if (lastButOne !== undefined) {
const avg = (lastButOne + last + A[i]) / 3;
if (avg < lowestAvg) {
lowestAvg = avg;
lowestIndex = i - 2;
}
}
lastButOne = last;
last = A[i];
}
return lowestIndex;
}
// you can write to stdout for debugging purposes, e.g.
// console.log('this is a debug message');
function solution(A) {
/* Consider a slice of size 4. You can always break it down into two slices of size 2. One of two cases may happen. First, the averages of the two slices are the same, in which case, you could just use the first average. Second, the averages are different, in which case, your original slice cannot be the min-average slice. So the slice of size 4 is either duplicated with a shorter slice, or not the min. You cannot make this argument with a slice of size 3.*/
const N = A.length;
let lowestIndex = 0;
let lowestAvg = Number.MAX_SAFE_INTEGER;
let last = undefined;
let lastButOne = undefined;
for (let i = 0; i < N; i++) {
if (last !== undefined) {
const avg = (last + A[i]) / 2;
if (avg < lowestAvg) {
lowestAvg = avg;
lowestIndex = i - 1;
}
}
if (lastButOne !== undefined) {
const avg = (lastButOne + last + A[i]) / 3;
if (avg < lowestAvg) {
lowestAvg = avg;
lowestIndex = i - 2;
}
}
lastButOne = last;
last = A[i];
}
return lowestIndex;
}
// you can write to stdout for debugging purposes, e.g.
// console.log('this is a debug message');
function solution(A) {
/* Consider a slice of size 4. You can always break it down into two slices of size 2. One of two cases may happen. First, the averages of the two slices are the same, in which case, you could just use the first average. Second, the averages are different, in which case, your original slice cannot be the min-average slice. So the slice of size 4 is either duplicated with a shorter slice, or not the min. You cannot make this argument with a slice of size 3.*/
const N = A.length;
let lowestIndex = 0;
let lowestAvg = Number.MAX_SAFE_INTEGER;
let last = undefined;
let lastButOne = undefined;
for (let i = 0; i < N; i++) {
if (last !== undefined) {
const avg = (last + A[i]) / 2;
if (avg < lowestAvg) {
lowestAvg = avg;
lowestIndex = i - 1;
}
}
if (lastButOne !== undefined) {
const avg = (lastButOne + last + A[i]) / 3;
if (avg < lowestAvg) {
lowestAvg = avg;
lowestIndex = i - 2;
}
}
lastButOne = last;
last = A[i];
}
return lowestIndex;
}
The solution obtained perfect score.