C++程序 找出给定数组的所有旋转中i*arr[i]的最大和
给定一个由n个整数组成的数组arr [],找到最大化i * arr [i]值的总和的最大值,其中i从0到n-1变化。
示例:
Method 1 : 该方法讨论了 Naive Solution ,需要O(n 2 )的时间量。
解决方案涉及在每次旋转中找到数组所有元素的总和,然后决定最大总和值。
- Approach: 一个简单的解决方案是尝试所有可能的旋转。计算每次旋转的i * arr [i]的求和并返回最大和。
- Algorithm:
- 旋转数组的所有值从0到n。
- 计算每个旋转的总和。
- 检查最大总和是否大于当前总和,然后更新最大总和。
- Implementation:
输出:
- 复杂度分析:
时间复杂度: O(n 2 ),因为我们使用嵌套循环。
辅助空间: O(1),因为我们没有使用任何额外的空间。
Method 2: 该方法讨论了 efficient solution ,可以在O(n)的时间内解决问题。在Naive Solution中,对于每个旋转计算了值。因此,如果可以在恒定时间内完成,则复杂度将减少。
- 方法: 基本方法是计算前一个旋转到新旋转的总和。这带来了一个相似之处,在这里只有第一个和最后一个元素的乘数发生了巨大变化,每个其他元素的乘数增加或减少1。因此,可以从当前的旋转总和计算下一个旋转的总和。
- 算法:
想法是使用先前旋转的值来计算旋转的值。当数组旋转1个位置时,i*arr[i]的总和发生以下变化。- arr[i-1]的乘数从0变为n-1,即arr[i-1]*(n-1)添加到当前值中。
- 其他项的乘数减少1.即从当前值中减去(cum_sum-arr[i-1]),其中cum_sum是所有数字的总和。
- 实现:
输出:
- 复杂度分析:
- 时间复杂度: O(n)。 因为要从0到n循环一次以检查所有旋转,而当前旋转的和是从前几个旋转计算出来的,时间复杂度为 O(1)。
- 辅助空间: O(1)。 因为不需要额外的空间,所以空间复杂度为 O(1) 。
- 方法: 假设数组是有序的。我们知道对于一个数组来说,当数组排序为升序时,最大和的数量是最大的。在旋转有序数组的情况下,我们可以旋转数组使其升序。所以,在这种情况下,需要找到中心点之后才能计算出最大和。
- 算法:
- 查找数组的中心点: 如果 arr[i] > arr[(i+1)%n],那么它就是中心点元素。 (i+1)%n 用于检查最后一个和第一个元素。
- 在获取中心点之后,可以通过与中心点的差来计算和。以当前元素为乘数,计算和时乘以中心点的差
- 实现:
- 复杂度分析:
- 时间复杂度: O(n) 只需要一次从0到n的遍历来查找中心点。需要另一个循环来查找和,所以复杂度仍为 O(n) 。
- 辅助空间: O(1)。 不需要额外的空间,所以辅助空间为 O(1) 。