Finding two non-subsequent elements in array which sum is minimal

前端 未结 13 1016
小蘑菇
小蘑菇 2021-02-05 03:40

Intro: As far as I could search, this question wasn\'t asked in SO yet.
This is an interview question.
I am not even specifically looking for a code sol

13条回答
  •  滥情空心
    2021-02-05 04:00

    Algorithm:

    1. Find the minimum, avoiding the end indices. (1 O(n) pass)
    2. Find the minimum, avoiding the end indices and the index of (1) and adjacent indices. (1 O(n) pass)
    3. Find the minimum, avoiding the end indices and the index of (1) (1 O(n) pass)
    4. Find the minimum, avoiding the end indices and the index of (3) and adjacent indices. (1 O(n) pass)
    5. Return the minimum of the sums (1) + (2), (3) + (4), if they exist.

    Passes 3 and 4 are meant to pass the case [4, 2, 1, 2, 4] = 4 by finding both 2s.

    public static int minSumNonAdjNonEnd(int[] array)
    {
        // 1. Find minimum
        int minIdx1 = -1;
        int minValue1 = Integer.MAX_VALUE;
        for (int i = 1; i < array.length - 1; i++)
        {
            if (array[i] < minValue1)
            {
                minIdx1 = i;
                minValue1 = array[i];
            }
        }
        // 2. Find minimum not among (1) or adjacents.
        int minIdx2 = -1;
        int minValue2 = Integer.MAX_VALUE;
        for (int i = 1; i < array.length - 1; i++)
        {
            if ((i < minIdx1 - 1 || i > minIdx1 + 1) && (array[i] < minValue2))
            {
                minIdx2 = i;
                minValue2 = array[i];
            }
        }
        boolean sum1Exists = (minIdx1 > -1 && minIdx2 > -1);
        int sum1 = minValue1 + minValue2;
    
        // 3. Find minimum not among (1).
        int minIdx3 = -1;
        int minValue3 = Integer.MAX_VALUE;
        for (int i = 1; i < array.length - 1; i++)
        {
            if ((i != minIdx1) && (array[i] < minValue3))
            {
                minIdx3 = i;
                minValue3 = array[i];
            }
        }
    
        // 4. Find minimum not among(3) or adjacents.
        int minIdx4 = -1;
        int minValue4 = Integer.MAX_VALUE;
        for (int i = 1; i < array.length - 1; i++)
        {
            if ((i < minIdx3 - 1 || i > minIdx3 + 1) && (array[i] < minValue4))
            {
                minIdx4 = i;
                minValue4 = array[i];
            }
        }
        boolean sum2Exists = (minIdx3 > -1 && minIdx4 > -1);
        int sum2 = minValue3 + minValue4;
    
        if (sum1Exists)
        {
            if (sum2Exists)
                return Math.min(sum1, sum2);
            else
                return sum1;
        }
        else
        {
            if (sum2Exists)
                return sum2;
            else
                throw new IllegalArgumentException("impossible");
        }
    }
    

    This performs 4 linear searches, for a complexity of O(n).

    Test cases:

    System.out.println(minSumNonAdjNonEnd(new int[] {5, 2, 4, 6, 3, 7}));
    System.out.println(minSumNonAdjNonEnd(new int[] {1, 2, 3, 3, 2, 1}));
    System.out.println(minSumNonAdjNonEnd(new int[] {4, 2, 1, 2, 4}));
    System.out.println(minSumNonAdjNonEnd(new int[] {2, 2, 1, 2, 4, 2, 6}));
    System.out.println(minSumNonAdjNonEnd(new int[] {2, 2, 3, 2}));
    
    5
    4
    4
    3
    Exception in thread "main" java.lang.IllegalArgumentException: impossible
    

提交回复
热议问题