0

Given two arrays of integers with equal lengths, return the maximum value of:

|arr1[i] - arr1[j]| + |arr2[i] - arr2[j]| + |i - j| 

where the maximum is taken over all 0 <= i, j < arr1.length.

Example 1: Input: arr1 = [1,2,3,4], arr2 = [-1,4,5,6] Output: 13

Example 2: Input: arr1 = [1,-2,-5,0,10], arr2 = [0,-2,-1,-7,-4] Output: 20

Constraints: 2 <= arr1.length == arr2.length <= 40000 -10^6 <= arr1[i], arr2[i] <= 10^6

public class Solution {
public int MaxAbsValExpr(int[] arr1, int[] arr2) {
    int max = 0;
    for (int i =0; i < arr1.Length; i++){
        for (int k =i+1; k < arr1.Length; k++){
            if (Math.Abs(arr1[i] - arr1[k]) + Math.Abs(arr2[i] - arr2[k]) + Math.Abs(i - k) > max){
                max = Math.Abs(arr1[i] - arr1[k]) + Math.Abs(arr2[i] - arr2[k]) + Math.Abs(i - k);
            }
        }
    }
    return max; 
}}

This passes most test cases but gets a "Time Limit Exceeded" when the test case has hundreds of values in the arrays in the six digits. I've tried looking online to see how to shorten it in c# but I don't know what else I could do to make it faster.

Flydog57
  • 6,851
  • 2
  • 17
  • 18
  • 1
    Hint, you are running one loop nested inside the other. So if you have N items, your algorithm will take N² time (if you go from 10 items to 20 items it will take 4 times as long). Now consider getting the max of `|arr1[i] - arr1[j]|`. That's going to occur when you find the pair of numbers the furthest apart. That will happen with the maximum and the minimum values. You can get that with a single pass through the array – Flydog57 Dec 04 '21 at 04:58

1 Answers1

0

You encountered "Time Limit Exceeded", it is because your algorithm takes too long to execute and the computer timeout. As commented by @Flydog57, nested loops can be very very expensive and should be avoided. He also suggested a way to implement the algorithm without nested loops. Here's the implementation in PHP (I do not know C#):

    /**
     * Find the indexes of the max and min values in $arr.
     *
     * @param array $arr
     * @return array
     */
    protected function minMaxIndexes(Array $arr)
    {
        // Initialize variables indexes and values by the 1st element of $arr.
        [$i0, $v0, $i1, $v1] = [0, $arr[0], 0, $arr[0]];
        for ($i = 1, $size = count($arr); $i < $size; ++$i) {
            if ($v0 > $arr[$i]) {
                $v0 = $arr[$i];
                $i0 = $i;
            } elseif ($v1 < $arr[$i]) {
                $v1 = $arr[$i];
                $i1 = $i;
            }
        }
        return [$i0, $i1];
    }

    public function maxAbsValExpr(Array $arr1, Array $arr2)
    {
        [$i, $j] = $this->minMaxIndexes($arr1);
        $max1 = abs($arr1[$i] - $arr1[$j]) + abs($arr2[$i] - $arr2[$j]) + abs($i - $j);

        [$i, $j] = $this->minMaxIndexes($arr2);
        $max2 = abs($arr1[$i] - $arr1[$j]) + abs($arr2[$i] - $arr2[$j]) + abs($i - $j);

        return max($max1, $max2);
    }

As you can see, the for loop is 2 times of N-1, if my calculation is correct, it is N/2 times faster than nested loop of N(N-1). That is, for 1 mil array length, it is 500k times faster.

kiatng
  • 2,847
  • 32
  • 39