递归:将整数数组切割为总和相等的两部分 - 在一次传递中
使用递归,找到一个索引,将数组分成两部分,以使两部分的总和相等。
切的意思是像用刀一样切。 所有索引 <= 结果的单元格的总和必须等于索引 >= 的所有单元格的总和。 到结果。 任何细胞都不能被遗漏或成为两侧的一部分。
数组包含任意整数(即正数、负数和零)。
如果没有这样的索引,则返回-1
。
不允许您分配堆对象。
您必须一次性完成此操作。
您必须使用递归来完成此操作(即不能使用循环结构)。
可以是任何语言或伪代码。
忘记添加此:您无法修改数组
Using recursion, find an index that cuts an array in two parts so that both parts have equal sum.
Cut means to cut like with a knife. All the cells with index <= to the result must be equal in their sum to the all the cells with index > to the result. No cells can be left off or be part of both sides.
The arrays contains arbitrary integers (i.e. positives, negatives, and zeros).
If there is no such index return -1
.
You are not allowed to allocate heap objects.
You must do it in a single pass.
You must do it with recursion (i.e. cannot use loop constructs).
Can be in any language or pseudocode.
Forgot to add this: You cannot modify the array
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
这是一种利用 Ruby 返回多个值的能力的方法。 第一个值是分割的索引(如果存在),第二个值是每一半的总和(如果没有找到分割,则为整个数组的总和):
像这样调用它:
结果如下:
编辑:
这里是稍微修改的版本以解决 onebyone.livejournal.com 的评论。 现在数组中的每个索引仅被访问一次:
Here's a way to do it that takes advantage of Ruby's ability to return multiple values. The first value is the index for the split (if it exists), the second is the sum of each half (or the sum of the whole array if no split is found):
Calling it like this:
Results in this:
EDIT:
Here's a slightly modified version to address onebyone.livejournal.com's comments. Now each index in the array is accessed only once:
使用递归进行迭代是一个微不足道的转换,因此我们假设您知道如何做到这一点。
如果您使用“一次传递”来构建自己的“总和到该索引”的数组,并且可以对该数组进行另一次传递,我可以看到如何做到这一点。 只需迭代第二个数组并从 sum[last] 中减去 sum[x] 即可。 如果您发现结果 = sum[x] 的情况,您将返回 x。 如果不这样做则返回-1。
正如 Neil N 提到的,如果你为递归定义“pass”非常松散,这样整个递归实际上可以多次访问索引,那么你可以省去第二个数组。
经过一番思考后,我怀疑这个想法是让您只访问每个数组元素一次(按顺序),并使用递归的内置堆栈属性来消除对任何第二个数组的需要。
您要做的就是编写递归例程以将其当前索引的数组值保存在本地,将该值添加到传入的“sum_of_array”值中,然后在下一个最高索引(如果有)上调用自身。 如果没有下一个最高索引,它将把总和保存到全局中,现在每个堆栈递归调用都可以使用该全局索引。 每个例程通过检查其总和与全局总和来结束。 如果是一半,则返回其索引。 否则返回-1。 如果调用自身返回非 -1,则跳过最后一步并返回该值。 我将在伪 Ada 中展示
此代码应具有以下属性:
Iterating with recursion is a trivial transformation, so we'll assume you know how to do that.
If you use your "one pass" to build your own array of "sum to this index", and can make another pass on that array, I could see how to do it. Just iterate through that second array and subtract sum[x] from sum[last]. If you ever find a situation where the result = sum[x] you return x. If you don't then return -1.
As Neil N mentioned, if you define "pass" very loosely for recursion, such that the entire recursion can actually visit indices multiple times, then you could dispense with the second array.
After thinking about this a bit, I suspect the idea is to get you to only visit every array element once (in order), and to use recursion's built-in stack property to get rid of the need for any second array.
What you do is write your recursive routine to save off it's current index's array value in a local, add that value to a passed in "sum_of_array" value, then call itself on the next highest index (if there is one). If there isn't a next highest index, it saves the sum into a global, which is now available to every stacked recursive call. Each routine finishes by checking its sum against the global sum. If it is half, then it returns its index. Otherwise it returns -1. If a non -1 was returned from a call to itself, this last step is skipped and that value is returned. I'll show in pseudo-Ada
This code should have the properties that:
该方法的调用如下。
这可以减少为仅使用单个总和并且目标为零。
现在该方法的调用方式如下。
The method is called as follows.
This can be reduced to use only a single sum and targeting zero.
The method is now called as follows.
看一下下面的内容,仅使用 1 个索引,假设数组的索引是从 1 开始的:
Take a look at the following, using only 1 index, assume array's indexes are 1-based:
我的版本:
注意:如果返回的索引是 5,我的意思是 sum(anArray[:5]) == sum(anArray[5:])。 “极值”也是有效的(其中空切片的总和为零),即如果整个数组的总和为零,则 0 和 len(anArray) 也是有效的切割。
My version:
Note: if the index returned is 5, I mean that sum(anArray[:5]) == sum(anArray[5:]). The "extremes" are also valid (where the sum of an empty slice is meant to be zero), i.e. if the sum of the whole array is zero, then 0 and len(anArray) are also valid cuts.
这是 Erlang 中的一个实现,因为我正在学习它,这似乎是一个有趣的挑战。 这个想法无耻地抄袭了佩斯托的解决方案。
Here's an implementation in Erlang, since I'm learning it and this seemed like an interesting challenge. Idea shamelessly cribbed from Pesto's solution.
Haskell:
你的规则有些误导。 您要求在堆上不分配任何对象,但恕我直言,没有解决方案使算法没有
O(n)
的空间要求,即堆栈随着对象的长度线性增长。列表和尾部调用是不可能的,因为函数必须检查递归调用的返回值。Haskell:
Your rules are somewhat misleading. You require that no objects are to be allocated on the heap, but IMHO there is no solution where the algorithm does not have space requirements of
O(n)
, i.e. the stack grows linearly with the length of the list and tail calls are not possible because the function has to inspect the return values from the recursive call.C/C++/Java 中的代码:
使用以下语法调用:
Code in C/C++/Java:
Call using the following syntax: