基本上我正在尝试做的是
static int NumdiffExponential(int[] arr, int K)
{
return (from i in arr
from j in arr
where (j - i) == K
select 1).Count();
}
除了线性时间外,最好使用单个LINQ查询,并且采用紧凑,可读和微优的方式。所以我想出的是尝试
static int NumdiffLinear(int[] arr, int K)
{
var counters =
arr
.GroupBy(i => i)
.ToDictionary(g => g.Key, g => g.Count());
return
counters
.Keys
.Aggregate(
0,
(total, i) => total + counters[i] * (counters.ContainsKey(K - i) ? counters[K - i] : 0)
);
}
不断出现0
,我无法弄清楚原因。
让我解释一下我认为它是如何运作的。如果我们有arr={1,1,1,2,3,3,5}
和K=2
,那么counter
就像
1->3, 2->1, 3->2, 5->1
让count = 0
。
我选择了密钥1
并看到1-K=-1
不是counter
中的密钥,因此count =
仍然是2
。与密钥3
相同。
对于密钥3-K=1
,我们counter
是3
中的密钥。密钥1
出现counter[3]=1
次出现(即2
,密钥count = 3*2 = 6
出现2次。因此count
成对(1,3) ,(1,3),(1,3),(1,3),(1,3),(1,3),(1,3)可以形成。
通过与上面相同的逻辑,由于对(3,5),我们再向count = 7
添加一个。所以答案是{{1}}。
我的算法或其实现有什么问题吗?
答案 0 :(得分:5)
更具可读性和更紧凑:
static int NumdiffLinear(int[] arr, int K)
{
return arr.SelectMany(v => arr, (a, b) => new { a, b })
.Where(s => s.b - s.a == K)
.Count();
}
这是一个具有相同原理的线性:
static int NumdiffLinear(int[] arr, int K)
{
int n = 1;
return arr.Select(value => new { value, index = n++ }) //Get number and index
.SelectMany(indexValue => arr.Skip(indexValue.index), (a, b) => new { a = a.value, b }) //Project it with the next elements in the array
.Where(s => s.a - s.b == K) //Do the math
.Count();
}
答案 1 :(得分:1)
替换
(total, i) => total + counters[i] * (counters.ContainsKey(K - i) ? counters[K - i] : 0)
通过
(total, i) => total + counters[i] * (counters.ContainsKey(i-K) ? counters[i-K] : 0)
答案 2 :(得分:1)
您应该添加而不是减去。例如,您知道自己拥有Quartile3
和key = 1
。然后你必须检查K = 2
是否存在。
在您的O(n ^ 2)算法中,检查key = (1+2)
。现在假设您只有J - I == K
和I
。如果条件为真,那么简单数学只需K
,那么J = K + I
就应该存在。
J
答案 3 :(得分:0)
您可以按照以下方式修复您的解决方案,
public int NumdiffLinear(int[] arr, int K)
{
var dupsDictionary =
arr
.GroupBy(i => i)
.ToDictionary(g => g.Key, g => g.Count());
return dupsDictionary.Keys.Aggregate(
0,
(total, i) =>
total +
dupsDictionary.Keys.Where(key => i - key == K)
.Sum(key => dupsDictionary[key]*dupsDictionary[i]));
}