leecode更新

This commit is contained in:
markilue 2023-03-02 20:06:36 +08:00
parent ee7a15d432
commit 36913ce39e
3 changed files with 269 additions and 0 deletions

View File

@ -0,0 +1,142 @@
package com.markilue.leecode.hot100;
import org.junit.Test;
import java.util.HashMap;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100
*@Author: markilue
*@CreateTime: 2023-03-02 09:54
*@Description:
* TODO 力扣10题 正则表达式匹配:
* 给你一个字符串 s 和一个字符规律 p请你来实现一个支持 '.' '*' 的正则表达式匹配
* '.' 匹配任意单个字符
* '*' 匹配零个或多个前面的那一个元素
* 所谓匹配是要涵盖 整个 字符串 s的而不是部分字符串
*@Version: 1.0
*/
public class T10_IsMatch {
@Test
public void test() {
// String s = "aab", p = "c*a*b";
String s = "mississippi", p = "mis*is*ip*.";
System.out.println(isMatch(s, p));
}
@Test
public void test1() {
// String s = "aab", p = "c*a*b";
String s = "ab", p = ".*c";
System.out.println(isMatch(s, p));
}
/**
* 思路:仍然是匹配类型的题,遍历p如果p使用完了都还没有遍历完那么就匹配不上中途匹配不上也停止
* 尝试失败 自己的方法有太多边界条件需要处理
* @param s
* @param p
* @return
*/
public boolean isMatch(String s, String p) {
char[] chars = p.toCharArray();
char[] sChars = s.toCharArray();
char lastChar = '1';
int SIndex = 0;
for (int i = 0; i < p.length(); i++) {
if (SIndex == s.length()) return true;
if (chars[i] - 'a' >= 0 && chars[i] - 'a' <= 26) {
//匹配上的是字母,判断是否能匹配s
if (i + 1 < chars.length && chars[i + 1] == '*') {
lastChar = chars[i];
} else if (sChars[SIndex++] != chars[i]) {
return false;
}
} else if (chars[i] == '*') {
if (lastChar == '.') {
//之前的是.
//找到下一个char中为字母的
while (i < chars.length && chars[i] - 'a' >= 0 && chars[i] - 'a' <= 26) {
i++;
}
if (i == chars.length) {
return true;//因为一定能匹配上了
} else {
lastChar = chars[i];
while (SIndex < sChars.length && sChars[SIndex] != lastChar) {
SIndex++;
}
}
}
//匹配上的是*,for循环增加
while (SIndex < sChars.length && sChars[SIndex] == lastChar) {
SIndex++;
}
} else {
//匹配上的是.
if (i + 1 < chars.length && chars[i + 1] == '*') {
lastChar = chars[i];
} else {
SIndex++;
}
}
}
if (SIndex < sChars.length) {
return false;
}
return true;
}
/**
* 官方思路:动态规划法
* TODO DP五部曲:
* 1.dp定义: f[i][j]表示 sss 的前 i个字符与 ppp 中的前 j个字符是否能够匹配
* 速度击败42.97% 内存击败32.92% 2ms
* @param s
* @param p
* @return
*/
public boolean isMatch1(String s, String p) {
int m = s.length();
int n = p.length();
boolean[][] f = new boolean[m + 1][n + 1];
f[0][0] = true;
for (int i = 0; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
if (p.charAt(j - 1) == '*') {
f[i][j] = f[i][j - 2];//不匹配字符将该组合扔掉不再进行匹配
if (matches(s, p, i, j - 1)) {
f[i][j] = f[i][j] || f[i - 1][j];//能匹配 s 末尾的一个字符将该字符扔掉而该组合还可以继续进行匹配
}
} else {
if (matches(s, p, i, j)) {
f[i][j] = f[i - 1][j - 1];
}
}
}
}
return f[m][n];
}
public boolean matches(String s, String p, int i, int j) {
if (i == 0) {
return false;
}
if (p.charAt(j - 1) == '.') {
return true;
}
return s.charAt(i - 1) == p.charAt(j - 1);
}
}

View File

@ -0,0 +1,71 @@
package com.markilue.leecode.hot100;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100
*@Author: markilue
*@CreateTime: 2023-03-02 11:17
*@Description:
* TODO 力扣15题 三数之和:
* 给你一个整数数组 nums 判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != k j != k 同时还满足 nums[i] + nums[j] + nums[k] == 0
* 你返回所有和为 0 且不重复的三元组
* 注意答案中不可以包含重复的三元组
*@Version: 1.0
*/
public class T11_ThreeSum {
@Test
public void test() {
int[] nums = {-1, 0, 1, 2, -1, -4};
// int[] nums = {-2,0,0,2,2};
System.out.println(threeSum(nums));
}
/**
* 思路:双指针法
* 速度击败33.39% 内存击败45.64% 33ms
* 但是和快速的方法差别不大
* @param nums
* @return
*/
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
int sum = 0;
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
if (nums[i] > 0) {
break;
}
if (i > 0 && nums[i - 1] == nums[i]) continue;
int left = i + 1;
int right = nums.length - 1;
while (left < right) {
sum = nums[i] + nums[left] + nums[right];
if (sum < 0) {
left++;
} else if (sum > 0) {
right--;
} else {
result.add(Arrays.asList(nums[i], nums[left], nums[right]));
while (left < right && nums[++left] == nums[left - 1]) continue;
while (right > left && nums[right] == nums[--right]) continue;
}
}
}
return result;
}
}

View File

@ -0,0 +1,56 @@
package com.markilue.leecode.hot100;
import java.util.*;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100
*@Author: markilue
*@CreateTime: 2023-03-02 13:12
*@Description:
* TODO 力扣17题 电话号码的字母组合:
* 给定一个仅包含数字 2-9 的字符串返回所有它能表示的字母组合答案可以按 任意顺序 返回
* 给出数字到字母的映射如下与电话按键相同注意 1 不对应任何字母
*
*@Version: 1.0
*/
public class T12_LetterCombinations {
Map<Character, List<Character>> map = new HashMap() {{
put('2', Arrays.asList('a', 'b', 'c'));
put('3', Arrays.asList('d', 'e', 'f'));
put('4', Arrays.asList('g', 'h', 'i'));
put('5', Arrays.asList('j', 'k', 'l'));
put('6', Arrays.asList('m', 'n', 'o'));
put('7', Arrays.asList('p', 'q', 'r', 's'));
put('8', Arrays.asList('t', 'u', 'v'));
put('9', Arrays.asList('w', 'x', 'y', 'z'));
}};
StringBuilder builder = new StringBuilder();
List<String> result = new ArrayList<>();
public List<String> letterCombinations(String digits) {
if(digits.length()==0)return result;
char[] chars = digits.toCharArray();
backtracking(chars, 0);
return result;
}
public void backtracking(char[] chars, int startIndex) {
if (builder.length() == chars.length) {
result.add(new String(builder));
return;
}
List<Character> characters = map.get(chars[startIndex]);
for (int i = 0; i < characters.size(); i++) {
builder.append(characters.get(i));
backtracking(chars, startIndex + 1);
builder.deleteCharAt(builder.length() - 1);
}
}
}