C# 从一个数组中选取两个数字,使总和为常数
我遇到了一个算法问题。假设我收到一张信用卡,只想从当地商店购买两件商品。我想买两件东西,加起来就是信用卡的全部价值。输入数据有三行 第一行是贷方,第二行是项目的总金额,第三行列出了所有项目的价格 样本数据1: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 我的想法是首
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(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我知道我发布这篇文章是一年半之后的事,但我碰巧遇到了这个问题,想添加输入 如果存在解决方案,则您知道解决方案中的两个值都必须小于目标和
同样,这是一个只有在数据集需要的情况下才值得实现的优化。我知道这是一年半后发布的,但我碰巧遇到了这个问题,希望添加输入 如果存在解决方案,则您知道解决方案中的两个值都必须小于目标和