一、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.
分析:
代碼1:
#include<iostream>#include<string.h>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<n; ++i){//f = (f+a[i]) > a[i] ? (f+a[i]) : a[i];//result = result > f ? result : f;if(f>0)f = f+a[i];elsef = a[i];result = result > f ? result : f;//新舊結果對比,因為a[i]可能小於0。若a[i]小於0,則用老結果。}return result;}
代碼2:與代碼1相比,可以返回子序列。。。
#include<iostream>#include<string.h>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; i<n; ++i){if(f>0)f = f+a[i];elsef = 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<int> &ratings){ int i; if(ratings.size() == 0)//沒有小孩兒 return 0; else if(ratings.size() == 1)//有一個小孩兒 return 1; else{ int num = ratings.size();//小孩兒的個數 vector<int> candies(num, 1); for(i=1; i<num; ++i){//從左往右遍曆 if(ratings[i]>ratings[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<num; ++i){//計算糖果數量 result += candies[i]; } return result; } }};
三、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<vector<int> > &triangle){ vector<int> former_res;//記錄前邊的結果 vector<int> result;//記錄考慮當前行的結果 int i, j; int temp; former_res.push_back(triangle[0][0]);//把三角形的第一個元素給former_res for(i=1; i<triangle.size(); ++i){//遍曆三角形每一行 result.push_back(triangle[i][0] + former_res[0]);//每一個行的第一個元素直接與former_res的第一個元素相加,並儲存 for(j=1; j<triangle[i].size()-1; ++j){//每一個行的第i個元素與former_res較小的值相加,並儲存 temp = (former_res[j-1] < former_res[j] ? former_res[j-1] : former_res[j]); result.push_back(temp+triangle[i][j]); } //每一個行的最後一個元素直接與former_res的最後一個元素相加,並儲存 result.push_back(triangle[i][triangle[i].size()-1] + former_res[former_res.size()-1]); former_res.clear();//清空former_res former_res = result;//用result更新former_res result.clear();//清空result } vector<int>::iterator biggest = min_element(former_res.begin(), former_res.end());//找到向量former_res中最小的元素 return *biggest; }};
本地調試代碼:
#include<iostream>#include<string>#include<vector>#include <algorithm>using namespace std;int minimumTotal(vector<vector<int> > &triangle);int main(){vector<vector<int> > 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<int> b;int i, j;for(i=0; i<num; ++i){cin >> a;b.push_back(a);++count;if(count == COUNT){triangle.push_back(b);b.clear();count=0;++COUNT;}}for(i=0; i<triangle.size(); ++i){for(j=0; j<triangle[i].size(); ++j)cout << triangle[i][j] << ' ';cout << endl;}cout << "result: " << minimumTotal(triangle) << endl;return 0;}
四、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<int> 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)
class Solution {public: int sum(vector<int> a){ int sum=0; for(int i=0; i<a.size(); ++i) sum += a[i]; return sum; } int sum2(vector<vector<int> > a){ int sum=0; for(int i=0; i<a.size(); ++i) sum += a[i][0]; return sum; } int minPathSum(vector<vector<int> > &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<vector<int> > result; vector<int> result_row; //計算result的第一行 result_row.push_back(grid[0][0]); result.push_back(result_row); for(j=1; j<grid[0].size(); ++j) result[0].push_back(result[0][j-1] + grid[0][j]); //計算result的剩餘行 for(i=1; i<grid.size(); ++i){ result_row.clear(); result_row.push_back(result[i-1][0] + grid[i][0]); result.push_back(result_row); for(j=1; j<grid[i].size(); ++j){ result[i].push_back((result[i][j-1] < result[i-1][j] ? result[i][j-1] : result[i-1][j]) + grid[i][j]); } } return result[--i][--j]; } }};本地調試代碼:
int main(){vector<vector<int> > grid;int m, n;cin >> m >> n;for(int i=0; i<m; ++i){vector<int> temp;for(int j=0; j<n; ++j){int x;cin >> x;temp.push_back(x);}grid.push_back(temp);}cout << "minPathSum: " << minPathSum(grid) << endl;/*調試用for(i=0; i<m; ++i){for(int j=0; j<n; ++j)cout << grid[i][j] << ' ';cout << endl;}cout << endl;*/return 0;}
六、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?
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<vector<int> > result(m, vector<int>(n, 1));//初始化全1 for(i=1; i<m; ++i) for(j=1; j<n; ++j) result[i][j] = result[i-1][j] + result[i][j-1]; return result[m-1][n-1]; }};
七、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<vector<int> > &obstacleGrid){ int i, j; int m = obstacleGrid.size();//行數 int n = obstacleGrid[0].size();//列數 vector<vector<int> > result(m, vector<int>(n, 0));//初始化用於儲存結果的數組,全為0 if(obstacleGrid[0][0] == 0)//如果左上方元素不是障礙物 result[0][0] = 1; else//否則返回0 return 0; for(j=1; j<n; ++j)//result的第一行 if(obstacleGrid[0][j] == 1)//如果當前位置是障礙物,此處的result設為0 result[0][j] = 0; else//若不是障礙物 result[0][j] = result[0][j-1];//則為左鄰居的值 for(i=1; i<m; ++i)//result的第一列,與第一行同理 if(obstacleGrid[i][0] == 1) result[i][0] = 0; else result[i][0] = result[i-1][0]; for(i=1; i<m; ++i){ for(j=1; j<n; ++j){ if(obstacleGrid[i][j] == 1)//與uniquePaths的區別之處,若當前位置為障礙物 result[i][j] = 0;//則把resutl設為0 else//若不是障礙物 result[i][j] = result[i-1][j] + result[i][j-1];//則把左邊和上邊的鄰居值相加 } } return result[m-1][n-1];//返回結果 }};
本地測試代碼:
int main(){vector<vector<int> > grid;int m, n;cin >> m >> n;for(int i=0; i<m; ++i){vector<int> temp;for(int j=0; j<n; ++j){int x;cin >> x;temp.push_back(x);}grid.push_back(temp);}cout << uniquePathsWithObstacles(grid) << endl;return 0;}