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代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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代码如下:

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
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代码如下:

1
2
3
4
5
6
7
8
9
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 @   nxf_rabbit75  阅读(768)  评论(0编辑  收藏  举报
编辑推荐:
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
阅读排行:
· DeepSeek火爆全网,官网宕机?本地部署一个随便玩「LLM探索」
· 开发者新选择:用DeepSeek实现Cursor级智能编程的免费方案
· Tinyfox 发生重大改版
· 独立开发经验谈:如何通过 Docker 让潜在客户快速体验你的系统
· 小米CR6606,CR6608,CR6609 启用SSH和刷入OpenWRT 23.05.5
一、连续数组求和Leetcode 53 最大子序和Leetcode 560 和为K的子数组Leetcode 523 连续的子数组和
点击右上角即可分享
微信分享提示