Original answer
My initial answer consisted of the following three steps. This algorithm works under the condition that the max value in the normalized array precedes the min value in the normalized array. The sample arrays I reviewed were [4, 0, 9, -2] and [0, 1, 3, -15]. Note that in both of these sample arrays, max preceded by min . However, this algorithm fails if the absolute min in the array appears before the absolute max . Two examples in which the algorithm fails are [-15, 1] ββand [40, 31, 140, 131].
Step 1: subtract the index of the array from the value in that index
array: 4 0 9 -2 index: -0 -1 -2 -3 ---------------- normalized array: 4 -1 7 -5
Step 2: scan the normalized array to find the min and max values
max = 7 min = -5
Step 3: subtract min from max and divide by 2 (rounding if necessary), and there your answer
(7 - (-5)) / 2 = 6
Justification and lack of original answer
The idea of ββmy initial answer was that the midpoint between max and min provided a target value so that each record in a normalized array could be adjusted to hit. max and min , which are the farthest from the target , required the greatest settings and, therefore, provided the answer. However, after seeing hk6279 comment, I realized that it is possible to have multiple targets for a normalized array. For example, consider an array [40, 31, 140, 131]. First step is
array: 40 31 140 131 index: -0 -1 -2 -3 ----------------- normalized: 40 30 138 128
target for the first two numbers - 35 (available with settings + -5). target for the second two numbers - 133 (also available with settings + -5). So the answer is 5, and the array settings are
array: 40 31 140 131 adjustment: -5 +5 -5 +5 ----------------- sorted: 35 36 135 136
(Lateral note: the array [-15,1] also has two targets. The target for -15 is -15 with a setting of 0. The target for 0 (normalized value 1) is 0 with a setting of 0. Thus, the answer is 0).
More complex (but still O (n)) answer
Step 1: normalize the array by subtracting the array index from the value in that index. This step does not change from the original answer.
Step 2: Define a data structure for storing information about array entries.
struct Section { int max; // the maximum value seen in this section of the array int min; // the minimum value seen in this section of the array int startIndex; // the starting index for this section of the array int endIndex; // the ending index for this section of the array }
Step 3. Scanning a normalized array when creating an array of Section structures. ( sectionsArray can be as long as the array is normalized .) The rules for creating sectionsArray are
initialize the first section as { normalized[0], normalized[0], 0, 0 } for each subsequent entry in the normalized array { if ( normalized[i] > currentSection.max ) // found a larger value than the current max { newSection = { normalized[i], normalized[i], i, i } // create a new section and add it to the sectionsArray currentSection = newSection // the new section is now our current section } else if ( normalized[i] < currentSection.min ) // found a new minimum for the current section { currentSection.min = normalized[i] // update the min and end of the current section currentSection.endIndex = i; } else // normalized[i] is within the current range of values { currentSection.endIndex = i; // update the end of the current section } }
Note that in this step, the maximum values ββin sectionsArray are in strictly ascending order. This is important for the next step.
Step 4: Working back from the end of sectionsArray , merge sections where possible. The rule for combining two sections:
if ( sectionsArray[i].min <= sectionsArray[i-1].min )
Step 5: Scan sectionsArray to find the largest difference between max and min . The largest difference, divided into two and rounded, if necessary, is the answer to the question. In addition, the midpoint between min and max is the target value for this section of the array (target values ββcan be truncated).
Example
Consider the array [8,5,8,6,14,12,18,13]. First, normalize the array:
Input array: 8 5 8 6 14 12 18 13 index: -0 -1 -2 -3 -4 -5 -6 -7 ------------------------------ Normalized: 8 4 6 3 10 7 12 6
Then create an array of partitions:
{ 8, 3, 0, 3 }
Work back: section 10.7 can be absorbed by section 12.6, resulting in
{ 8, 3, 0, 3 } { 12, 6, 4, 7 }
The maximum difference is 6, so the answer is 3.
The purpose of the first section is (8 + 3) / 2 = 5 (after truncation) The purpose of the second section is (12 + 6) / 2 = 9
Adjustments:
Normalized: 8 4 6 3 10 7 12 6 Adjustments: -3 1 -1 2 -1 2 -3 3 ------------------------------- Targets: 5 5 5 5 9 9 9 9
Apply the same settings to the input array:
Input array: 8 5 8 6 14 12 18 13 Adjustments: -3 1 -1 2 -1 2 -3 3 ------------------------------- Sorted: 5 6 7 8 13 14 15 16
Applying this technique to other arrays visible in this stream
input: 4 0 9 -2 normalized: 4 -1 7 -5 sections: { 4, -1, 0, 1 } { 7, -5, 2, 3 } combined: { 7, -5, 0, 3 } answer: (7 - (-5)) / 2 = 6 targets: one target for the entire normalized array => (7 + (-5)) / 2 = 1 input: 0 1 3 -15 normalized: 0 0 1 -18 sections: { 0, 0, 0, 1 } { 1, -18, 2, 3 } combined: { 1, -18, 0, 3 } answer: (1 - (-18)) / 2 = 10 targets: one target for the entire normalized array => (1 + (-18)) / 2 = -8 input: -15 1 normalized: -15 0 sections: { -15, -15, 0, 0 } { 0, 0, 1, 1 } combined: same as above answer: 0 (same answer for both sections) targets: targets are -15 and 0 input: 40 31 140 131 normalized: 40 30 138 128 sections: { 40, 30, 0, 1 } { 138, 128, 2, 3 } combined: same as above answer: 5 (same answer for both sections) targets: targets are 35 and 133
Task
Find a counter example that breaks this algorithm and posts it in the comments :)