我正在尝试解决testdome在线考试中的问题。
问题是写一个函数,给定一个列表和一个目标和,返回任何两个不同元素的从零开始的索引,其总和等于目标总和。如果没有这样的元素,函数应该返回null。
这是我的代码,它只有75%为真,25%对时间超过
using System;
using System.Linq;
using System.Collections.Generic;
class TwoSum
{
public static Tuple<int, int> FindTwoSum(IList<int> list, int sum)
{
var result = from n1 in list
from n2 in list
where n1 + n2 == sum
select new Tuple<int, int>(list.IndexOf(n1), list.IndexOf(n2));
return result.FirstOrDefault();
}
public static void Main(string[] args)
{
Tuple<int, int> indices = FindTwoSum(new List<int>() { 1, 3, 5, 7, 9 }, 12);
Console.WriteLine(indices.Item1 + " " + indices.Item2);
}
}
您可以将我的代码粘贴到在线网站上并查看结果。 任何人都可以帮助我,所以我们100%真实。 :D
答案 0 :(得分:4)
这是您需要通过其他方法解决问题的案例之一。而不是对所有值进行交叉连接并找到匹配的第一个总和,而是要查找所有值并循环并检查当前项和总和的差异是否在该查找中。这样就可以得到最差的线性性能而不是多项式。
public static Tuple<int, int> FindTwoSum(IList<int> list, int sum)
{
var lookup = list.Select((x, i) => new { Index = i, Value = x })
.ToLookup(x => x.Value, x => x.Index);
for (int i = 0; i < list.Count; i++)
{
int diff = sum - list[i];
if (lookup.Contains(diff))
return Tuple.Create(i, lookup[diff].First());
}
return null;
}
答案 1 :(得分:4)
使用HashSet而不是LookUp稍微修改代码。
public static Tuple<int, int> FindTwoSum(IList<int> list, int sum)
{
var hs = new HashSet<int>();
list.ToList().ForEach(x => hs.Add(x));
for (int i = 0; i < hs.Count; i++)
{
var diff = sum - list[i];
if (hs.Contains(diff))
{
var index = list.IndexOf(diff);
return new Tuple<int, int>(i, index);
}
}
return null;
}
我已经尝试并测试并获得100%,即所有测试都通过,包括 &#34;具有大量元素的性能测试&#34;测试
答案 2 :(得分:3)
Atif的解决方案稍作修改,我们不需要先将列表复制到HashSet。
public static Tuple<int, int> FindTwoSum(IList<int> list, int sum)
{
HashSet<int> hs = new HashSet<int>();
for (int i = 0; i < list.Count; i++)
{
var needed = sum - list[i];
if (hs.Contains(needed))
{
return Tuple.Create(list.IndexOf(needed), i);
}
hs.Add(list[i]);
}
return null;
}
答案 3 :(得分:2)
public static Tuple<int, int> FindTwoSum(IList<int> list, int target)
{
var dict = new Dictionary<int, int>();
for (int i = 0; i < list.Count; i++)
{
var diff = target - list[i];
int j = -1;
if(dict.TryGetValue(diff, out j))
{
return Tuple.Create<int, int>(j, i);
}
dict[list[i]] = i;
}
return null;
}
答案 4 :(得分:1)
对您的版本稍作修改也会通过测试。但这不是100%正确。这告诉你Testdome上的测试用例不完整。我将把它留作一个错误的练习。
public static Tuple<int, int> FindTwoSum(IList<int> list, int sum)
{
var result = from n1 in list
join n2 in list
on n1 equals sum - n2
select new Tuple<int, int>(list.IndexOf(n1), list.IndexOf(n2));
return result.FirstOrDefault(x=>x.Item1!=x.Item2);
}
答案 5 :(得分:1)
使用juharr代码版本的非Linq扩展方法
public static Tuple<int, int> FindTwoSumImprovedNonLinq(IList<int> list, int sum)
{
for (int i = 0; i < list.Count; i++)
{
int diff = sum - list[i];
if (list.IndexOf(diff) > -1)
return Tuple.Create(i, list.IndexOf(diff));
}
return null;
}
答案 6 :(得分:1)
这是我的工作解决方案:
public static Tuple<int, int> FindTwoSum(IList<int> list, int sum)
{
var dictionary = new Dictionary<int, int>();
for (var i = 0; i < list.Count; i++)
{
var aim = sum - list[i];
if(dictionary.ContainsKey(aim))
{
return new Tuple<int, int> (dictionary[aim], i);
}
else if(!dictionary.ContainsKey(list[i]))
{
dictionary.Add(list[i], i);
}
}
return null;
}
答案 7 :(得分:1)
public static Tuple<int, int> FindTwoSum(IList<int> list, int sum)
{
int max = list.Max();
for (int i = 0; i < list.Count - 1; i++)
{
int first = list[i];
if (first + max == sum) return new Tuple<int, int>(i, list.IndexOf(max));
if (first + max < sum) continue;
for (int j = i+1; j < list.Count; j++)
{
int second = list[j];
if (sum == first + second)
{
return new Tuple<int, int>(i, j);
}
}
}
return null;
}
答案 8 :(得分:1)
这是通过所有4项测试的代码。然而,关于这个问题的abuncha问题令人感兴趣。基本测试:遍历列表,对于列表中的每个数字,遍历列表并找到它的对,即加在一起时与目标值相等的那一对。所以它是O(n ** 2)算法。第四次测试将其烧毁。这里有一个很大的提示,你只需要返回第一个匹配对。所以,要解决:
因此,通过输入列表排序,对于每个项目,在字典中搜索其对。如果没有,请在字典中搜索此项目,如果没有,请添加它。当你在字典中找到它的对时,设置你的回报然后去。
public class Item
{
public Item(int _val, int _loc) {
val = _val;
loc = _loc;
}
public int val;
public int loc;
}
class TwoSum
{
public static Tuple<int, int> FindTwoSum(IList<int> list, int sum)
{
Tuple<int, int> result = null;
Dictionary<int, Item> dictionary = new Dictionary<int, Item>();
int index = 0;
bool done = false;
do
{
int curr = list[index];
int pair = sum - list[index];
if (dictionary.ContainsKey(pair))
{
result = new Tuple<int, int>(index, dictionary[pair].loc);
done = true;
}
else
{
if (! dictionary.ContainsKey(curr))
{
Item found1 = new Item(curr, index);
dictionary.Add(curr, found1);
}
}
index++;
}
while (index < list.Count && !done);
return result;
}
答案 9 :(得分:0)
更简单的方法是:
public static Tuple<int, int> FindTwoSum(IList<int> list, int sum)
{
for (int i = 0; i < list.Count; i++)
{
// subtract the item to the sum to find the difference
int diff = sum - list[i];
// if that number exist in that list find its index
if (list.Contains(diff))
{
return Tuple.Create(i, list.IndexOf(diff));
}
}
return null;
}
这样你就不需要事先查询整个列表,但仍然是75%。
答案 10 :(得分:0)
int[] arr = new int[] { 1, 0, 2, 3, 4, 3 };
for (int i = 0; i < arr.Length; i++)
{
var requiredElements = arr.Select((item, index) => new { index, item }).Where(ind => ind.item.Equals(4 - arr[i])).ToList();
if (requiredElements.Count > 0)
{
foreach (var disp in requiredElements)
Console.WriteLine("Indexes are " + i.ToString() + ":" + disp.index);
}
break;
}
}
//其中4是目标 - ind.item.Equals(4 - arr [i])
答案 11 :(得分:-2)
public static Tuple FindTwoSum(IList list,int sum) {
public String getCookiesForHttpResult(SampleResult sampleResult) {
if (sampleResult instanceof HTTPSampleResult) {
HTTPSampleResult httpSampleResult = (HTTPSampleResult) sampleResult;
return httpSampleResult.getCookies();
}
// not HTTP result
return null;
}
}
这将有效