From 36913ce39ed1d0916156909c6744c6fdf6d3f0ad Mon Sep 17 00:00:00 2001 From: markilue <745518019@qq.com> Date: Thu, 2 Mar 2023 20:06:36 +0800 Subject: [PATCH] =?UTF-8?q?leecode=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../markilue/leecode/hot100/T10_IsMatch.java | 142 ++++++++++++++++++ .../markilue/leecode/hot100/T11_ThreeSum.java | 71 +++++++++ .../hot100/T12_LetterCombinations.java | 56 +++++++ 3 files changed, 269 insertions(+) create mode 100644 Leecode/src/main/java/com/markilue/leecode/hot100/T10_IsMatch.java create mode 100644 Leecode/src/main/java/com/markilue/leecode/hot100/T11_ThreeSum.java create mode 100644 Leecode/src/main/java/com/markilue/leecode/hot100/T12_LetterCombinations.java diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/T10_IsMatch.java b/Leecode/src/main/java/com/markilue/leecode/hot100/T10_IsMatch.java new file mode 100644 index 0000000..8d058b4 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/T10_IsMatch.java @@ -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); + } + +} diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/T11_ThreeSum.java b/Leecode/src/main/java/com/markilue/leecode/hot100/T11_ThreeSum.java new file mode 100644 index 0000000..e81eef4 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/T11_ThreeSum.java @@ -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 != j、i != 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> threeSum(int[] nums) { + + List> 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; + + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/T12_LetterCombinations.java b/Leecode/src/main/java/com/markilue/leecode/hot100/T12_LetterCombinations.java new file mode 100644 index 0000000..b1b9330 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/T12_LetterCombinations.java @@ -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> 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 result = new ArrayList<>(); + + public List 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 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); + } + + } +}