《剑指Offer——连续子数组的最大和,礼物的最大价值》代码
Posted 穿迷彩服的鲨鱼
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《剑指Offer——连续子数组的最大和,礼物的最大价值》代码相关的知识,希望对你有一定的参考价值。
42.连续子数组的最大和,47.礼物的最大价值
前言
//==================================================================
// 《剑指Offer——连续子数组的最大和,礼物的最大价值》代码
// 题目:输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整
// 数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。
// 题目:在一个m×n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值
// (价值大于0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向左或
// 者向下移动一格直到到达棋盘的右下角。给定一个棋盘及其上面的礼物,请计
// 算你最多能拿到多少价值的礼物?
//==================================================================
一、示例
1.连续子数组的最大和
/*********************************************************************
输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。
要求时间复杂度为O(n)。
示例1:
输入: nums = [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
***********************************************************************/
2.礼物的最大价值
/******************************************************************************
在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。
你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。
给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?
示例 1:
输入:
[
[1,3,1], [0,0,0,0]
[1,5,1],----->[0,1,4,5]-----------[1,4,5,2,9]
[4,2,1] [0,2,9,10]
] [0,6,11,12]
输出: 12
解释: 路径 1→3→5→2→1 可以拿到最多价值的礼物
*************************************************************************/
二、代码解析
1.新建.cpp文件
代码如下(示例):
//==================================================================
// 《剑指Offer——连续子数组的最大和,礼物的最大价值》代码
// 题目:输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整
// 数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。
// 题目:在一个m×n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值
// (价值大于0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向左或
// 者向下移动一格直到到达棋盘的右下角。给定一个棋盘及其上面的礼物,请计
// 算你最多能拿到多少价值的礼物?
//==================================================================
#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;
/*********************************************************************
输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。
要求时间复杂度为O(n)。
示例1:
输入: nums = [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
***********************************************************************/
int maxSubArray(vector<int>& nums)
{
if (nums.empty() || nums.size() <= 0)
{
return 0;
}
int len = nums.size();
int nCurSum = 0;
int nGreatestSum = 0x80000000;
for (int i = 0; i < len; ++i)
{
if (nCurSum <= 0)
{
nCurSum = nums[i];
}
else
{
nCurSum += nums[i];
}
if (nCurSum > nGreatestSum)
{
nGreatestSum = nCurSum;
}
}
return nGreatestSum;
}
/******************************************************************************
在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。
你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。
给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?
示例 1:
输入:
[
[1,3,1], [0,0,0,0]
[1,5,1],----->[0,1,4,5]-----------[1,4,5,2,9]
[4,2,1] [0,2,9,10]
] [0,6,11,12]
输出: 12
解释: 路径 1→3→5→2→1 可以拿到最多价值的礼物
*************************************************************************/
/*法一 二维数组辅助*/
int maxValue1(vector<vector<int>>& grid)
{
if (grid.empty() || grid.size() <= 0 || grid[0].size() <= 0)
{
return 0;
}
int row = grid.size();
int columns = grid[0].size();
vector<vector<int>> dp(row + 1, vector<int>(columns + 1, 0));
for (int i = 1; i <= row; ++i)
{
for (int j = 1; j <= columns; ++j)
{
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1];
}
}
return dp[row][columns];
}
/*法二 一维数组辅助*/
int maxValue2(vector<vector<int>>& grid)
{
if (grid.empty() || grid.size() <= 0 || grid[0].size() <= 0)
{
return 0;
}
int row = grid.size();
int columns = grid[0].size();
vector<int> arr(columns, 0);
for (int i = 0; i < row; ++i)
{
for (int j = 0; j < columns; ++j)
{
int left = 0;
int up = 0;
if (i > 0)
up = arr[j];
if (j > 0)
left = arr[j - 1];
arr[j] = max(left, up) + grid[i][j];
}
}
int maxValue = arr[columns - 1];
return maxValue;
}
int main()
{
vector<int> nums = { -2,1,-3,4,-1,2,1,-5,4 };
cout << "连续子数组的最大和--->" << maxSubArray(nums) << endl << endl;
vector<vector<int>> grid =
{
{1,3,1},
{1,5,1},
{4,2,1}
};
cout << "礼物的最大价值--->二维数组---->" << maxValue1(grid) << endl << endl;
cout << "礼物的最大价值--->一维数组---->" << maxValue2(grid) << endl << endl;
return 0;
}
三,测试
以上是关于《剑指Offer——连续子数组的最大和,礼物的最大价值》代码的主要内容,如果未能解决你的问题,请参考以下文章