[leetcode] 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 is 11 (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.

class Solution {
public:
    int minimumTotal(vector<vector<int> > &triangle) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        int min=INT_MAX;
        int n=triangle.size();
        DFS(triangle,0,0,n,0,min);
        return min;
    }
    void DFS(vector<vector<int> >& A, int depth,int p, int n , int sum, int &min){
         if(depth==n){
            if(min>sum)
                min=sum;
            return ;
         }
         DFS(A,depth+1,p,n,sum+A[depth][p],min);
         DFS(A,depth+1,p+1,n,sum+A[depth][p],min);
         return;
    }    
};

DFS递归似乎效率比较低,大数据过不了.DFS如果不用循环去实现应该是下面这个样子:

class Solution {
public:
    int minimumTotal(vector<vector<int> > &triangle) {
		// Start typing your C/C++ solution below
		// DO NOT write int main() function
		int n=triangle.size();
		int *p=new int[n];
		memset(p,0,sizeof(int)*n);
		int k=1,min=INT_MAX;
		int sum=triangle[0][0];
		if(n==1)
			return triangle[0][0];
		for( ; ; ){
			if(p[k]-p[k-1]>1){
				k--;
				if(k==0)
					break;
				sum-=triangle[k][p[k]];
				p[k]++;
				for(int i=k ; i<n-1 ; i++)
                    p[i+1]=p[i];
				continue;
			}
			if(k==n-1){
				sum+=triangle[k][p[k]];
				if(sum<min)
					min=sum;
				sum-=triangle[k][p[k]];
				p[k]++;
			}
			else{
				sum+=triangle[k][p[k]];
				k++;
			}
		}
		return min;
	}   
};

当然可以用动态规划去做:

到某一个数字的路径为到其肩膀上的两个数字路径长度的较小值加上它自身。

class Solution {
public:
    int minimumTotal(vector<vector<int> > &triangle) {
		// Start typing your C/C++ solution below
		// DO NOT write int main() function
		int n=triangle.size();
		int *path=new int[n];
		int *temp=new int[n];
		memset(path,0,n*sizeof(int));
		path[0]=triangle[0][0];
		for(int i=1 ; i<n ; i++){
			for(int k=0 ; k<i ; k++)
				temp[k]=path[k];
			for(int j=1; j<i ; j++){
				path[j]=triangle[i][j]+min(temp[j-1],temp[j]);
			}
			path[0]=temp[0]+triangle[i][0];
			path[i]=temp[i-1]+triangle[i][i];
		}
		for(int i=1 ; i<n ; i++){
			if(path[i]<path[0])
				path[0]=path[i];
		}
		return path[0];
	}
};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值