从给定数组中查找最低总和

发布于 2025-02-05 08:37:32 字数 947 浏览 1 评论 0原文

我有一个数字[3,4,5,1,2,3,1]查找3 Pairs sub sequence say sub [] sub [0]< sub [1]> sub [2],总和这3个元素并获取最低总和。

示例:

对于[3,4,5,1,2,3,1],我可以选择[1,2,1]这里1< 2> 1因此,总和是1+2+1 = 4最小。

约束:

数组尺寸最高1,00,000 每个元素大小为1至1,00,00,00,000

我的方法是使用3个嵌套进行循环,并获得最小总和,这不是有效的方法。

public long process(List<Integer> list) {
   int n = list.size();
   long output = Long.MAX_VALUE;
   for(int i=0; i<n; i++) {
      for(int j=i+1; j<n; j++) {
       if(list.get(i) < list.get(j)) {
          for(int k=j+1; k<n; k++) {
            if(list.get(j) > list.get(k)) {
               output = Math.min(output, list.get(i)+list.get(j)+list.get(k));
             }
          }
       }
      }
   }
   return output;
}

如何以较小的时间复杂性有效地解决该程序?

I have an array of numbers [3,4,5,1,2,3,1] find 3 pairs sub sequence say sub[] such that sub[0] < sub[1] > sub[2], sum those 3 elements and get the minimum sum.

Example:

For [3,4,5,1,2,3,1], I can select [1,2,1] here 1<2>1 so sum is 1+2+1 = 4 which is minimum.

Constraints:

array size upto 1,00,000
each element size is 1 to 1,00,00,00,000

My approach is using 3 nested for loops and getting the minimum sum which is not an efficient way.

public long process(List<Integer> list) {
   int n = list.size();
   long output = Long.MAX_VALUE;
   for(int i=0; i<n; i++) {
      for(int j=i+1; j<n; j++) {
       if(list.get(i) < list.get(j)) {
          for(int k=j+1; k<n; k++) {
            if(list.get(j) > list.get(k)) {
               output = Math.min(output, list.get(i)+list.get(j)+list.get(k));
             }
          }
       }
      }
   }
   return output;
}

How do solve this program efficiently with less time complexity?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

吹梦到西洲 2025-02-12 08:37:32

让我提供一个解决方案,其时间复杂性为o(n),空间复杂性为o(n)。您必须通过三次阵列迭代,并存储两个阵列以达到最低元素。我受到@SomeOne的评论的启发。请记住,该解决方案可以假设任何sub [i]&lt; sub [j]&gt; sub [k]必须保持:i&lt; J&LT; k

可以轻松修改解决方案以覆盖i&lt; = j&lt; = k的情况。如果该方程式没有强制性,那么问题就会变得更加琐碎。只需找到前三个最小元素,我们知道sub [i]&lt; sub [j]&gt; sub [k]保持。确保第三个(最大)与其他一个不同。尽管您没有指定我上面提到的规则,但我相信问题要您遵守该规则 - 否则这将非常微不足道。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Stackoverflow {
    public static void main(String[] args) {
        ArrayList<Integer> numbers = new ArrayList<>(Arrays.asList(3,4,5,1,2,3,1));
        System.out.println(process(numbers));
    }
    
    public static long process(List<Integer> list) {
        if(list.size() < 3) return -1; // not enough elements
        
        int n = list.size();
        
        int[] minLeft = new int[n];
        int[] minRight = new int[n];
        
        minLeft[0] = list.get(0);
        minRight[minRight.length - 1] = list.get(list.size() - 1);
        
        // store the minimum elements from left up to current index
        for(int i=1; i<n; i++) {
            minLeft[i] = Math.min(list.get(i), minLeft[i - 1]);
        }
        
        
        // store the maximum elements from right up to current index
        for(int i=n - 2; i>=0; i--) {
            minRight[i] = Math.min(list.get(i), minRight[i+1]);
        }
        
        
        long sum = Integer.MAX_VALUE;
        
        for(int i=1; i<n-1; i++) {
            sum = Math.min(sum, minLeft[i - 1] + list.get(i) + minRight[i + 1]);
        }
        
        return sum;
    }
}

输出:

4

Let me provide a solution whose time complexity is O(n) and space complexity is O(n). You have to iterate through the array thrice and also store two arrays for the minimum elements. I was inspired by the comment made by @Someone. Please keep in mind that this solution makes the assumption that for any sub[i] < sub[j] > sub[k] this must hold: i < j < k.

Solution can be modified easily to cover the cases where i <= j <= k. If it's not compulsory for this equation to hold, then question becomes more trivial. Just find first three minimum element and we know that sub[i] < sub[j] > sub[k] holds. Make sure that the third one (largest one) is different than the others. Although you didn't specify the rule I mentioned above, I believe question wants you to comply with that rule - otherwise that would be very trivial.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Stackoverflow {
    public static void main(String[] args) {
        ArrayList<Integer> numbers = new ArrayList<>(Arrays.asList(3,4,5,1,2,3,1));
        System.out.println(process(numbers));
    }
    
    public static long process(List<Integer> list) {
        if(list.size() < 3) return -1; // not enough elements
        
        int n = list.size();
        
        int[] minLeft = new int[n];
        int[] minRight = new int[n];
        
        minLeft[0] = list.get(0);
        minRight[minRight.length - 1] = list.get(list.size() - 1);
        
        // store the minimum elements from left up to current index
        for(int i=1; i<n; i++) {
            minLeft[i] = Math.min(list.get(i), minLeft[i - 1]);
        }
        
        
        // store the maximum elements from right up to current index
        for(int i=n - 2; i>=0; i--) {
            minRight[i] = Math.min(list.get(i), minRight[i+1]);
        }
        
        
        long sum = Integer.MAX_VALUE;
        
        for(int i=1; i<n-1; i++) {
            sum = Math.min(sum, minLeft[i - 1] + list.get(i) + minRight[i + 1]);
        }
        
        return sum;
    }
}

Output:

4

混浊又暗下来 2025-02-12 08:37:32

相同的代码和添加的次要约束以考虑角案例:

public class minimumSubsequence {
    public static void main(String[] args) {
        ArrayList<Integer> numbers = new ArrayList<>(Arrays.asList(3, 4, 5, 1, 2, 3, 1));
        System.out.println(minimumSubsequence.getMinimumSum(numbers));
    }

    public static long getMinimumSum(List<Integer> arr) {
        if (arr.size() < 3)
            return -1;

        int n = arr.size();
        int[] minLeft = new int[n];
        int[] minRight = new int[n];
        minLeft[0] = arr.get(0);
        minRight[n - 1] = arr.get(arr.size() - 1);

        //find min from left
        for (int i = 1; i < n; i++) {
            minLeft[i] = Math.min(arr.get(i), minLeft[i - 1]);
        }
        // find min from right
        for (int i = n - 2; i >= 0; i--) {
            minRight[i] = Math.min(arr.get(i), minRight[i + 1]);
        }

        long sum = Integer.MAX_VALUE;
        int flag = 0;
        for (int i = 1; i < n - 1; i++) {
            if (minLeft[i - 1] < arr.get(i) && minRight[i + 1] < arr.get(i)) {
                sum = Math.min(sum, minLeft[i - 1] + arr.get(i) + minRight[i + 1]);
                flag = 1;
            }
        }
        if (flag == 0) return -1;
        return sum;

    }

}

The same code with minor constraints added to consider corner cases:

public class minimumSubsequence {
    public static void main(String[] args) {
        ArrayList<Integer> numbers = new ArrayList<>(Arrays.asList(3, 4, 5, 1, 2, 3, 1));
        System.out.println(minimumSubsequence.getMinimumSum(numbers));
    }

    public static long getMinimumSum(List<Integer> arr) {
        if (arr.size() < 3)
            return -1;

        int n = arr.size();
        int[] minLeft = new int[n];
        int[] minRight = new int[n];
        minLeft[0] = arr.get(0);
        minRight[n - 1] = arr.get(arr.size() - 1);

        //find min from left
        for (int i = 1; i < n; i++) {
            minLeft[i] = Math.min(arr.get(i), minLeft[i - 1]);
        }
        // find min from right
        for (int i = n - 2; i >= 0; i--) {
            minRight[i] = Math.min(arr.get(i), minRight[i + 1]);
        }

        long sum = Integer.MAX_VALUE;
        int flag = 0;
        for (int i = 1; i < n - 1; i++) {
            if (minLeft[i - 1] < arr.get(i) && minRight[i + 1] < arr.get(i)) {
                sum = Math.min(sum, minLeft[i - 1] + arr.get(i) + minRight[i + 1]);
                flag = 1;
            }
        }
        if (flag == 0) return -1;
        return sum;

    }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文