一、数字字符串转化成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 的小写字母以及字符 . 和 *,无连续的 '*'。
-
0≤str.length≤26
-
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;
}
}
运行结果
