LeetCode练习-动态规划算法(一)


一、Maximum Subarray(最大连续子序列和)

描述:

Find the contiguous subarray within an array (containing at least one number) which has the largest sum.
For example, given the array [−2,1,−3,4,−1,2,1,−5,4], the contiguous subarray [4,−1,2,1] has the largest sum = 6.

分析:

LeetCode练习-动态规划算法(一)_第1张图片

代码1:

#include
#include
using namespace std;

/*最大连续子序列和*/
int maxSubArray(int a[], int n);
int main()
{
	int a[] = {-2,1,-3,4,-1,2,1,-5,4};
	int n = sizeof(a)/4;
	cout << maxSubArray(a, n) << endl;
	return 0;
}
int maxSubArray(int a[], int n)
{
	
	int i;
	int f=0;
	int result=-99999;

	for(i=0; i a[i] ? (f+a[i]) : a[i];
		//result = result > f ? result : f;
		if(f>0)
			f = f+a[i];
		else
			f = a[i];
		result = result > f ? result : f;//新旧结果对比,因为a[i]可能小于0。若a[i]小于0,则用老结果。
	}
	return result;
}

代码2:与代码1相比,可以返回子序列!!!

#include
#include
using namespace std;

/*最大连续子序列和*/
int maxSubArray(int a[], int n, int &l, int &r);// l、r分别为最大连续子序列的起始和终止点
int main()
{
	int a[] = {-2,1,-3,4,-1,2,1,-5,4};
	int n = sizeof(a)/4;
	int l=0, r=0;
	int out = maxSubArray(a, n, l, r);
	cout << out << endl;
	int i;
	for(i=l; i<=r; i++)
		cout << a[i] << ' ';
	cout << endl;
	return 0;
}
int maxSubArray(int a[], int n, int &l, int &r)
{
	int i;
	int f=0;
	int last_f=0;
	int result=-99999;
	int last_result=-99999;
	
	for(i=0; i0)
			f = f+a[i];
		else
			f = a[i];
		
		if(last_f<0 && f>0)//f由负跳到正的时候,记录子序列起始点
			l = i;
		last_f = f;

		if(result < f)//result增大时,记录子序列终止点
		{
			result = f;
			r = i;
		}
	}
	return result;
}

二、Candy

题目描述
There are N children standing in a line. Each child is assigned a rating value.
You are giving candies to these children subjected to the following requirements:
    Each child must have at least one candy.
    Children with a higher rating get more candies than their neighbors.
What is the minimum candies you must give?

class Solution {
public:
    int candy(vector &ratings){
        int i;
        if(ratings.size() == 0)//没有小孩儿
            return 0;
        else if(ratings.size() == 1)//有一个小孩儿
            return 1;
        else{
            int num = ratings.size();//小孩儿的个数
            vector candies(num, 1);

            for(i=1; iratings[i-1] && candies[i] <= candies[i-1])
                    candies[i] = candies[i-1] + 1;
            }

            for(i=num-2; i>=0; --i){//从右往左遍历
                if(ratings[i] > ratings[i+1] && candies[i] <= candies[i+1])
                    candies[i] = candies[i+1] + 1;
            }

            int result=0;
            for(i=0; i

三、triangle

题目描述
Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.
For example, given the following triangle
[
     [2],
    [3,4],
   [6,5,7],
  [4,1,8,3]
]

The minimum path sum from top to bottom is11(i.e., 2 + 3 + 5 + 1 = 11).
Note:
Bonus point if you are able to do this using only O(n) extra space, where n is the total number of rows in the triangle.

思路:

     [2],        ----------------> [2]
    [3,4],      --------------->[5,6]
   [6,5,7],   ------------->[11,10,13]         把当前行的第j个元素与former_res中第j与第j-1较小的值相加,
  [4,1,8,3]  ----------->[15,11,18,16]      第0个元素与former_res的第0个元素相加,最后一个元素同理。

代码:

class Solution {
public:
    int minimumTotal(vector > &triangle){
        vector former_res;//记录前边的结果
        vector result;//记录考虑当前行的结果
        int i, j;
        int temp;
        former_res.push_back(triangle[0][0]);//把三角形的第一个元素给former_res
        for(i=1; i::iterator biggest = min_element(former_res.begin(), former_res.end());//找到向量former_res中最小的元素
        return *biggest;

    }
};
本地调试代码:

#include
#include
#include
#include 
using namespace std;

int minimumTotal(vector > &triangle);
int main(){
	vector > triangle;
	int n;
	cout << "The rows of triangle: ";
	cin >> n;
	int num = n*(n+1)/2;
	cout << "num: " << num << endl;
	int count=0, COUNT=1;
	int a;
	vector b;
	int i, j;
	for(i=0; i> a;
		b.push_back(a);
		++count;
		if(count == COUNT){
			triangle.push_back(b);
			b.clear();
			count=0;
			++COUNT;
		}
	}
	
	for(i=0; i
四、climbing-stairs
题目描述
You are climbing a stair case. It takes n steps to reach to the top.

Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

思路:

//climbStairs(n) = climbStairs(n-1) + climbStairs(n-2);
//与《王道》里边的铺砖问题一样!

代码:

class Solution {
public:
    
    int climbStairs(int n){
        if(n<0)
            return NULL;
        else if(n<=2)
            return n;
        else{
            vector a;
            a.push_back(0);
            a.push_back(1);
            a.push_back(2);
            for(int i=3; i<=n; ++i){
                int b = a[i-1]+a[i-2];
                a.push_back(b);
            }
            return a[a.size()-1];
        }
    }
};

五、minimum-path-sum

题目描述
Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.
Note: You can only move either down or right at any point in time.

思路:在计算result时,result(i, j) = min( result(i-1, j), result(i, j-1) ) + grid(i, j)

LeetCode练习-动态规划算法(一)_第2张图片

class Solution {
public:
    int sum(vector a){
        int sum=0;
        for(int i=0; i > a){
        int sum=0;
        for(int i=0; i > &grid){
        if(grid.size() <= 0)
            return NULL;
        else if(grid.size() == 1)//只有一行
            return sum(grid[0]);
        else if(grid[0].size() == 1)//只有一列
            return sum2(grid);
        else{
            int i, j;
            vector > result;
            vector result_row;
            //计算result的第一行
            result_row.push_back(grid[0][0]);
            result.push_back(result_row);
            for(j=1; j
本地调试代码:

int main(){
	vector > grid;
	int m, n;
	cin >> m >> n;
	for(int i=0; i temp;
		for(int j=0; j> x;
			temp.push_back(x);
		}
		grid.push_back(temp);
	}
	cout << "minPathSum: " << minPathSum(grid) << endl;
	/*调试用
	for(i=0; i

六、unique-paths

题目描述
A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).
The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).
How many possible unique paths are there?

LeetCode练习-动态规划算法(一)_第3张图片

Above is a 3 x 7 grid. How many possible unique paths are there?
Note: m and n will be at most 100.

思路:与上一题minimum-path-sum很像

代码:

class Solution {
public:
    int uniquePaths(int m, int n){
        int i, j;
        if(m<1 || n<1)
            return 0;
        vector > result(m, vector(n, 1));//初始化全1

        for(i=1; i
七、unique-paths-ii
题目描述
Follow up for "Unique Paths":
Now consider if some obstacles are added to the grids. How many unique paths would there be?
An obstacle and empty space is marked as1and0respectively in the grid.
For example,
There is one obstacle in the middle of a 3x3 grid as illustrated below.
[
  [0,0,0],
  [0,1,0],
  [0,0,0]
]
The total number of unique paths is2.

Note: m and n will be at most 100.

思路:与上一题unique-paths很像,区别在于:当 当前位置为障碍物时,把对应的result置为0。此外,result的第一行与第一列的设置方式与unique-paths也稍有区别!

代码:

class Solution {
public:
    int uniquePathsWithObstacles(vector > &obstacleGrid){
        int i, j;
        int m = obstacleGrid.size();//行数
        int n = obstacleGrid[0].size();//列数
        vector > result(m, vector(n, 0));//初始化用于存储结果的数组,全为0
        if(obstacleGrid[0][0] == 0)//如果左上角元素不是障碍物
            result[0][0] = 1;
        else//否则返回0
            return 0;
        for(j=1; j

本地测试代码:

int main(){
	vector > grid;
	int m, n;
	cin >> m >> n;
	for(int i=0; i temp;
		for(int j=0; j> x;
			temp.push_back(x);
		}
		grid.push_back(temp);
	}
	
	cout << uniquePathsWithObstacles(grid) << endl;
	return 0;
}



你可能感兴趣的:(C++,C语言,LeetCode练习题)