Interview - Find magnitude pole in an array

前端 未结 8 2247
孤独总比滥情好
孤独总比滥情好 2021-02-09 15:52

Magnitude Pole: An element in an array whose left hand side elements are lesser than or equal to it and whose right hand side element are greater than or equal to it.

相关标签:
8条回答
  • 2021-02-09 16:28

    I saw this problem on Codility, solved it with Perl:

    sub solution {
            my (@A) = @_;            
    
            my ($max, $min) = ($A[0], $A[-1]);
            my %candidates;
    
            for my $i (0..$#A) {
                    if ($A[$i] >= $max) {
                            $max = $A[$i];
                            $candidates{$i}++;
                    }
            }
            for my $i (reverse 0..$#A) {
                    if ($A[$i] <= $min) {
                            $min = $A[$i];
                            return $i if $candidates{$i};
                    }
            }
            return -1;
    }
    
    0 讨论(0)
  • 2021-02-09 16:30

    Your logic seems perfectly correct (didn't check the implementation, though) and can be implemented to give an O(n) time algorithm! Nice job thinking in terms of sets.

    Your right set can be implemented as a stack which supports a min, and the left set can be implemented as a stack which supports a max and this gives an O(n) time algorithm.

    Having a stack which supports max/min is a well known interview question and can be done so each operation (push/pop/min/max is O(1)).

    To use this for your logic, the pseudo code will look something like this

    foreach elem in a[n-1 to 0]
        right_set.push(elem)
    
    while (right_set.has_elements()) {
       candidate = right_set.pop();
       if (left_set.has_elements() && left_set.max() <= candidate <= right_set.min()) {
           break;
       } else if (!left.has_elements() && candidate <= right_set.min() {
            break;
       }
       left_set.push(candidate);
    }
    
    return candidate
    
    0 讨论(0)
  • 2021-02-09 16:31
    1. Create array of ints called mags, and int variable called maxMag.
    2. For each element in source array check if element is greater or equal to maxMag.
    3. If is: add element to mags array and set maxMag = element.
    4. If isn't: loop through mags array and remove all elements lesser.

    Result: array of magnitude poles

    0 讨论(0)
  • 2021-02-09 16:34

    Interesting question, I am having my own solution in C# which I have given below, read the comments to understand my approach.

    public int MagnitudePoleFinder(int[] A)
    {
        //Create a variable to store Maximum Valued Item i.e. maxOfUp
        int maxOfUp = A[0];
    
        //if list has only one value return this value
        if (A.Length <= 1) return A[0];
    
        //create a collection for all candidates for magnitude pole that will be found in the iteration
        var magnitudeCandidates = new List<KeyValuePair<int, int>>();
    
        //add the first element as first candidate
        var a = A[0];
        magnitudeCandidates.Add(new KeyValuePair<int, int>(0, a));
    
        //lets iterate
        for (int i = 1; i < A.Length; i++)
        {
            a = A[i];
            //if this item is maximum or equal to all above items ( maxofUp will hold max value of all the above items)
            if (a >= maxOfUp)
            {
                //add it to candidate list
                magnitudeCandidates.Add(new KeyValuePair<int, int>(i, a));
                maxOfUp = a;
            }
            else
            {
                //remote all the candidates having greater values to this item
                magnitudeCandidates = magnitudeCandidates.Except(magnitudeCandidates.Where(c => c.Value > a)).ToList();
            }
        }
        //if no candidate return -1
        if (magnitudeCandidates.Count == 0) return -1;
        else
            //return value of first candidate
            return magnitudeCandidates.First().Key;
    }
    
    0 讨论(0)
  • 2021-02-09 16:39

    For an O(n) algorithm:

    1. Count the largest element from n[0] to n[k] for all k in [0, length(n)), save the answer in an array maxOnTheLeft. This costs O(n);
    2. Count the smallest element from n[k] to n[length(n)-1] for all k in [0, length(n)), save the answer in an array minOnTheRight. This costs O(n);
    3. Loop through the whole thing and find any n[k] with maxOnTheLeft <= n[k] <= minOnTheRight. This costs O(n).

    And you code is (at least) wrong here:

    if (A[i] > left_max && A[i] <= right_min) // <-- should be >= and <=
    
    0 讨论(0)
  • 2021-02-09 16:39

    How about the following code? I think its efficiency is not good in the worst case, but it's expected efficiency would be good.

        int getFirstPole(int* a, int n)
    {
        int leftPole = a[0];
        for(int i = 1; i < n; i++)
        {
            if(a[j] >= leftPole)
            {
                int j = i;
                for(; j < n; j++)
                {
                    if(a[j] < a[i])
                    {
                        i = j+1;  //jump the elements between i and j                   
                        break;
                    }
                    else if (a[j] > a[i])
                        leftPole = a[j];
                }
                if(j == n) // if no one is less than a[i] then return i
                    return i;
            }
        }
        return 0;
    }
    
    0 讨论(0)
提交回复
热议问题