[Leetcode] 11, 120, 132

本文解析了两道LeetCode上的经典算法题目:“盛最多水的容器”和“三角形最小路径和”。针对“盛最多水的容器”,介绍了通过两端逼近的方法来优化遍历过程;对于“三角形最小路径和”,则运用了动态规划的思想,详细阐述了状态转移方程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

11. Container With Most Water

Given n non-negative integers a1a2, ..., an, where each represents a point at coordinate (iai). n vertical lines are drawn such that the two endpoints of line i is at (iai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.

Note: You may not slant the container and n is at least 2.

Solution: 

使用两边向中间逼近的方式遍历,实际就是将普通的遍历方式将从前往后和从后往前结合了:

#include<iostream>
using namespace std;

int main(){
	int a[10] = {1,2,3,4,5,6,7,8,9,10};
	int count = 1;
	int times = 0;
	for(int i=0, t=9; i<t; count++){
		if(count%2){//我选择了轮流固定第一个和最后一个的方式,但实际上每轮遍历时可以随意固定第一个或者最后一个
			for(int j=i+1; j<=t; j++){
				cout<<a[i]<<' '<<a[j]<<endl;
				times++;
			}
			i++;
		}else{
			for(int j=i; j<t; j++){
				cout<<a[j]<<' '<<a[t]<<endl;
				times++;
			}
			t--;
		}
	}
	cout<<times<<endl;
	return 0;
} 
在这一题中,使用这种遍历方式,对于两个端点中高度较小的一个,一定可以确定固定它时得到的一组面积中最大的情况是它和另一个端点得到的面积,因此内层循环就可以直接节省掉。

Code:

class Solution {
public:
    int maxArea(vector<int>& height) {
        int start = 0;
        int last = height.size()-1;
        int maxArea = 0;
        while(start<last){
            int newArea = min(height[start], height[last])*(last-start);
            if(newArea>maxArea){
                maxArea = newArea;
            }
            if(height[start]>height[last])
                last--;
            else
                start++;
        }
        return maxArea;
    }
};



120. 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.

Solution: 动态规划,设状态为f(i; j),表示从从位置(i; j) 出发,路径的最小和,则状态转移方程为: f(i, j) = min{ f(i, j + 1),  f(i + 1, j + 1)} + (i, j)

Code:

class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        //sum_n[i] = min(sum_n+1[i], sum_n+1[i+1]) + triangle[n][i]
        vector<int> sum(triangle.back().begin(), triangle.back().end());
        int n = sum.size()-1;
        while(n>0){
            for(int i=0; i<n; i++){
                sum[i] = min(sum[i], sum[i+1]) + triangle[n-1][i];
            }
            n--;
        }
        return sum[0];
    }
};




132. Palindrome Partitioning II

Given a string s, partition s such that every substring of the partition is a palindrome.

Return the minimum cuts needed for a palindrome partitioning of s.

For example, given s = "aab",
Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut.

Solution: 对于一个子序列,找到所有可能的(包含第一个字母的所有回文)第一个切割点,然后计算每个切割点得到的子序列的最小切割数+1即可得到全局的最小值。状态转移方程式为:f(i) = min{ f(j + 1) + 1},  i <= j < n。注意:判断一个子序列是否为回文串也需要使用动规,直接判断会超时,动态转移方程式为:P[i][j] = str[i] == str[j] && P[i+1][j-1]。

Code:

class Solution {
public:
    int minCut(string s) {
        const int n = s.size();
        bool p[n][n];
        fill_n(&p[0][0], n*n, false);
        vector<int> cutNeeds(s.size()+1, INT_MAX);//(0)a(1)a(2)b(3)
        cutNeeds.back() = -1;
        for(int i=cutNeeds.size()-2; i>=0; i--){
            for(int t=i; t<s.size(); t++){
                if(i==t) p[i][t] = true;
                else if(i+1==t) p[i][t] = s[i]==s[t];
                else p[i][t] = (s[i]==s[t]) && p[i+1][t-1];
                if(p[i][t]){
                    //s(i:t)是个回文
                    int newcut = cutNeeds[t+1]+1;
                    if(newcut<cutNeeds[i]) cutNeeds[i] = newcut;
                }
            }
        }
        return cutNeeds[0];
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值