动态规划(三)

一、数字字符串转化成IP地址

现在有一个只包含数字的字符串,将该字符串转化成IP地址的形式,返回所有可能的情况。

例如:

给出的字符串为"25525522135",

返回"255.255.22.135", "255.255.221.35". (顺序没有关系)

数据范围:字符串长度 0≤n≤12

要求:空间复杂度 O(n!),时间复杂度 O(n!)

注意:ip地址是由四段数字组成的数字序列,格式如 "x.x.x.x",其中 x 的范围应当是 0,255。

复制代码
import java.util.*;

public class Solution {

    ArrayList<String> ans = new ArrayList<>();
    public ArrayList<String> restoreIpAddresses (String s) {
        // 尝试使用 . 切分
        dfs(new StringBuilder(s), 0, 0);
        return ans;
    }

    // curIndex: 当前插入 . 的下标
    void dfs(StringBuilder sb, int numOfPoint, int curIndex) {
        if (numOfPoint == 3) {
            // System.out.println(sb);
            if (checkValid(sb)) {
                ans.add(new String(sb));
            }
            return;
        }
        for (int i = curIndex + 1; i < sb.length(); i++) {
            sb.insert(i, '.');
            dfs(sb, numOfPoint + 1, i);
            sb.deleteCharAt(i);
        }
    }

    boolean checkValid(StringBuilder sb) {
        boolean ans = true;
        String[] sbb = sb.toString().split("\\.");
        if (sbb.length != 4) return false;
        for (String s : sbb) {
            if (s.isEmpty() || s.length() > 3) return false;
            if (s.length() > 1 && s.startsWith("0")) return false;
            int x = Integer.valueOf(s);
            ans &= (x >= 0);
            ans &= (x <= 255);
        }
        return ans;
    }
}

运行结果

二、编辑距离

给定两个字符串 str1 和 str2 ,请你算出将 str1 转为 str2 的最少操作数。

你可以对字符串进行3种操作:

1.插入一个字符

2.删除一个字符

3.修改一个字符。

字符串长度满足 1≤n≤1000 ,保证字符串中只出现小写英文字母。

复制代码
public class Solution {
    public int editDistance(String str1, String str2) {
        char[] a1 = str1.toCharArray(), a2 = str2.toCharArray();
        int m = a1.length, n = a2.length;
        int[][] dp = new int[m + 1][n + 1];
        for (int i = 1; i <= m; i++) {
            dp[i][0] = i;
        }
        for (int j = 1; j <= n; j++) {
            dp[0][j] = j;
        }
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (a1[i - 1] == a2[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1];
                } else {
                    dp[i][j] = Math.min(dp[i - 1][j - 1], Math.min(dp[i - 1][j], dp[i][j - 1])) + 1;
                }
            }
        }
        return dp[m][n];
    }
}

运行结果

三、正则表达式匹配

请实现一个函数用来匹配包括'.'和'*'的正则表达式。

1.模式中的字符'.'表示任意一个字符

2.模式中的字符'*'表示它前面的字符可以出现任意次(包含0次)。

在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配

数据范围:

1.str 只包含从 a-z 的小写字母。

2.pattern 只包含从 a-z 的小写字母以及字符 . 和 *,无连续的 '*'。

  1. 0≤str.length≤26

  2. 0≤pattern.length≤26

    import java.util.*;

    public class Solution {
    public boolean match(String str, String pattern) {
    // 优化方向:记忆化搜索
    return match(str, 0, pattern, 0);
    }

    复制代码
     private boolean match(String str, int i, String pattern, int j) {
         boolean b1 = j + 1 < pattern.length() && pattern.charAt(j + 1) == '*';
         if (i == str.length() || j == pattern.length()) {
             return b1 ? match(str, i, pattern, j + 2) : i == str.length() &&
                    j == pattern.length();
         }
         boolean b2 = str.charAt(i) == pattern.charAt(j) || pattern.charAt(j) == '.';
         if (b1) {
             return match(str, i, pattern, j + 2) || b2 && match(str, i + 1, pattern, j);
         }
         return b2 && match(str, i + 1, pattern, j + 1);
     }

    }

运行结果

四、最长的括号子串

给出一个长度为 n 的,仅包含字符 '(' 和 ')' 的字符串,计算最长的格式正确的括号子串的长度。

例1: 对于字符串 "(()" 来说,最长的格式正确的子串是 "()" ,长度为 2 .

例2:对于字符串 ")()())" , 来说, 最长的格式正确的子串是 "()()" ,长度为 4 .

复制代码
import java.util.*;


public class Solution {
    public int longestValidParentheses(String s) {
        return Math.max(func(s, '('), func(new StringBuilder(s).reverse().toString(),
                                           ')'));
    }

    public int func(String s, char c1) {
        int res = 0, curr = 0, cnt = 0;
        for (char c : s.toCharArray()) {
            if (c == c1) {
                curr++;
            } else if (--curr < 0) {
                cnt = -1;
                curr = 0;
            }
            res = Math.max(++cnt * (curr == 0 ? 1 : 0), res);
        }
        return res;
    }
}

运行结果

相关推荐
木棉软糖1 小时前
JDBC 读 ResultSet 读到一半,报 stream closed
java·mysql·spring
Logic1011 小时前
C语言/数据结构贡献法题解:数组权值——所有连续子数组中不同数字个数之和(O(n)解法)
c语言·数据结构·算法·数组·时间复杂度·贡献法·哈希记录
DongQiShanRen1 小时前
六根硬件映射(中):双站校验、生克闭环与驱动接口
数据库·人工智能·算法·rust·哈希算法·集成学习
狂奔的sherry1 小时前
JRuby 多线程反引号偶发 127:GC 提前释放了 posix_spawn 的 argv
java·linux·ruby·gc·jruby
咖啡八杯1 小时前
异常体系设计:三类策略(i18n code、message、受检异常)
java·架构·代码规范
mmmmath_32 小时前
LeetCode.637.二叉树的层平均值
算法·leetcode
青少儿编程课堂2 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会C/C++考级:并查集连通块与朋友圈问题解析
c++·python·算法·bfs·信息学竞赛
Spatial3Ddddd2 小时前
2026空间三维重建服务商横向对比
java·服务器·人工智能
Tisfy2 小时前
LeetCode 2913.子数组不同元素数目的平方和 I:第一题先常数很大的O(n^2)
算法·leetcode·题解·模拟·暴力