Java 如何在数组中找到两个和为k的元素

Java 如何在数组中找到两个和为k的元素,java,arrays,Java,Arrays,假设给定一个未排序整数数组,如下所示: A = {3,4,5,1,4,2} 输入:6 输出:{5,1},{4,2} 如何在O(n)或O(logn)中执行此操作。如有任何建议,将不胜感激 更新: 我们能写出比这更有效的东西吗 for(int i=0;i<array.length-1;i++) { if(array[i]+array[i+1]==6) System.out.println("{"+array[i]+","+array[i+1]+"}");

假设给定一个未排序整数数组,如下所示:

A = {3,4,5,1,4,2}
输入:
6
输出:
{5,1},{4,2}

如何在O(n)或O(logn)中执行此操作。如有任何建议,将不胜感激

更新: 我们能写出比这更有效的东西吗

for(int i=0;i<array.length-1;i++)  
{  
    if(array[i]+array[i+1]==6)  
        System.out.println("{"+array[i]+","+array[i+1]+"}");  
}  

for(inti=0;i与您的另一个问题一样,O(logn)是不可能的,因为您必须检查整个数组。但是O(n)或多或少是可能的

如果可能的整数范围相对较小-也就是说,如果它在n的常数因子范围内-则可以编写:

final boolean[] seen = new boolean[max - min + 1];
for(final int a : A)
{
    if(seen[input - a - min])
        System.out.println("{" + (input - a) + "," + a + "}");
    seen[a - min] = true;
}
如果没有,则可以执行相同的操作,但使用
哈希集
而不是数组:

final Set<Integer> seen = new HashSet<Integer>();
for(final int a : A)
{
    if(seen.contains(input - a))
        System.out.println("{" + (input - a) + "," + a + "}");
    seen.add(a);
}
final Set seen=new HashSet();
对于(最终int a:a)
{
如果(见。包含(输入-a))
System.out.println(“{”(input-a)+”,“a++”);
见。添加(a);
}

但这并不能保证O(n)时间。

如果输入数组中存储的数字仅为正数,那么我将创建另一个由K+1数组列表元素组成的数组K。其中K是需要它们相加的数字。 只有两个小于k的数字可以加起来等于k(假设我们处理的是正整数},或者在特殊情况下{0,k})。 然后我将遍历输入数组的所有元素,对于小于或等于k的每个int m,我将获取其索引,并将该索引添加到索引m处的ArrayList k数组中。 然后我将迭代数组K的前半部分,对于每个索引I,其中存储了一些int,我将找到互补索引[K-I],并查看其中是否有任何值。如果有,那么这些就是你的对。 顺便说一句,这是O(n)

公共静态void findElemtsThatSumTo(int data[],int k){
列表arrayK[]=新列表[k+1];
对于(int i=0;i
publicstaticvoidmain(String[]args){
//TODO自动生成的方法存根
int arr[]={4,2,6,8,9,3,1};
整数和=10;
int arr1[]=新的int[sum];

对于(int x=0;xO(n)复杂度和O(n)额外内存的问题,我的小回答。此代码段返回所有唯一索引和K的元素对

/**
 * Returns indices of all complementary pairs in given {@code arr} with factor {@code k}. Two elements {@code arr[i]} and {@code arr[j]} are
 * complementary if {@code arr[i] + arr[j] = k}.
 * Method returns set of pairs in format {@literal [i,j]}. Two pairs {@literal [i,j]} and {@literal [j,i]} are treated as same, and only one pair
 * is returned.
 * Method support negative numbers in the {@code arr}, as wel as negative {@code k}.
 * <p>
 * Complexity of this method is <t>O(n)</t>, requires <t>O(n)</t> additional memory.
 *
 * @param arr source array
 * @param k   factor number
 * @return not {@code null} set of all complementary pairs in format {@literal [i,j]}
 */
public static Set<String> getComplementaryPairs(int[] arr, int k) {
    if (arr == null || arr.length == 0)
        return Collections.emptySet();

    Map<Integer, Set<Integer>> indices = new TreeMap<>();

    for (int i = 0; i < arr.length; i++) {
        if (!indices.containsKey(arr[i]))
            indices.put(arr[i], new TreeSet<>());
        indices.get(arr[i]).add(i);
    }

    Set<String> res = new LinkedHashSet<>();

    for (Map.Entry<Integer, Set<Integer>> entry : indices.entrySet()) {
        int x = entry.getKey();
        int y = k - x;

        if (x == y) {
            int size = entry.getValue().size();

            if (size < 2)
                continue;

            Integer[] ind = entry.getValue().toArray(new Integer[size]);

            for (int j = 0; j < size - 1; j++)
                for (int m = j + 1; m < size; m++)
                    res.add(String.format("[%d,%d]", ind[j], ind[m]));
        } else if (x < y && indices.containsKey(y))
            for (int j : entry.getValue())
                for (int m : indices.get(y))
                    res.add(String.format("[%d,%d]", j, m));
    }

    return res;
}
/**
*返回给定{@code arr}中具有因子{@code k}的所有互补对的索引。有两个元素{@code arr[i]}和{@code arr[j]}
*如果{@code arr[i]+arr[j]=k}是互补的。
*方法返回格式为{@literal[i,j]}的对集。两个对{@literal[i,j]}和{@literal[j,i]}被视为相同,并且只有一个对
*他回来了。
*方法支持{@code arr}中的负数,以及负数{@code k}。
*
*该方法的复杂度为O(n),需要O(n)个额外内存。
*
*@param arr源阵列
*@param k因子数
*@return不是{@code null}格式为{@literal[i,j]}的所有互补对的集合
*/
公共静态集getComplementaryPairs(int[]arr,int k){
如果(arr==null | | arr.length==0)
返回集合;
映射索引=新树映射();
对于(int i=0;i
可能重复[a和b两个数组。查找所有元素对(a1,b1),使a1属于数组a,b1属于数组b,其和a1+b1=k]()另请参见您的示例,您假设两个整数相邻。这是故意的吗?对于
k=6
,如果
a={2,3,4},则不会返回任何内容
,即使
{2,4}=6
。此外,您的算法是O(n),因此没有比O(n)更有效的算法可以编写,但可以编写更正确的算法。您能否解释HashSet方法的问题,因为您说它不能保证O(n)时间。感谢详细的解决方案。在这个数组上输入
{6,4,5,1,4,2,0}
我得到的答案是
索引[6,0]的数字加起来是6。索引[3,2]的数字加起来是6。索引[5,1]的数字加起来是6。索引[5,4]的数字加起来是6。
有什么问题吗?这些是ineces,而不是值。数组索引是从零开始的,所以索引5处的项是整数2,索引4处的项是整数4,所以2+4是6。一切似乎都正常。您可以将println语句转换为打印值,而不是索引,但索引更有用(IMO)因为你可以在许多不同的指数上有相同的数字。你能解释一下这是如何回答这个问题的,还是更有效?
public static void main(String[] args) {
    // TODO Auto-generated method stub

    int arr[]={4,2,6,8,9,3,1};
    int sum=10;
    int arr1[]=new int[sum];


    for(int x=0;x<arr.length;x++)
    {
        arr1[arr[x]]++;
    }

    for(int y=0;y<arr.length;y++)
    {
        if(arr1[sum-arr[y]]==1)
        {
            System.out.println(arr[y]+","+(sum-arr[y]));
        }
    }

}
/**
 * Returns indices of all complementary pairs in given {@code arr} with factor {@code k}. Two elements {@code arr[i]} and {@code arr[j]} are
 * complementary if {@code arr[i] + arr[j] = k}.
 * Method returns set of pairs in format {@literal [i,j]}. Two pairs {@literal [i,j]} and {@literal [j,i]} are treated as same, and only one pair
 * is returned.
 * Method support negative numbers in the {@code arr}, as wel as negative {@code k}.
 * <p>
 * Complexity of this method is <t>O(n)</t>, requires <t>O(n)</t> additional memory.
 *
 * @param arr source array
 * @param k   factor number
 * @return not {@code null} set of all complementary pairs in format {@literal [i,j]}
 */
public static Set<String> getComplementaryPairs(int[] arr, int k) {
    if (arr == null || arr.length == 0)
        return Collections.emptySet();

    Map<Integer, Set<Integer>> indices = new TreeMap<>();

    for (int i = 0; i < arr.length; i++) {
        if (!indices.containsKey(arr[i]))
            indices.put(arr[i], new TreeSet<>());
        indices.get(arr[i]).add(i);
    }

    Set<String> res = new LinkedHashSet<>();

    for (Map.Entry<Integer, Set<Integer>> entry : indices.entrySet()) {
        int x = entry.getKey();
        int y = k - x;

        if (x == y) {
            int size = entry.getValue().size();

            if (size < 2)
                continue;

            Integer[] ind = entry.getValue().toArray(new Integer[size]);

            for (int j = 0; j < size - 1; j++)
                for (int m = j + 1; m < size; m++)
                    res.add(String.format("[%d,%d]", ind[j], ind[m]));
        } else if (x < y && indices.containsKey(y))
            for (int j : entry.getValue())
                for (int m : indices.get(y))
                    res.add(String.format("[%d,%d]", j, m));
    }

    return res;
}