C# 从一个数组中选取两个数字,使总和为常数

C# 从一个数组中选取两个数字,使总和为常数,c#,algorithm,C#,Algorithm,我遇到了一个算法问题。假设我收到一张信用卡,只想从当地商店购买两件商品。我想买两件东西,加起来就是信用卡的全部价值。输入数据有三行 第一行是贷方,第二行是项目的总金额,第三行列出了所有项目的价格 样本数据1: 200 7 150 24 79 50 88 345 3 这意味着我有200美元买两件东西,一共7件。我应该按照200=150+50 样本数据2: 8 8 2 1 9 4 4 56 90 3 这表明我有8美元从总共8篇文章中挑选两个项目。答案是第4项和第5项,因为8=4+4 我的想法是首

我遇到了一个算法问题。假设我收到一张信用卡,只想从当地商店购买两件商品。我想买两件东西,加起来就是信用卡的全部价值。输入数据有三行

第一行是贷方,第二行是项目的总金额,第三行列出了所有项目的价格

样本数据1:

200
7
150 24 79 50 88 345 3
这意味着我有200美元买两件东西,一共7件。我应该按照
200=150+50

样本数据2:

8
8
2 1 9 4 4 56 90 3
这表明我有8美元从总共8篇文章中挑选两个项目。答案是第4项和第5项,因为
8=4+4

我的想法是首先创建数组,然后选择任何项目,比如项目x。创建另一个数组(如“保留”),从原始数组中删除x

从信用证中减去x的价格,得到残值,并检查“剩余”是否包含残值

这是我的C语言代码

我的两个问题:

  • 复杂性如何?我认为是O(n2)
  • 算法有什么改进吗?当我使用示例2时,我很难获得正确的索引。因为数组中有两个“4”,所以它总是返回第一个索引,因为IndexOf(String)报告此实例中第一次出现的指定字符串的从零开始的索引

  • 您只需按
    O(nlogn)
    时间对数组排序即可。然后,在
    O(nlogn)
    时间内,对每个元素
    A[i]
    再次进行二进制搜索
    S-A[i]


    编辑:正如Heuster所指出的,您可以使用两个指针(一个从开始,另一个从结束)在线性时间内解决排序数组上的2和问题

    您只需按
    O(nlogn)
    时间对数组排序即可。然后,在
    O(nlogn)
    时间内,对每个元素
    A[i]
    再次进行二进制搜索
    S-A[i]

    编辑:正如Heuster所指出的,您可以使用两个指针(一个从开始,另一个从结束)在线性时间内解决排序数组上的2和问题

    创建价格的
    HashSet
    。然后按顺序检查。类似于:

    HashSet<int> items = new HashSet<int>(itemsList);
    
    int price1 = -1;
    int price2 = -1;
    foreach (int price in items)
    {
        int otherPrice = 200 - price;
        if (items.Contains(otherPrice))
        {
            // found a match.
            price1 = price;
            price2 = otherPrice;
            break;
        }
    }
    if (price2 != -1)
    {
        // found a match.
        // price1 and price2 contain the values that add up to your target.
        // now remove the items from the HashSet
        items.Remove(price1);
        items.Remove(price2);
    }
    
    HashSet items=新的HashSet(itemsList);
    整数价格1=-1;
    整数价格2=-1;
    foreach(项目的整数价格)
    {
    int otherPrice=200——价格;
    if(项目包含(其他价格))
    {
    //找到了一根火柴。
    价格1=价格;
    价格2=其他价格;
    打破
    }
    }
    如果(价格2!=-1)
    {
    //找到了一根火柴。
    //price1和price2包含与目标值相加的值。
    //现在从HashSet中删除这些项
    项目。移除(价格1);
    项目。移除(价格2);
    }
    
    这是创建
    哈希集的O(n)
    。因为
    HashSet
    中的查找是O(1),所以
    foreach
    循环是O(n)。

    创建价格的
    HashSet
    。然后按顺序检查。类似于:

    HashSet<int> items = new HashSet<int>(itemsList);
    
    int price1 = -1;
    int price2 = -1;
    foreach (int price in items)
    {
        int otherPrice = 200 - price;
        if (items.Contains(otherPrice))
        {
            // found a match.
            price1 = price;
            price2 = otherPrice;
            break;
        }
    }
    if (price2 != -1)
    {
        // found a match.
        // price1 and price2 contain the values that add up to your target.
        // now remove the items from the HashSet
        items.Remove(price1);
        items.Remove(price2);
    }
    
    HashSet items=新的HashSet(itemsList);
    整数价格1=-1;
    整数价格2=-1;
    foreach(项目的整数价格)
    {
    int otherPrice=200——价格;
    if(项目包含(其他价格))
    {
    //找到了一根火柴。
    价格1=价格;
    价格2=其他价格;
    打破
    }
    }
    如果(价格2!=-1)
    {
    //找到了一根火柴。
    //price1和price2包含与目标值相加的值。
    //现在从HashSet中删除这些项
    项目。移除(价格1);
    项目。移除(价格2);
    }
    

    这是创建
    哈希集的O(n)
    。因为
    HashSet
    中的查找是O(1),所以
    foreach
    循环是O(n)。

    这个问题称为2-sum。参见,例如,

    这个问题称为二和问题。请参阅,例如,

    这里有一个O(N)时间复杂度和O(N)空间的算法:-

    1. Put all numbers in hash table.
    2. for each number Arr[i] find Sum - Arr[i] in hash table in O(1)
    3. If found then (Arr[i],Sum-Arr[i]) are your pair that add up to Sum
    
    注意:-当Arr[i]=Sum/2时,只有失败的情况才能出现,然后您可以得到假阳性,但您可以始终检查O(N)中的数组中是否有两个Sum/2

    以下是O(N)时间复杂度和O(N)空间中的一个算法:-

    1. Put all numbers in hash table.
    2. for each number Arr[i] find Sum - Arr[i] in hash table in O(1)
    3. If found then (Arr[i],Sum-Arr[i]) are your pair that add up to Sum
    

    注意:-只有当Arr[i]=Sum/2时才是失败的情况,那么你可以得到假阳性,但你可以随时检查O(N)中的数组中是否有两个Sum/2

    我知道我发布这篇文章是一年半之后的事,但我碰巧遇到了这个问题,想添加输入

    如果存在解决方案,则您知道解决方案中的两个值都必须小于目标和

  • 在值数组中执行二进制搜索,搜索目标和(可能存在也可能不存在)

  • 二进制搜索将以查找总和或小于总和的最近值结束。这是使用前面提到的解决方案在阵列中搜索时的初始高值。任何高于新的起始高值的值都不能出现在解决方案中,因为它大于目标值

  • 此时,您已经在日志(n)时间内消除了一块数据,否则将在O(n)时间内消除

  • 同样,这是一个只有在数据集需要的情况下才值得实现的优化。

    我知道这是一年半后发布的,但我碰巧遇到了这个问题,希望添加输入

    如果存在解决方案,则您知道解决方案中的两个值都必须小于目标和

  • 在值数组中执行二进制搜索,搜索目标和(可能存在也可能不存在)

  • 二进制搜索将以查找总和或小于总和的最近值结束。这是使用前面提到的解决方案在阵列中搜索时的初始高值。任何高于新的起始高值的值都不能出现在解决方案中,因为它大于目标值

  • 此时,您已经在日志(n)时间中删除了一块数据,即w