动态规划 - 笔记

正则表达式匹配

 

 

class Solution {
    public boolean isMatch(String s, String p){
        StringBuilder sb = new StringBuilder();
        char[] cs = p.toCharArray();
        for(int i = 0; i < cs.length; i++){
            while(i < cs.length - 1 && cs[i + 1] == '*' && cs[i] == '*'){
                i++;
            }
            sb.append(cs[i]);
        }
        p = sb.toString();
        char[] sChars = ( " " + s ).toCharArray();
        char[] pChars = ( " " + p ).toCharArray();
        int sLen = s.length(), pLen = p.length();
        boolean[][] dp = new boolean[sLen + 1][pLen + 1];
        dp[0][0] = true;
        //当匹配串为*时, 要对dp[0][j]进行特殊处理下
        for(int j = 2; j <= pLen; j++){
            if(pChars[j] == '*') dp[0][j] = dp[0][j - 2];
        }
        for(int i = 1; i <= sLen; i++){
            for(int j = 1; j <= pLen; j++){
                if(pChars[j] == '*'){
                    if(j > 1) dp[i][j] = dp[i][j - 2];
                    char c = pChars[j - 1];
                    for(int k = i; k >= 1; k--){
                        if(sChars[k] != c && c != '.') break;
                        dp[i][j] |= dp[k][j - 1];
                    }
                }else {
                    if(sChars[i] == pChars[j] || pChars[j] == '.'){
                        dp[i][j] = dp[i - 1][j - 1];
                    }
                }
            }
        }

        return dp[sLen][pLen];
    }
}

最长有效括号

    public int longestValidParentheses(String s){
        int n = s.length();
        char[] a = (" " + s).toCharArray();
        int[] dp = new int[n + 1];
        int max = 0;
        for(int i = 1; i <= n; i++){
            if(a[i] == ')'){
                if(a[i - 1] == '('){
                    dp[i] = dp[i - 2] + 2;
                }else if(a[i - 1] == ')'){
                    int miniro = i - dp[i - 1] - 1;
                    dp[i] = a[miniro] == '(' ? dp[miniro - 1] + dp[i - 1] + 2 : 0;
                }
            }
            max = Math.max(dp[i], max);
        }
        return max;
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
动态规划是一种算法设计技术,通常用于解决最优化问题,特别适用于那些有重叠子问题和最优子结构特征的问题。以下是关于动态规划的一些关键点,大约1000字的笔记概要: 1. **基础概念**: - 它将复杂问题分解成更小的子问题,并存储解决方案,避免重复计算。 - 遵循“自底向上”(bottom-up)或“贪心策略”的原则。 2. **核心思想**: - 最优子结构:问题的最优解可以由其子问题的最优解组成。 - 无后效性:一旦做出某个决策,就不会影响先前已经做出的其他决策的最优值。 3. **基本步骤**: a. 状态定义:明确问题的状态变量,通常是通过前一阶段的决策组合得到的。 b. 状态转移方程:描述如何从当前状态转换到下一个状态并求解目标函数。 c. 边界条件:确定初始状态或最简单情况下的状态值。 d. 更新表:按照顺序填充状态值表格,最终结果在最复杂的状态下找到。 4. **典型应用**: - 背包问题(0-1背包、完全背包、多重背包) - 最长公共子序列(LCS) - 最短路径(Dijkstra, Floyed-Warshall算法) - 最大子数组(Kadane's Algorithm) - 编辑距离 5. **注意事项**: - 避免重复工作:动态规划的关键在于记住之前的结果,避免不必要的计算。 - 计算空间管理:内存消耗较大,需要谨慎设计存储结构。 6. **案例分析**: 分析一个具体的例子,如斐波那契数列,说明如何将其转化为动态规划问题,并写出伪代码和Python实现。 7. **总结和拓展**: - 动态规划与其他算法的区别(例如分治法、贪心等)。 - 动态规划在实际项目中的应用场景和优化策略。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值