我遇到了一个算法问题。假设我收到了一个信用卡,并希望从本地商店购买两件商品。我想买两件相当于信用额度的物品。输入数据有三行。
第一行是信用,第二行是商品的总金额,第三行是所有商品的价格。
样本数据1:
200
7
150 24 79 50 88 345 3
这意味着我有200美元购买两件商品,共有7件商品。我应该将第1项和第4项作为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#中的代码。
// Read lines from input file and create array price
foreach (string s in price)
{
int x = Int32.Parse(s);
string y = (credit - x).ToString();
index1 = Array.IndexOf(price, s) ;
index2 = Array.IndexOf(price, y) ;
remain = price.ToList();
remain.RemoveAt(index1);//remove an element
if (remain.Contains(y))
{
break;
}
}
// return something....
我的两个问题:
答案 0 :(得分:4)
您可以在O(nlogn)
时间内对数组进行简单排序。然后,对于每个元素A[i]
,在S-A[i]
时间内再次对O(nlogn)
进行二分搜索。
答案 1 :(得分:2)
创建HashSet<int>
价格。然后顺序完成它。像:
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);
}
这是O(n)来创建HashSet
。由于HashSet
中的查找为O(1),因此foreach
循环为O(n)。
答案 2 :(得分:1)
这个问题叫做2-sum。例如,参见http://coderevisited.com/2-sum-problem/
答案 3 :(得分:0)
这是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中数组中是否有两个Sum / 2 (N)
答案 4 :(得分:0)
我知道我发布这是一年半之后,但我碰巧遇到了这个问题,并希望添加输入。
如果存在解决方案,那么您知道解决方案中的两个值都必须小于目标总和。
在值数组中执行二进制搜索,搜索目标总和(可能存在也可能不存在)。
二进制搜索将以查找总和或最小值小于sum结束。这是使用前面提到的解决方案在数组中搜索时的起始值。高于新起始值的任何值都不能在解决方案中,因为它超过了目标值。
同样,这是一个优化,如果数据集需要它,可能只值得实现。