2.3 数据结构---数组(连续)

一、连续数组求和

Leetcode 53 最大子序和

题目描述:给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

示例:

 输入: [-2,1,-3,4,-1,2,1,-5,4], 输出: 6 

说明:解释: 连续子数组 [4,-1,2,1] 的和最大,为6。  

 

思路1:判断加了当前数之后,是否会使得和增大,如果不会,就判断当前的和是否比num这个数大,如果没有,则当前使和最大的数就是num这个数;如果会,就将其加入list中;如果当前的num加进去之后,使得和更低了,也将其加入list中,注意,这个list不是最终的list,为了得到最后的list,需要判断一下,当前得到的和是否比上一轮得到的和更大,如果没有,就不更新最终的list

思路1代码如下:

def maxSubArray(arr):
    res_list = []
    s = -2**31 #返回的和
    ts =-2**31 #每轮连续最大和
    Res_list = []
    for num in arr:
        if num > num + ts: #如果加了num后的结果比num一个值的时候还糟
            res_list = [num]
            ts = num
        else: #如果加了num之后的结果能够使得和变大
            res_list.append(num)
            ts += num
        if ts > s:#只有当前的和最大时,才输出
            s = ts
            Res_list = res_list
            print(ts)
            print(res_list)
    return s,Res_list

 

思路2:分治法

先将数组一分为二,对每个子数组求连续子序列和最大值,再合并;

分为三种情况,左子序列(加mid);右子序列(不加mid);从mid开始向左延伸,得到延伸之后的包括mid的左子序列最大值+不加mid向右延伸,得到延伸之后的右子序列最大值

取这三种情况里面的最大值,就作为本轮得到的最大连续子序列和。

举个例子:

思路2代码如下:

def maxSubArray1(array,start,last): #举例 [-2,1,-3,4,-1]
    mid = start + (last-start) // 2
    if start == last: #递归的出口是只有一个数字的时候,如果该数字大于0,就保留该数字并返回;如果该数字小于0,就丢弃该数字,返回0
        if array[start] > 0:
            return array[start]
        else:
            return 0
    '''
    左[-2,1,-3] --> 左[-2,1] 右[-3]
    右[4,-1]
    '''
    maxSumL = maxSubArray1(array,start,mid) #计算[start:mid]之间数的最长子序列和(包括mid)
    maxSumR = maxSubArray1(array,mid+1,last) #计算[mid+1:last]之间数的最长子序列和(不包括mid)

    '''因为上面的递归只计算了左半部分(包括mid),和右半部分分别的最长子序列和,那左边和右边加一起最大的最长子序列和是多少呢?
    或者说右半部分加mid的子序列和会不会是最大呢?'''
    maxsuml = 0
    maxsumr = 0
    temp_maxsum = 0
    i = mid
    while i >= start: #计算左半部分连同mid向左延伸最大和----从mid到start【逆序】,保留最大的连续和
        temp_maxsum += array[i]
        if temp_maxsum > maxsuml:
            maxsuml = temp_maxsum
        i -= 1

    i = mid + 1
    temp_maxsum = 0
    while i <= last: #计算右半部分向右延伸最大的和,从mid+1到last【顺序】
        temp_maxsum += array[i]
        if temp_maxsum > maxsumr:
            maxsumr = temp_maxsum
        i += 1

    maxSum = max(max(maxSumL,maxSumR),maxsuml+maxsumr)
    return maxSum

array=[-2,1,-3,4,-1,2,1,-5,4]
start=0
last=len(array)-1
res = maxSubArray1(array,start,last)
print(res)

  

思路3:贪心法  时间复杂度O(N^2)

思路3代码如下:

def maxSubArray2(A):
    if not A:
        return 0
    else:
        subSum=maxSum=A[0]
        for item in A[1:]:
            subSum=max(item,item+subSum)
            maxSum=max(subSum,maxSum)
        return maxSum

  

 

Leetcode 560 和为K的子数组

题目描述:

给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数。

示例:

输入:nums = [1,1,1], k = 2
输出: 2 , [1,1] 与 [1,1] 为两种不同的情况。

说明 :

  1. 数组的长度为 [1, 20,000]。
  2. 数组中元素的范围是 [-1000, 1000] ,且整数 k 的范围是 [-1e7, 1e7]。

 

 

 

Leetcode 523 连续的子数组和

题目描述:

给定一个包含非负数的数组和一个目标整数 k,编写一个函数来判断该数组是否含有连续的子数组,其大小至少为 2,总和为 k 的倍数,即总和为 n*k,其中 n 也是一个整数。

示例:

示例 1:
输入: [23,2,4,6,7], k = 6
输出: True
解释: [2,4] 是一个大小为 2 的子数组,并且和为 6

示例 2:
输入: [23,2,6,4,7], k = 6
输出: True
解释: [23,2,6,4,7]是大小为 5 的子数组,并且和为 42。

说明:

  1. 数组的长度不会超过10,000。
  2. 你可以认为所有数字总和在 32 位有符号整数范围内。
posted @ 2019-01-20 16:40  nxf_rabbit75  阅读(764)  评论(0编辑  收藏  举报