Leetcode: Triangle、Interleaving String (week11---hard×1, medium×1)

120. Triangle

题目 

分析

题解

97. Interleaving String 

题目

分析

题解

错解(复杂度较高)

正解


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.

分析

  1. 这一道题其实比起之前的寻路的个数难度降低了,只不过形态比较奇怪,所以刚开始看起来可能会感到困惑
  2. 也就是杨辉三角形的变形,只不过每一个三角形底边的新生成采用局部贪心算法的模式,也就是一直去最小值就可以了。
  3. 步骤可以简化为如下:(i表示行, j表示列, 存储的数组为M)
    1. 当j为0的时候,则M[i][j] = M[i - 1][j] + a[i][j]
    2. 当j等于i的时候,则M[i][j] = M[i - 1][j] + a[i][j]
    3. 其余的情况,M[i][j] = min(M[i - 1][j - 1], M[i - 1][j]) + a[i][j]

题解

class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        int l = triangle.size();
        int a1[l][l];
        a1[0][0] = triangle[0][0];
        for(int i = 1; i < l; i++){
            for(int j = 0; j <= i; j++){
                if(j == 0) a1[i][j] = a1[i - 1][0] + triangle[i][j];
                else if(j == i) a1[i][j] = a1[i - 1][j - 1] + triangle[i][j];
                else {
                    a1[i][j] = min(a1[i - 1][j - 1], a1[i - 1][j]) + triangle[i][j];
                }
            }
        }
        int minnum = a1[l - 1][0];
        for(int i = 0; i < l; i++){
            if (a1[l - 1][i] < minnum){
                minnum = a1[l - 1][i];
            }
        }
        return minnum;
    }
};

97. Interleaving String 

题目

Given s1s2s3, find whether s3 is formed by the interleaving of s1 and s2.

Example 1:

Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
Output: true

分析

  1. 一开始看这一道题的思路与之前做过的正则表达式匹配的思路是一样的,因为自己理解成了只要存在一个两者合并的方式就可以了,因此采用的是递归的方式,但是当字符串的长度较长的时候算法的复杂度已经很高了,也就是会造成超时,所以就应该另寻方法
  2. 采用二维数组的动态规划算法
    1. 开一个大小为M[s1.length() + 1][s2.length() + 1]的数组
    2. M[i][j]表示的是在s1中取前i个字符以及s2中取前j个字符是否能够构成s3中的i+j个字符串,依赖于前面的值
    3. 一开始的初始化:
      1. M[0][0] = true
      2. 分别对s1与s2进行M[i][0] M[0][j]的赋值操作:M[i][0] = M[i - 1][0] && s1[i - 1] == s3[i - 1];
    4. 在进行遍历填表
      1. M[i][j] = (M[i][j - 1] && s2[j - 1] == s3[i + j - 1]) || (M[i - 1][j] && s1[i - 1] == s3[i + j - 1]);

题解

错解(复杂度较高)

class Solution {
public:
    bool isInterleave(string s1, string s2, string s3) {
        if(s3 == "") return s1.empty() && s2.empty();
        if(s1 == "") return (s2 == s3);
        if(s2 == "") return (s1 == s3);
         if(s3[0] == s1[0] && s3[0] == s2[0]){
             return isInterleave(s1.substr(1, s1.length() - 1), s2, s3.substr(1, s3.length() - 1)) || isInterleave(s1, s2.substr(1, s2.length() - 1), s3.substr(1, s3.length() - 1));
             }
         else if(s3[0] == s1[0]) return isInterleave(s1.substr(1, s1.length() - 1), s2, s3.substr(1, s3.length() - 1));
         else if(s3[0] == s2[0]) return isInterleave(s1, s2.substr(1, s2.length() - 1), s3.substr(1, s3.length() - 1));
        else return false;
    }
};

正解

class Solution {
public:
    bool isInterleave(string s1, string s2, string s3) {
        int l1 = s1.length();
        int l2 = s2.length();
        int l3 = s3.length();
        if((l1 + l2) != l3) return false;
        bool M[l1+1][l2+1];
        M[0][0] = true;
        for(int i = 1; i <= l1; i++){
            M[i][0] = M[i - 1][0] && s1[i - 1] == s3[i - 1];
        }
        for(int j = 1; j <= l2; j++){
            M[0][j] = M[0][j - 1] && s2[j - 1] == s3[j - 1];
        }
        for(int i = 1; i <=l1; i++){
            for(int j = 1; j <= l2; j++){
                M[i][j] = (M[i][j - 1] && s2[j - 1] == s3[i + j - 1]) || (M[i - 1][j] && s1[i - 1] == s3[i + j - 1]);
            }
        }    
        return M[l1][l2];
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值