zoukankan      html  css  js  c++  java
  • 微软面试题: 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 };
  • 相关阅读:
    Docker 镜像
    Docker 安装命令
    Docker 基本概念
    Redis 高可用之"持久化"
    Git 安装和使用
    oracle角色
    oracle权限
    审计
    手动创建数据库
    oracle口令文件认证
  • 原文地址:https://www.cnblogs.com/wangxf2019/p/13992048.html
Copyright © 2011-2022 走看看