本文使用分治思想求解一个整型数组中的最大子序列,该算法的时间复杂度为NlogN,使用千万级的数据量计算结果的时间不超过0.5s。该算法使用了分治的思想:求解最大子序列的问题可以理解为将整个数组分成左右两部分,分别求解左边和 右边的最大子序列,并且还有一种情况是最大子序列在中间,此时可以可以直接从中间开始分别向左和向右遍历求解左右两边的最大子序列(由于此时假定最大子序列在中间,因而中间的元素肯定在最大子序列中),然后将两边的最大子序列相加就会得到最大子序列在中间时的子序列,此时当前数组就会有三个(左边,右边和中间)已经求得的最大子序列,现只需要比较这三个子序列的和即可,将最大和返回。具体的算法如下:
public class Solution { public long findMaxSubSequence(Integer[] arr) { // return maxSumRec(arr, 0, arr.length - 1); } // 求解最大子序列函数 private long maxSumRec(Integer[] arr, int left, int right) { // 递归调用的出口 if (left == right) { return arr[left]; } // 分别计算左边和右边的最大子序列 int center = (left + right) / 2; long maxLeftSum = maxSumRec(arr, left, center); long maxRightSum = maxSumRec(arr, center + 1, right); // 计算中间的最大子序列的左半部分的最大值 int maxLeftBorderSum = 0, leftBorderSum = 0; for (int i = center; i >= left; i--) { leftBorderSum += arr[i]; if (leftBorderSum > maxLeftBorderSum) { maxLeftBorderSum = leftBorderSum; } } // 计算中间的最大子序列的右半部分的最大值 int maxRightBorderSum = 0, rightBorderSum = 0; for (int i = center + 1; i <= right; i++) { rightBorderSum += arr[i]; if (rightBorderSum > maxRightBorderSum) { maxRightBorderSum = rightBorderSum; } } return max(maxLeftSum, maxRightSum, maxLeftBorderSum + maxRightBorderSum); } // 求解三个值中的最大值 private long max(long maxLeftSum, long maxRightSum, int maxBorderSum) { return maxLeftSum >= maxRightSum && maxLeftSum >= maxBorderSum ? maxLeftSum : (maxRightSum > maxBorderSum ? maxRightSum : maxBorderSum); } }
具体的实验程序如下:
import java.util.Date; import java.util.Random; public class App { public static void main(String[] args) { Integer[] arr = new Integer[10000000]; for (int i = 0; i < 10000000; i++) { arr[i] = new Random().nextInt(); } Solution solution = new Solution(); Long start = new Date().getTime(); long result = solution.findMaxSubSequence(arr); Long end = new Date().getTime(); System.out.println("结果为:" + result); System.out.print("所用时长为:" + (end - start)); } }
运行结果如下:
计算结果为:2147483164 所用时长为:447 Process finished with exit code 0
这是计算最大子序列的一种算法,现贴出一种更为完美的方法,其时间复杂度为O(N),代码量也得到了大大的简化,代码如下:
public class Solution { public long findMaxSubSequence(Integer[] arr) { long maxSum = 0, thisSum = 0; for (int i = 0; i < arr.length; i++) { thisSum += arr[i]; if (thisSum > maxSum) { maxSum = thisSum; } else if (thisSum < 0){ thisSum = 0; } } return maxSum; } }
由于本人也不甚理解,现只将代码帖于此处。
相关推荐
在本实验中,我们将探讨四个核心的算法问题:串匹配问题、最大连续子序列和问题、求众数问题以及最近点对问题。这些问题都属于算法设计与分析的范畴,通过解决这些问题,我们可以深入理解分治法和其他算法策略。 1....
其次,解决阶段,我们递归地对每个子序列执行相同的操作,即找出子序列的最大值和最小值。在最底层,子序列只有一个元素时,最大值和最小值就是这个元素本身。对于上述例子,{1, 5, 3, 9} 的最大值为 9,最小值为 1...
6. 算法设计思想:本资源展示了如何使用递归算法和分治法来解决最大子段和问题,展示了算法设计思想的应用。 7. 实验步骤:本资源提供了一个实验步骤,展示了如何使用分治法和递归算法来解决最大子段和问题。 8. ...
这两个问题都可以通过分治思想进行有效解决。 首先,寻找最大值和最小值。传统的做法是遍历整个数组,但采用分治法可以更快地完成这一任务。基本步骤如下: 1. 将数组分为两个相等(或近乎相等)的部分。 2. 分别...
动态规划是一种重要的算法,它的核心思想是通过解决子问题来构建原问题的最优解。与分治法相比,虽然两者都是通过分解问题来求解,但动态规划处理的问题子问题之间通常存在重叠,而非完全独立。这使得直接使用分治法...
**最大字段和问题**,也被称为**最大子序列和问题**,是指在给定的一组数字中找到一个连续子序列(或子数组),使得这个子序列的和最大。这个问题在实际应用中非常常见,比如在金融数据分析中寻找收益最大的投资组合...
它通过自底向上的计算和存储子问题解,有效地减少了计算复杂性,解决了许多实际问题,如最短路径、背包问题、最长公共子序列等。理解和掌握动态规划,对于解决计算机科学中的优化问题具有重大意义。
分治法是一种重要的算法设计策略,它将复杂的问题分解成较小的子问题,然后递归地解决这些子问题,最后将子问题的解合并成原问题的解。在这个实验中,我们应用分治法来寻找数组中的众数,即出现次数最多的元素。 在...
2. **最大子段和问题**:对于一个整数序列,找到和最大的连续子序列。这个问题可以通过Kadane's algorithm等分治策略解决。 3. **邮局选址问题**:在给定n个居民点的位置后,找到一个点作为邮局的位置,使得所有...
- 为了保证O(n log n)的时间复杂度,可以使用二分查找来快速定位子序列的最低买入价格。同时,对于每个分割点,我们只需要遍历一次子序列来更新最高卖出价格,所以总时间复杂度是线性的。 4. **代码实现**: - `...
归并排序是一种典型的分治算法,其核心思想是将待排序序列分为若干个子序列,每个子序列都是有序的,然后再把有序子序列合并为整体有序序列。归并排序的过程主要包括“分”和“合”两个阶段: 1. **分**:递归地将...
通过将序列分成多个小的子序列,然后在每个子序列中查找指定元素的位置,可以大大提高查找效率。同时,分治法也可以减少时间复杂度,提高算法的效率。 结论 通过本实验,学生可以学习如何使用分治法来解决元素查找...
然而,有些变种的问题,如寻找具有特定性质的最大子序列,可能会使用到分治的思想。 动态规划(Dynamic Programming,简称DP)是解决此类问题的常用方法。最大子段和问题非常适合使用动态规划来解决,因为它具有...
分治算法 分治算法是一种解决复杂问题的思想和方法,它将一个复杂的问题分解成两个或更多的...最大子序列和也是分治算法的实例,最大子序列和的问题我们可以使用动态规划的解法,但是也可以使用分治算法来解决问题。
使用动态规划思想,仅需一次遍历即可找到最大子序列和,时间复杂度为 \( O(N) \)。 ```cpp int maxSubSum4(const vector<int>& a) { int maxSoFar = 0, maxEndingHere = 0; for (auto x : a) { maxEndingHere = ...
我们可以将数组分为两半,分别求解左右两边的最大子序列和,然后选择其中较大的一个与跨边界的子序列进行比较,得到最终结果。不过,由于每次划分都要进行一次排序,这种方法的时间复杂度是O(n log n),在效率上不如...
"利用动态规划算法解决最长公共子序列问题" ...本文详细介绍了动态规划算法的思想、基本步骤和基本要素,并且应用动态规划算法解决了最长公共子序列问题,展示了动态规划算法在解决复杂问题中的重要作用。
分治算法是计算机科学中一种重要的解决问题的方法,它的核心思想是将一个复杂的问题分解成两个或更多的相同或相似的子问题,直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这种策略在处理大量...
并行图算法在子序列和计算中...通过结合分治思想、并行计算技术和图论模型,可以有效地解决一系列复杂的子序列和问题。随着并行计算技术的发展以及新型硬件平台的出现,未来该领域的研究将更加深入,应用也将更加广泛。
1. **分解问题**:将原问题转化为求解子问题,即找到数组中最大子序列和。 2. **解决子问题**:选取数组中间值 `middle`,将其左侧的子数组称为 `leftnums`,右侧子数组称为 `rightnums`。 3. 分别计算 `leftnums` ...