LeetCode刷题之旅(简单-13):最大子序和

LeetCode Hot100 刷题笔记(4)—— 二叉树、图论 一、二叉树:二叉树的中序遍历,二叉树的最大深度,翻转二叉树,对称二叉树,二叉树的直径,二叉树的层序遍历,将有序数组转换为二叉搜索树,验证二叉搜索树,二叉搜索树中第 K 小的元素,二叉树的右视图,二叉树展开为链表,从前序与中序遍历序列构造二叉树,路径总和 III,二叉树的最近公共祖先,二叉树中的最大路径和。 二、图论:岛屿数量,腐烂的橘子,课程表,实现 Trie (前缀树)。 阅读详情

2019年6月8日

目录

题目:

解决方法1:暴力累计遍历法

思路:

性能结果:

解决方法2:动态规划

思路:

性能结果:

解决方法3:分治法(类似二分法)

思路:

性能结果:

解决方法4:其他网友的解法:利用中间数组过渡比较

思路:

性能结果:

小结:


题目:

 

解决方法1:暴力累计遍历法


public class MaximumSubordinateSum {
    public static void main(String[] args){
        List<Integer> list = new ArrayList<>();
        list.add(-2);
        list.add(1);
//        list.add(-3);
//        list.add(4);
//        list.add(-1);
//        list.add(2);
//        list.add(1);
//        list.add(-5);
//        list.add(4);
        int[] array = list.stream().mapToInt(Integer::intValue).toArray();
        int sum = maxSubArray(array);
        System.out.println("max = "+ sum);
    }


    public static int maxSubArray(int[] nums) {
        if (nums.length <= 0){
            return 0;
        }
        Integer max = nums[0];
        for (int i = 1 ; i<nums.length; i++){
            int temp = nums[i];
            if (temp > max){
                max = temp;
            }
            for (int j= i+1;j<nums.length;j++){
                temp += nums[j];
                if (temp > max){
                    max = temp;
                }
            }
        }
        return max;
    }
}

思路:

  • 基于JDK8的stream,用mapToInt对于Integer元素转int,创建数组入参;
  • 时间复杂度:O(n) = n*n;肉眼可见,结果不尽人意。(O(n)姑且木有实现,分治呢?)

 

性能结果:

解决方法2:动态规划


    /**
     * 主要是利用逐步求解,以连续数组结束位置为每一步的解,
     * sum其实就是记录了上一步骤的解,在这一步骤进行对比,如果上一步骤的解<0则舍弃。
     * 最终得到这一步骤解,与之前步骤解的最大值res进行比较,保存当前的最优解。
     * */
    public static int maxSubArrayV2(int[] nums) {
        int sum=0;
        int res=nums[0];
        // 1.一次遍历解决
        for(int num:nums){
            // 2.上次结果是否正数 ? 与新元素相加 : 取新元素
            sum=sum>0?(sum+num):num;
            // 3.该次结果与上次结果比较与赋值
            if(res<sum){
                res=sum;
            }
        }
        return res;
    }

 

思路:

  • 主要是利用逐步求解,以连续数组结束位置为每一步的解,sum其实就是记录了上一步骤的解,在这一步骤进行对比,如果上一步骤的解<0则舍弃。最终得到这一步骤解,与之前步骤解的最大值res进行比较,保存当前的最优解。

  • 这道题根据题目关键词,“最大”“连续”,可以判断是一道动态规划。

 

性能结果:

性能提高明显。

解决方法3:分治法(类似二分法)

 

    public static void main(String[] args){
        List<Integer> list = new ArrayList<>();
        list.add(-2);
        list.add(1);
//        list.add(-3);
//        list.add(4);
//        list.add(-1);
//        list.add(2);
//        list.add(1);
//        list.add(-5);
//        list.add(4);
        int[] array = list.stream().mapToInt(Integer::intValue).toArray();
        int sum = maxSubArrayPart(array,0,array.length-1);
        System.out.println("max = "+ sum);
    }

    //-------------------分治法----------------------
    /**
     * 通过递归分治不断的缩小规模,问题结果就有三种,左边的解,右边的解,以及中间的解(有位置要求,从中介mid向两边延伸寻求最优解),
     * 得到三个解通过比较大小,等到最优解。
     * */
    private static int maxSubArrayPart(int[] nums,int left,int right){
        if(left==right){
            return nums[left];
        }
        int mid=(left+right)/2;
        return Math.max(
                maxSubArrayPart(nums,left,mid),
                Math.max(
                        maxSubArrayPart(nums,mid+1,right),
                        maxSubArrayAll(nums,left,mid,right)
                )
        );
    }

    //左右两边合起来求解
    private static int maxSubArrayAll(int[] nums,int left,int mid,int right){
        int leftSum=Integer.MIN_VALUE;
        int sum=0;
        for(int i=mid;i>=left;i--){
            sum+=nums[i];
            if(sum>leftSum){
                leftSum=sum;
            }
        }
        sum=0;
        int rightSum=Integer.MIN_VALUE;
        for(int i=mid+1;i<=right;i++){
            sum+=nums[i];
            if(sum>rightSum){
                rightSum=sum;
            }
        }
        return leftSum+rightSum;
    }

 

思路:

  • 通过递归分治不断的缩小规模,问题结果就有三种,左边的解,右边的解,以及中间的解(有位置要求,从中介mid向两边延伸寻求最优解),得到三个解通过比较大小,等到最优解。

  • 解法3的时间复杂度是nlog(n);

  • 分治的计算工作主要在中间部分的计算中, 左右部分的分治事实上没什么贡献;

 

性能结果:

解决方法4:其他网友的优秀解法

class Solution {
    public int maxSubArray(int[] nums) {
         int[] dp = new int[nums.length+1];
        for (int i = 0; i < nums.length; i++) {
        	dp[i] = nums[i];
        }
        for (int i = 0; i < nums.length-1; i++) {
            dp[i+1] = Math.max(dp[i+1], dp[i]+nums[i+1]);
        }
        int maxx = dp[0];
        for (int i = 1; i < nums.length; i++)
        	maxx = Math.max(maxx, dp[i]);
        return maxx;
    }
}

思路:

  • 拷贝nums到dp数组;
  • 从dp第二项开始,元素取(nums逐项)和(相邻两个元素之和)的最大值;其本质就是通过中间数组进行了一次相加(delta);(我感觉还是未能描述清楚作者的意图)

性能结果:

 

小结:

只能说,好的代码,性能优化的非常好,思路也是新奇的很;多练习,多思考,从现在出发吧。

【LeetCode攻略】使用LeetCode刷题时你必须注意的几个点 LeetCode刷题攻略:详细介绍LeetCode刷题时的各种常用技巧和注意点 阅读详情

相关推荐

【中软软件测试笔试题】中国软件与技术服务股份有限公司笔试一卷

请分别写出ISO7层架构,并分别说明TCP、UDP协议分别在处于哪一层,以及TCP、 UPD协议有什么区别。 答:7 应用层 6 表示层 5 会话层 4 传输层 3网络层 2 数据链路层 1 物理层 第四层;UDP是面向无连接、不可靠数据传输协议; TCP是面向连接、可靠数据传输协议......

Yanan990830的博客 1815

c语言:最大的子序列和

算法思想:一个数A加上X大于等于A的条件是X必须大于等于零。数组a  长度size(1)最大子序列和maxsum = 0,部分和sum = 0,j=0(2)从数组a[0]处开始运行,sum = sum + a[j]       if  sum&gt; maxsum,maxsum =sum          else if  sum&lt; 0,sum = 0,                  e...

u010513327的博客 1656

Unity 2D精灵点击交互实现:从BoxCollider 2D到Event Trigger的完整指南

本文提供了Unity 2D精灵点击交互的完整实现指南。通过详细拆解BoxCollider 2D与Event Trigger两大核心组件的协同工作原理,手把手教你为Sprite Renderer添加点击、悬停等事件响应。文章包含从基础配置到进阶优化、性能调试的实战步骤,帮助开发者高效实现游戏世界内的对象交互,是Unity 2D开发的实用教程。

ansible6ops的博客 301

LeetCode 题解之 53. Maximum Subarray(连续子数组的最大和问题)

53. Maximum Subarray(连续子数组的最大和问题) 题目描述和难度 题目描述: 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 示例: 输入: [-2,1,-3,4,-1,2,1,-5,4], 输出: 6 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。 进阶: 如果你已经实现复杂度为 O(...

李威威的博客 1万+

Clipper库中文帮助文档

引言: 第一次接触Clipper,主要是想用来处理DXF中的图形,网上也有博友翻译过,但是可惜打不开,好像那个网站https://love2.io凉凉了,但是优快云上也有博友分享了CHM,看着只剩3个下载币的我好无奈,一怒之下花费两天的时间将英文CHM也翻译了一遍,主要还是想在翻译的同时好好的理解Clipper,为使用打下坚实的基础。当然我也会无私的奉献出来。 简单的认识一下Clipper:...

zefllj的博客 3421

终端以太网接入Internet实验

实验过程: 1.布局 2.连接 3.配置Route0和Route1 4.配置RIP 5.static: 6.查看Route0,Route1的路由表: 7.完成PC2和server0 IP地址,子网掩码和默认网关地址的配置: 8.命令行: 9.启动PC0桌面下的PPPoe宽带连接程序: 10.启动PC1桌面下的PPPoe宽带连接程序: 11.验证PC0和PC2的ICMP报文传输过程 12.验证PC1和server0的ICMP报文传输过程 关键命令说明

chaojidagouzi的博客 4082

LeetCode之最大连续子数组之和(简单 数组 动态规划)

问题描述: 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 示例: 输入: [-2,1,-3,4,-1,2,1,-5,4], 输出: 6 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。 进阶: 如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。 考虑最大和跟子数组最后一个元素arr[n-1]...

qq_27817327的博客 987

【Unity3D】关于unity中spriteAtlas的打包方案及使用时内存状态的多组对照实验

unity项目中使用精灵(Sprite)为了降低性能消耗,我们可以使用精灵图集(Sprite Atlas)技术,它能够将多个纹理合并成一个大纹理

云渊寒烬 5100

LeetCode刷题:最大子序和(day13)

LeetCode刷题:最大子序和(day13) 题目描述: 给定一个整数数组nums,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 示例: 输入: [-2,1,-3,4,-1,2,1,-5,4], 输出: 6 解释:连续子数组[4,-1,2,1] 的和最大,为6。 思路: 定义一个函数f(n),以第n个数为结束点的子数列的最大和,存在一个递推关...

bingeox的博客 206

EtherCat 从站开发中遇到的问题分享

EtherCat从站 AX58100

yu_arius的博客 2058

【控制模块算法】控制理论的进修之路

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录系列文章目录前言一、(经典)自动控制理论【本科阶段】二、现代控制理论【本科阶段】三、最优控制理论【硕士阶段】总结 前言 认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长! 本文先对对控制理论的理解做个简单的介绍,具体内容后续再更,其他模块可以参考去我其他文章 提示:以下是本篇文章正文内容 一、(经典)自动控制理论【本科阶段】 一般控制工程、自动化相关的考研专业课就是自动

qq_35635374的博客 1448

LeetCode刷题指南(一)

以下是我个人做题过程中的一些体会: 1. LeetCode的题库越来越大,截止到目前,已经有321个问题了。对于大多数人来说,没有时间也没有必要把所有题目都做一遍(时间充裕可以随意)。刷个100题左右应该就差不多了(可以考虑序号为前100多的题目,相对更经典一点)。 2. 从AC率高的开始做,难度从简单->中等,先不要做困难的。 3. 可以按照下文的面试出题频率顺序来做,从频率最高的一批开始。

Lnho的专栏 11万+

【WiFi】T830 MT7992 WMM测试修改操作说明

WiFi WMM(Wi-Fi Multimedia)是Wi-Fi联盟推出的一项技术,用于优化无线网络中的多媒体内容传输。WMM通过优先处理不同类型的数据流来改善网络性能,特别是在网络拥堵时。:WMM通过提供服务质量支持,确保语音、视频和其他多媒体应用在无线网络中获得优先处理。这有助于减少延迟和抖动,改善用户体验。:WMM将数据流分为四个优先级队列:语音、视频、最佳效果(Best Effort)和背景(Background)。语音和视频流通常被赋予更高的优先级,以确保它们在网络中得到及时传输。

wgl307293845的博客 1018

你有多久没有坚持过一件事情了?如果没有就来刷一轮力扣LeetCode

选择一样你想做的事情,坚持21天。如果没有想好,那就先来刷一轮力扣吧!~

车手只需要车和手,压力来自轮胎 1360

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

力扣 (LeetCode)-最大子序和,JavaScript数据结构与算法(数组)

Github来源:力扣 (LeetCode)|刷题打卡 | 求星星 ✨ | 给个❤️关注,❤️点赞,❤️鼓励一下作者[已开启]任务一:刷题打卡 * 10 篇大家好,我是魔王哪吒,很高兴认识...

程序员哆啦A梦,蓝胖子 2041

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

(leetcode) 力扣100 13最大子序和(动态规划&卡达内算法&分治法)

本文介绍了三种求解最大子数组和的算法:动态规划、Kadane算法和分治法。动态规划通过状态转移方程f(i)=max{f(i−1)+nums[i],nums[i]}求解,时间复杂度O(n)。Kadane算法在遍历数组时维护当前和,若为负则清零,每次更新最大值,空间更优。分治法采用类似归并排序的思路,将数组分为左右子区间分别求解后合并,需维护四个区间信息。三种方法都能正确求解,其中Kadane算法最简洁高效,分治法虽然复杂但有助于理解线段树等数据结构。

qq_62235017的博客 1111

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

力扣热题100(附刷题表版)

不仅方便查看题目,并且,在完成题目后,,我放在了结尾,大家自取,直接复制粘贴到。2. 字母异位词分组(中等)3. 最长连续序列(中等)1. 两数之和 (简单)时做记录,整理了下面。

2301_79966297的博客 2232

C语言力扣刷题13——最大子数组和[线性动态规划]

C语言,最大子数组和,动态规划,中等难度

why1249777255的博客 1056

动态规划LeetCode53最大子序和

最大子序和(最大子段和)是非常经典的动态规划题目,其变形题目也很多。 LeetCode53最大子序和 题目描述: 给定一个整数数组 nums,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 示例: 输入: [-2,1,-3,4,-1,2,1,-5,4],输出: 6解释:连续子数组[4,-1,2,1] 的和最大,为6。 题解: 1 cl...

weixin_30361641的博客 125

力扣(LeetCode)刷题,简单题(第13期)

力扣(LeetCode)定期刷题,每期10道题,业务繁重的同志可以看看我分享的思路,不是最高效解决方案,只求互相提升。 第1题:字符的最短距离 试题要求如下: 解答思路: 从左向右遍历,记录上一个字符 C 出现的位置 prev,那么答案就是 i - prev。 从右想做遍历,记录上一个字符 C 出现的位置 prev,那么答案就是 prev - i。 这两个值取最小就是答案。 回答(C语言): /** * Note: The returned array must be malloce

不脱发的程序猿 3363

力扣 (LeetCode)-13. 罗马数字转整数|刷题打卡

Github来源:力扣 (LeetCode)|刷题打卡 | 求星星 ✨ | 给个❤️关注,❤️点赞,❤️鼓励一下作者[已开启]任务一:刷题打卡 * 10 篇哪吒人生信条:如果你所学的东西 ...

程序员哆啦A梦,蓝胖子 878

力扣刷题day27|455分发饼干、376摆动序列、53最大子序和

力扣刷题day27|455分发饼干、376摆动序列、53最大子序和

Skyc的学习博客 447

前端JavaScript力扣HOT100刷题【1-50】

注:纯手打,如有错误欢迎评论区交流!编写此文是为了更好地学习前端知识,如果损害了有关人的利益,请联系删除!本文章将不定时更新,敬请期待!!!!!

testleaf.cn 1060

leetcode刷题笔记

leetcode刷题1. 算法1.1 动态规划1.1.1 简单题目 1. 算法 1.1 动态规划 1.1.1 简单题目 53.最大子序和 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 /* 用 f(i)代表以第i个数结尾的「连续子数组的最大和」 动态规划转移方程:f(i)=max{f(i−1)+nums[i],nums[i]} f(i)只和f(i−1)相关,可以只用一个变量pre来维护对于当前f(i)的f(i-1)的值是多少 */ class

Listen·Rain的博客 3931

LeetCode13—— 最大子序和

LeetCode13—— 最大子序和 前言: 题目内容: 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 示例 1: 输入:nums = [-2,1,-3,4,-1,2,1,-5,4] 输出:6 解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。 示例 2: 输入:nums = [1] 输出:1 示例 3: 输入:nums = [0] 输出:0 示例 4: 输入:nums = [-1] 输出:-1 示例 5: 输入:nums = [-10

a_1234567890_的博客 150

2024年5月13号刷题相关事项个人总结

是一个代码在线评测平台(Online Judge),包含了等不同分类的题目,其中以算法题目为主。我们可以通过解决 LeetCode 题库中的问题来练习编程技能,以及提高算法能力。LeetCode 上有 3000+ 道的编程问题,支持 16+ 种编程语言(C、C++、Java、Python 等),还有一个活跃的社区,可以用于分享技术话题、职业经历、题目交流等。并且许多知名互联网公司在面试的时候喜欢考察 LeetCode 题目,通常会以手写代码的形式出现。

weixin_49534890的博客 2060
上一篇: LeetCode刷题之旅(简单-12):报数
下一篇: ELK开发实战(1):一文搞懂 elasticsearch 的安装部署
后台技术汇
博客等级 码龄11年 670粉丝 531原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

后台技术汇

对你的帮助,是对我的最好鼓励。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值