找出列表中的任何两个元素是否总和为 R 中的特定值
Find out if any two elements in a list sum to a specific value in R
这是一道经典的面试题。给定一个列表 numbers
和一个特定值 k
,找出 numbers
中的任意两个元素在求和时是否等于 k
。如何在 r
中用单遍算法而不是穷举搜索来解决这个问题?
实际上:在 r
中写入最优化函数,该函数接收列表 numbers
和特定值 k
,returning TRUE
如果 numbers
中有两个元素相加等于 k
。如果没有,return FALSE
.
这个问题可以表述为:numbers
中是否有a
和b
,使得:
a + b = k
?考虑到您已经知道 k
,并假设实际上有两个数字相加后等于 k
,可以假设:
a = k - b
或 b = k - a
.
因此,通过 k - numbers
,我们基本上可以求解上述两个方程的右侧。例如:
numbers <- c(10, 12, 6, 3)
和 k <- 9
。 k - numbers
会 return c(-1, -3, 3, 6)
。看到 3 和 6 是怎么出现的了吗?
要在 R 中完成所有这些,可以定义一个函数
sum_finder <- function(numbers, k) {
diff_sequence <- k - numbers
condition <- any(numbers %in% diff_sequence)
return(condition)
}
或者简单地说:
sum_finder <- function(numbers, k) {
return(any(numbers %in% (k - numbers)))
}
编辑: 出于基准测试目的,我将在这里发布到目前为止发布的解决方案和使用 microbenchmark::microbenchmark()
.
的性能结果
# as posted by @eduardokapp
function1 <- function(numbers, k) {
any(numbers %in% (k - numbers))
}
# as posted by @AnilGoyal
function2 <- function(numbers, k) {
any(apply(outer(numbers, numbers, `+`), 1, function(x){x == k}))
}
# Performance Comparison
numbers <- sample(500, 500)
k <- sample(500, 1)
microbenchmark::microbenchmark(
function1(numbers, k),
function2(numbers, k)
)
性能比较
单位:微秒
expr
min
lq
mean
median
uq
max
neval
function1(numbers, k)
13.651
21.277
39.58225
27.4485
40.1905
277.256
100
function2(numbers, k)
5061.088
5805.186
10971.04516
7571.6030
13316.1325
47782.874
100
我认为你只能在 baseR 中使用内置函数来做到这一点
我来演示一下-
- 使用
outer
构建数字向量的求和矩阵 say x
。我们将中间结果命名为 y
- 使用 apply 来检查
which
元素是否等于所需的数量,比如 k
。我使用 arr.ind
argument = T
以便输出再次是矩阵格式的索引。
- 创建一个包含
x
个值的最终矩阵,以获得所需的结果
x <- 25:40
k <- 61
y <- outer(x, x, `+`)
matrix(x[which(apply(y, 1, function(x){x == k}), arr.ind = T)], ncol = 2)
[,1] [,2]
[1,] 36 25
[2,] 35 26
[3,] 34 27
[4,] 33 28
[5,] 32 29
[6,] 31 30
[7,] 30 31
[8,] 29 32
[9,] 28 33
[10,] 27 34
[11,] 26 35
[12,] 25 36
我们看到有 12 个值组合满足您的条件。
注-1 对于像 sum
这样的任何交换运算,在这种情况下,输出将包含镜像,您可以通过取一半以上的值来过滤掉这些镜像,如果太想要了。
Note-2 如果你还想消除迭代自身的值,可以在进一步处理之前设置diag(y) <- 0
或diag(y) <- NA
编辑鉴于修改要求,执行此操作
x <- 25:40
k <- 61
sum(outer(x, x, `+`) == k) > 0
[1] TRUE
#OR
x <- 1:6
k <- 1
sum(outer(x, x, `+`) == k) > 0
[1] FALSE
这是一道经典的面试题。给定一个列表 numbers
和一个特定值 k
,找出 numbers
中的任意两个元素在求和时是否等于 k
。如何在 r
中用单遍算法而不是穷举搜索来解决这个问题?
实际上:在 r
中写入最优化函数,该函数接收列表 numbers
和特定值 k
,returning TRUE
如果 numbers
中有两个元素相加等于 k
。如果没有,return FALSE
.
这个问题可以表述为:numbers
中是否有a
和b
,使得:
a + b = k
?考虑到您已经知道 k
,并假设实际上有两个数字相加后等于 k
,可以假设:
a = k - b
或 b = k - a
.
因此,通过 k - numbers
,我们基本上可以求解上述两个方程的右侧。例如:
numbers <- c(10, 12, 6, 3)
和 k <- 9
。 k - numbers
会 return c(-1, -3, 3, 6)
。看到 3 和 6 是怎么出现的了吗?
要在 R 中完成所有这些,可以定义一个函数
sum_finder <- function(numbers, k) {
diff_sequence <- k - numbers
condition <- any(numbers %in% diff_sequence)
return(condition)
}
或者简单地说:
sum_finder <- function(numbers, k) {
return(any(numbers %in% (k - numbers)))
}
编辑: 出于基准测试目的,我将在这里发布到目前为止发布的解决方案和使用 microbenchmark::microbenchmark()
.
# as posted by @eduardokapp
function1 <- function(numbers, k) {
any(numbers %in% (k - numbers))
}
# as posted by @AnilGoyal
function2 <- function(numbers, k) {
any(apply(outer(numbers, numbers, `+`), 1, function(x){x == k}))
}
# Performance Comparison
numbers <- sample(500, 500)
k <- sample(500, 1)
microbenchmark::microbenchmark(
function1(numbers, k),
function2(numbers, k)
)
性能比较
单位:微秒
expr | min | lq | mean | median | uq | max | neval |
---|---|---|---|---|---|---|---|
function1(numbers, k) | 13.651 | 21.277 | 39.58225 | 27.4485 | 40.1905 | 277.256 | 100 |
function2(numbers, k) | 5061.088 | 5805.186 | 10971.04516 | 7571.6030 | 13316.1325 | 47782.874 | 100 |
我认为你只能在 baseR 中使用内置函数来做到这一点
我来演示一下-
- 使用
outer
构建数字向量的求和矩阵 sayx
。我们将中间结果命名为y
- 使用 apply 来检查
which
元素是否等于所需的数量,比如k
。我使用arr.ind
argument =T
以便输出再次是矩阵格式的索引。 - 创建一个包含
x
个值的最终矩阵,以获得所需的结果
x <- 25:40
k <- 61
y <- outer(x, x, `+`)
matrix(x[which(apply(y, 1, function(x){x == k}), arr.ind = T)], ncol = 2)
[,1] [,2]
[1,] 36 25
[2,] 35 26
[3,] 34 27
[4,] 33 28
[5,] 32 29
[6,] 31 30
[7,] 30 31
[8,] 29 32
[9,] 28 33
[10,] 27 34
[11,] 26 35
[12,] 25 36
我们看到有 12 个值组合满足您的条件。
注-1 对于像
sum
这样的任何交换运算,在这种情况下,输出将包含镜像,您可以通过取一半以上的值来过滤掉这些镜像,如果太想要了。Note-2 如果你还想消除迭代自身的值,可以在进一步处理之前设置
diag(y) <- 0
或diag(y) <- NA
编辑鉴于修改要求,执行此操作
x <- 25:40
k <- 61
sum(outer(x, x, `+`) == k) > 0
[1] TRUE
#OR
x <- 1:6
k <- 1
sum(outer(x, x, `+`) == k) > 0
[1] FALSE