• 微软面试题: LeetCode 53. 最大子序和 出现次数:3


    题目描述:

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

    1. 定义状态

      经典动态规划问题,定义 dp[i] : nums中以nums[i] 结尾的具有最大和的连续子数组。取dp[i]  ( 0=< i <  n)的

    最大值即可得到最终结果。

    2.状态转移分析

      假设在计算 dp[i] 时,前面的 dp[i-1],dp[i-2],...,dp[1],dp[0]都已知,nums[i]此时也是已知。根据 已知的条件,分类

    讨论dp[i] 可能的情况。

          2.1  如果 dp[i - 1] <= 0,以 nums[i] 结尾的具有最大和的连续子数组 ,不管nums[i] 是多少,没必要再加上一个0 或负数被拖累,

    只包含自己就是具有最大和的连续子数组 。

          2.2  如果 dp[i-1] > 0,num[i] 接上 dp[i-1] 对应的连续子数组 一定比num[i]孤独一人组成的连续子数组的和大。

    所以dp 转移方程:

      dp[i]  =  dp[i-1] + nums[i] ; (dp[i-1] > 0)

          dp[i] = nums[i]; (dp[i-1] <= 0)

    上面的状态 dp[i] 仅和它的上一个状态有关,可以将 状态数组 dp[] 压缩成状态变量。

    3. 确定 dp 的 base case

        动态规划的base case 是状态转移方程的起点,有时候确定 base case 是能否正确 解决 dp问题的关键。

    这里的 状态转移方程从 nums[1]  ,dp [1] 开始,base case 就是 dp[0],很容易得到dp[0] = nums[0]

    4.确定状态转移方向

        最简单的 从 nums[0] 到 nums[n-1].

    代码如下 :

     1 class Solution {
     2 public:
     3     int maxSubArray(vector<int>& nums) 
     4     {
     5         if(nums.empty() || nums.size() == 0) return INT_MAX;
     6         int dp = nums[0];//dp[i] 在nums中以nums[i]结尾的具有最大和的连续子数组
     7         int res = dp;
     8         for(int i = 1;i<nums.size();++i)
     9         {
    10             if(dp <= 0)
    11             {
    12                 dp = nums[i];
    13             }
    14             else 
    15             {
    16                dp = dp + nums[i];
    17             }
    18             res = max(res,dp);
    19         }
    20         return res;
    21     }
    22 };
  • 相关阅读:
    从网络得到图片数据保存到手机中,
    jni 写一个简单的photoshop
    rman catalog配置简要笔记
    如何利用c中的指针实现两个8bit的数合并为16bit
    使用eclipse远程调试weblogic
    迁移11g Rac中OCR和VOTEDISK
    SQL SERVER导入数据到ORACLE的方法总结
    SQL SERVER如何通过SQL语句获服务器硬件和系统信息
    ORACLE SQL Developer日期显示格式设置
    mysqldump:Couldn't execute 'show create table `tablename`': Table tablename' doesn't exist (1146)
  • 原文地址:https://www.cnblogs.com/wangxf2019/p/13992048.html
Copyright © 2020-2023  润新知