【问题标题】:Find a triplet that sum to a given value gives TLE in Java在Java中找到一个给定值的总和给出TLE的三元组
【发布时间】:2021-05-24 15:38:33
【问题描述】:

我正在尝试解决这个问题https://practice.geeksforgeeks.org/problems/triplet-sum-in-array-1587115621/1# 我使用 HashMap 来存储所有可能的总和以及我已存储总和的索引数组。这是我的代码

  class Solution
 {

//Function to find if there exists a triplet in the array A[] which sums up to X. 
  
 public static boolean find3Numbers(int arr[], int n, int X){ `
  
 HashMap<Integer,ArrayList<Pair>> hm=new HashMap<>();

    for(int i=0;i<n;i++){
        for(int j=i+1;j<n;j++){
            if(!hm.containsKey(arr[i]+arr[j])){hm.put(arr[i]+arr[j],new ArrayList<>());}
            Pair pair=new Pair(i,j);
            ArrayList<Pair> list=hm.get(arr[i]+arr[j]);
            list.add(pair);
            hm.put(arr[i]+arr[j],list);
        }
    }
    for(int i=0;i<n;i++){
        if(hm.containsKey(X-arr[i])){
            ArrayList<Pair> p=hm.get(X-arr[i]);
            for(int k=0;k<p.size();k++){
                if(p.get(k).ind1!=i && p.get(k).ind2!=i)return true;
            }
        }
    }
    return false;
}
public static class Pair{
    int ind1;
    int ind2;
    Pair(int i,int j){
        ind1=i;
        ind2=j;
    }
}
}

请告诉我为什么我会得到 TLE?

【问题讨论】:

  • 什么是 TLE?另外,你能在这里描述任务而不是链接到它吗?链接可能会中断,从而使问题对其他人毫无用处。另请参阅How to Ask

标签: java arrays data-structures hashmap sum


【解决方案1】:

从问题描述来看,时间复杂度应该是O(n^2)。但是这部分代码不是 O(n^2),最坏的情况是 O(n^3)

for(int i=0;i<n;i++){
    if(hm.containsKey(X-arr[i])){
        ArrayList<Pair> p=hm.get(X-arr[i]);
        for(int k=0;k<p.size();k++){
            if(p.get(k).ind1!=i && p.get(k).ind2!=i)return true;
        }
    }
}

因为 ArrayList 的大小可以是 n^2。例如,[1,1,1,1,1]。总和为 2 的对列表为 10。

(n - 1) + (n - 2) + (n - 3) + ... + 2 + 1 = (n - 1) * n / 2 ≈ n^2

可能的解决方案:

public static boolean find3Numbers(int arr[], int n, int X){
    Arrays.sort(arr);
    for (int i = 1; i < n - 1; i++) { // from the second to penultimate
        int l = 0; // first index
        int r = n - 1; // last index
        while (l < i && r > i) {
            int sum = arr[l] + arr[r] + arr[i];
            if (sum == X)
                return true;
            if (X > sum)
                l++;
            else
                r--;
        }
    }
    return false;
}
  • 时间复杂度 - O(n^2)
  • 空间复杂度 - O(1)

这种方法也称为“双指针技术”,广泛用于算法问题。如果你有兴趣,你可以在网上找到很多资料。

【讨论】:

  • 描述问题是解决问题的一半,不适合答案。如果您还提供 O(n^2) 解决方案,您更有可能获得支持。
  • 好的,我在答案中添加了解决方案
  • 太棒了。还请描述初学者的解决方案。在写关于 SO 的答案时,尽可能彻底。
  • 如果不对数组进行排序,有没有办法在 O(n^2) 中解决这个问题?我只是好奇。
【解决方案2】:
 package com.test;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;

    public class TripletSum {
        public static void main(String[] args) {
        int[] arr = { 1, 2, -3, 4, 9, -2, -1 };
        System.out.println(TripletSum.getTriplet(arr, 1));
}

    private static List<List<Integer>> getTriplet(int[] arr, int target) {
        Arrays.sort(arr);
        List<List<Integer>> allTriplets = new ArrayList<List<Integer>>();
         for (int i = 0; i < arr.length - 2; i++) {
            int sum = target - arr[i];
            int start = i + 1;
            int end = arr.length - 1;
            while (start < end) {
            int t = arr[start] + arr[end];
            if (t == sum) {
                allTriplets.add(Arrays.asList(arr[start], arr[end], arr[i]));
                start++;
                end--;
            } else if (t < sum) {
                start++;
            } else {
                end--;
            }
        }

    }

         return allTriplets;

}

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-16
    • 1970-01-01
    相关资源
    最近更新 更多