当前位置: 首页 > 知识库问答 >
问题:

给定一个数字列表和一个数字k,返回列表中的任意两个数字加起来是否等于k

符学
2023-03-14

这个问题是在谷歌编程采访中提出的。我想到了两种方法

>

  • 找出长度的所有子序列。这样做时,计算两个元素的和,并检查它是否等于k。如果是,请打印“是”,否则继续搜索。这是一种暴力手段。

    按非降序排列数组。然后从数组的右端开始遍历数组。假设我们有一个排序数组,{3,5,7,10},我们希望总和是17。我们将从元素10开始,索引=3,让我们用“j”来表示索引。然后包含当前元素并计算所需的_sum=sum-current_元素。之后,我们可以在数组[0-(j-1)]中执行二元或三元搜索,以确定是否存在一个值等于所需_和的元素。如果我们找到这样一个元素,我们可以分解,因为我们找到了一个长度为2的子序列,其和就是给定的和。如果我们找不到任何这样的元素,则减小j的索引,并重复上述步骤,得到长度=长度-1的子阵列,即在这种情况下排除索引3处的元素。

    这里我们考虑了数组可以有正整数也可以有负整数。

    你能提出比这更好的解决方案吗?也许是DP解决方案?一个可以进一步降低其时间复杂性的解决方案。

  • 共有3个答案

    公羊涛
    2023-03-14

    这是一个具有O(n)时间复杂度和O(n)空间的java实现。其想法是创建一个HashMap,其中包含每个数组元素w.r.t目标的补码。如果找到了补码,我们有两个数组元素,它们的和就是目标。

     public boolean twoSum(int[] nums, int target) {
        if(nums.length == 0 || nums == null) return false;
    
        Map<Integer, Integer> complementMap = new HashMap<>();
    
        for (int i = 0; i < nums.length; i++) {
             int curr = nums[i];
             if(complementMap.containsKey(target - curr)){
               return true;
             }
        complementMap.put(curr, i);
        }
      return false;
    }
    
    沈华晖
    2023-03-14

    下面是一个Java实现,其时间复杂度与用于排序数组的算法相同。请注意,这比您的第二个想法要快,因为我们不需要每次检查一个数字时在整个数组中搜索匹配的伙伴。

    public static boolean containsPairWithSum(int[] a, int x) {
        Arrays.sort(a);
        for (int i = 0, j = a.length - 1; i < j;) {
            int sum = a[i] + a[j];
            if (sum < x)
                i++;
            else if (sum > x)
                j--;
            else
                return true;
        }
        return false;
    }
    

    归纳证明:设a[0,n]为长度为n1和p=(p1,p2)的数组,其中p1,p2是整数,p1

    基本情况(i=0, j=n):a[0,-1]不包含p1和a[n, n 1]不包含p2。

    假设:a[0,i-1]不包含a[i]a[j1,n]不包含p2。

    步骤情况(i至i 1或j至j-1):

    1. 假设p1=a[i]。然后,由于p1 a[j]

    因为每次迭代,a[0,i-1]a[j1,n],都不包含p1p2a[i,j]确实包含p1p2。最后,a[i]=p1a[j]=p2算法返回true。

    公西宏峻
    2023-03-14

    借助O(N)时间复杂度中的set可以很容易地解决这个问题。首先将数组的所有元素添加到set中,然后遍历数组的每个元素,检查K-ar[i]是否存在于set中。

    以下是复杂度为O(N)的java代码:

    boolean flag=false;
    HashSet<Long> hashSet = new HashSet<>();
    for(int i=0;i<n;i++){
        if(hashSet.contains(k-ar[i]))flag=true;
        hashSet.add(ar[i]);
    }
    if(flag)out.println("YES PRESENT");
    else out.println("NOT PRESENT");
    
     类似资料:
    • 问题内容: 我有一个数字清单。我也有一定数目 该总和由我列表中的几个数字得出(我可能/可能不知道它是由多少个数字组成的)。是否有一种快速算法来获取可能的数字列表?用Python编写会很棒,但是伪代码也很好。(除Python:P之外,我什么都看不到) 例 注意: 我确实知道算法,可以从大小为n的列表中找到哪些数字总和为另一个数字(但是我无法读取C#,也无法检查它是否满足我的需求。我在Linux上,尝

    • 我试图确定数组列表中的数字是否可以被antoher数组列表中的所有数字整除。我下面的代码输出列表中的所有数字,这些数字可以被中的任何除数整除。我想输出列表中所有除数都可以整除的值,而不是它们中的任何一个。例如,如果我有listdiv=[1,2,3,,5,8]和listdivisor=[2,4]。预期的输出应该是8,但此代码输出2和8。 非常感谢。我们将非常感谢您的努力!

    • 例如,它将以1开始,然后将2添加到列表中,得到1-2。然后将检查1-2以查看序列是否符合递增/递减的规则。当它符合时,将3相加,得到1-2-3。然后检查1-2-3,这不符合。所以我们会回到1,现在加3而不是2,给出1-3等等。 我在用C。

    • 有人能告诉我下面的解决方案是否可能“一次性”实现吗? 给定一个数字列表和一个数字,返回列表中的任意两个数字加起来是否等于。 例如,给定

    • 您有已排序整数的列表。从每个列表中找到至少包含一个数字的最小范围。 例如, 这里最小的范围是,因为它包含中的、中的和中的。 我的做法是: null 但我面临的唯一问题是:假设一个列表中没有剩下的元素,我应该完成还是应该继续?

    • 下面是完整的问题: 问题3【30分】。编写一个包含两个正整数k和n的函数,其工作方式如下1。打印由数字1组成的长度k的所有递增序列。。。n 2。返回此类序列的数目。例如 打印序列的具体顺序由您决定。在数字之间加一个空格。别忘了用新行分隔序列。您的函数应该在合理的时间内对输入n、k进行处理,直到20。[提示:使用递归。您可能还想使用助手函数] 我的实现只打印第一个序列,然后停止。我哪里做错了? 这是