[算法] 求解和值最大子段及绝对值最小子段
求和值最大子段:不断对已有子段加值,当和值小于0时舍弃子段;由遍历决定复杂度O(n);
求和值绝对值最小子段:求前n子段和值,然后求最小差值;求最小差值时使用了排序后遍历的方法,由排序决定复杂度O(nlogn);这里求最小差值的问题中,在某些限制条件下(数组波动不大)可以用桶排序进一步降低时间复杂度,见求最小差值,但因有条件限制不稳定,故不选取;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | # -*- coding: utf-8 -*- array = ( 4 , - 3 , 2 , 5 , - 9 , 6 ) #array = (4, -3, 1) #array = (-4, -3, -2, -5, -9, -6) # 求解和值最大子段 # 算法关键是将和值对整体不利的子序列舍弃,修减问题树 # 复杂度O(n) def big_sub(): try_sum = 0 try_start = 0 start = 0 end = 0 sum = 0 big = array[ 0 ] big_index = 0 for i in range ( 0 , len (array)): if try_sum > = 0 : try_sum + = array[i] if (try_sum > sum ): sum = try_sum end = i start = try_start else : # try_sum < 0 try_sum = array[i] try_start = i if array[i] > big: big = array[i] big_index = i if sum = = 0 : sum = big start = end = big_index print array[start:end + 1 ], print sum # 求解和值绝对值最小子段 # 算法关键是求解前n子段和后进行排序,找数列最小差值 # 因为有排序过程存在,所以时间复杂度达到O(nlogn) # 快排 def split(tuples, start, end): middle = tuples[end] index = start - 1 for i in range (start, end + 1 ): if tuples[i][ 1 ] < = middle[ 1 ]: index + = 1 temp = tuples[index] tuples[index] = tuples[i] tuples[i] = temp return index def sort_tuples(tuples, start, end): if start < end: index = split(tuples, start, end) sort_tuples(tuples, start, index - 1 ) sort_tuples(tuples, index + 1 , end) def small_sub(): sum = 0 sums = [] for i in range ( 0 , len (array)): sum + = array[i] sums.append((i, sum )) # 排序 sort_tuples(sums, 0 , len (sums) - 1 ) # 找最小差值 small_diff = - 1 small_diff_index = 0 for i in range ( 0 , len (array) - 1 ): diff = sums[i + 1 ][ 1 ] - sums[i][ 1 ] if (small_diff < 0 ) or (diff < small_diff): small_diff = diff small_diff_index = i if (sums[small_diff_index][ 0 ] < sums[small_diff_index + 1 ][ 0 ]): start = sums[small_diff_index][ 0 ] end = sums[small_diff_index + 1 ][ 0 ] minus = False else : end = sums[small_diff_index][ 0 ] start = sums[small_diff_index + 1 ][ 0 ] minus = True print array[start + 1 :end + 1 ], if minus: print - small_diff else : print small_diff if __name__ = = "__main__" : big_sub() small_sub() |
注:为处理全负数组,在求最大和子段时,用了一个空间big保存最大元素值;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步