力扣前200题字符串总结
哈希表:
3.无重复字符的最长子串
12.整数转罗马数字 并且按照从大到小的顺序依次枚举
17.电话号码的字母组合 + dfs
49.字母异位词分组 + char[26].toString()
√ 87.扰乱字符串
class Solution {HashMap<String, Boolean> map = new HashMap<>();public boolean isScramble(String s1, String s2) {if(s1.length() != s2.length()) return false;return helper(s1, s2);}public boolean helper(String s1, String s2) {String key = s1 + "#" + s2;if(map.containsKey(key)) return map.get(key);if(s1.equals(s2)) {map.put(key, true);return true;}int len = s1.length();if(len == 1) {map.put(key, false);return false;}int[] count1 = new int[26];int[] count2 = new int[26];for(int i = 0; i < s1.length(); i++) count1[s1.charAt(i) - 'a']++;for(int i = 0; i < s2.length(); i++) count2[s2.charAt(i) - 'a']++;for(int i = 0; i < 26; i++) {if(count1[i] != count2[i]) {map.put(s1 + "#" + s2, false);return false;}}for(int k = 1; k < len; k++) {boolean cond1 = helper(s1.substring(0, k), s2.substring(len - k)) &&helper(s1.substring(k), s2.substring(0, len - k));boolean cond2 = helper(s1.substring(0, k), s2.substring(0, k)) &&helper(s1.substring(k), s2.substring(k));if(cond1 || cond2) {map.put(s1 + "#" + s2, true);return true;}}map.put(key, false);return false;}
}
√ 166.分数到小数 用哈希表存循环小数的位置
class Solution {public String fractionToDecimal(int numerator, int denominator) {if(numerator == 0) return "0";StringBuilder sb = new StringBuilder();String sign = (numerator > 0) ^ (denominator > 0) ? "-" : "";sb.append(sign);long n = Math.abs((long)numerator);long d = Math.abs((long)denominator);long res = n / d;sb.append(res);n %= d;if(n == 0) return sb.toString();sb.append('.');HashMap<Long, Integer> map = new HashMap<>();while(n != 0) {n *= 10;long tmp = n / d;sb.append(tmp);n %= d;if(map.containsKey(n)) {int idx = map.get(n);sb.insert(idx, '(');sb.append(')');break;}else {map.put(n, sb.length());} }return sb.toString();}
}
205.同构字符串
双指针:
5.最长回文子串,分奇偶讨论
76.最小覆盖子串
125.验证回文串
纯遍历:
6.Z字形变换
8.字符串转换整数
14.最长公共前缀
√ 30.串联所有单词的子串 + 哈希表
class Solution {public List<Integer> findSubstring(String s, String[] words) {List<Integer> res = new ArrayList<>();HashMap<String, Integer> map = new HashMap<>();for(String word: words) map.put(word, map.getOrDefault(word, 0) + 1);int wordlen = words[0].length(), cntlen = words.length;for(int i = 0; i < wordlen; i++) {int left = i, right = i;int cnt = 0;HashMap<String, Integer> cur = new HashMap<>();while(right + wordlen <= s.length()) {String subs = s.substring(right, right + wordlen);right += wordlen;if(map.containsKey(subs)) {cur.put(subs, cur.getOrDefault(subs, 0) + 1);cnt++;while(cur.get(subs) > map.get(subs)) {String subs1 = s.substring(left, left + wordlen);cur.put(subs1, cur.get(subs1) - 1);cnt--;left += wordlen;}if(cnt == cntlen) res.add(left);}else {left = right;cur = new HashMap<>();cnt = 0;}}}return res;}
}
38.外观数列
43.字符串相乘 两个数组遍历,考虑进位
58.最后一个单词的长度
65.有效数字
67.二进制求和 /2、%2
√ 68.文本左右对齐
class Solution {public List<String> fullJustify(String[] words, int maxWidth) {List<String> res = new ArrayList<>();List<String> line = new ArrayList<>();int i = 0, len = 0;while(i < words.length) {if(line.size() + len + words[i].length() > maxWidth) {int spaces = maxWidth - len;int space_ave = spaces / Math.max(1, line.size() - 1);int space_remain = spaces % Math.max(1, line.size() - 1);for(int j = 0; j < Math.max(1, line.size() - 1); j++) {for(int k = 0; k < space_ave; k++) line.set(j, line.get(j) + " ");;// for(int m = 0; m < space_remain; m++) line.get(j) += " ";if(space_remain > 0) {line.set(j, line.get(j) + " ");space_remain--;}}StringBuilder sb = new StringBuilder();for(String s: line) sb.append(s);res.add(sb.toString());line = new ArrayList<>();len = 0;}line.add(words[i]);len += words[i].length();i++;}// 最后一行StringBuilder sb = new StringBuilder();for (int j = 0; j < line.size(); j++) {sb.append(line.get(j));if (j != line.size() - 1) sb.append(" ");}int space_last = maxWidth - sb.length();for(int k = 0; k < space_last; k++) sb.append(" ");res.add(sb.toString());return res;}
}
71.简化路径
139.单词拆分
151.反转字符串中的单词
165.比较版本号
168.Excel表列名称 ( - 1)/ 26、% 26
179.最大数 两两交换比较
187.重复的DNA序列
dfs:
√ 10.正则表达式匹配
class Solution {public boolean isMatch(String s, String p) {return dfs(0, s, 0, p);}public boolean dfs(int i, String s, int j, String p) {int lens = s.length();int lenp = p.length();if(i >= lens && j >= lenp) return true;if(j >= lenp) return i >= lens;boolean match = (i < lens && (s.charAt(i) == p.charAt(j) || p.charAt(j) == '.' ));if(j + 1 < lenp && p.charAt(j + 1) =='*') {return (match && dfs(i + 1, s, j, p)) || dfs(i, s, j + 2, p);}if(match) return dfs(i + 1, s, j + 1, p);return false;}
}
22.括号生成
79.单词搜索
93.复原IP地址
131.分割回文串
√ 132.分割回文串II
class Solution {public int minCut(String s) {int[] dp = new int[s.length()];Arrays.fill(dp, -1);int res = helper(s, 0, s.length(), dp);return res - 1;}public int helper(String s, int start, int end, int[] dp) {if(start == end) return 0;if(dp[start] != -1) return dp[start];int res = Integer.MAX_VALUE;for(int i = start; i < s.length(); i++) {if(isPalindrome(s, start, i)) {int cnt = 1 + helper(s, i + 1, end, dp);res = Math.min(res, cnt);}dp[start] = res;}return res;}public boolean isPalindrome(String s, int i, int j) {// int i = 0, j = s.length() - 1;while(i < j) {if(s.charAt(i) != s.charAt(j)) return false;i++;j--;}return true;}
}
√ 140.单词拆分II
class Solution {List<String> res = new ArrayList<>();public List<String> wordBreak(String s, List<String> wordDict) {Set<String> set = new HashSet<>(wordDict);// List<String> path = new ArrayList<>();// for (int i = 0; i < s.length(); i++) {List<String> path = new ArrayList<>();helper(s, 0, set, path);// }return res;}public void helper(String s, int i, Set<String> set, List<String> path) {if (i == s.length()) {StringBuilder sb = new StringBuilder();for (int j = 0; j < path.size() - 1; j++) {sb.append(path.get(j));sb.append(" ");}sb.append(path.get(path.size() - 1));res.add(sb.toString());return;}for (int j = i; j < s.length(); j++) {String subs = s.substring(i, j + 1);if (set.contains(subs)) {path.add(subs);helper(s, j + 1, set, path);path.remove(path.size() - 1);}}}
}
KMP算法:
28.找出字符串中第一个匹配项的下标
栈:
20.有效的括号
32.最长有效括号
171.Excel表列序号
dp:
44.通配符匹配
72.编辑距离
√ 91.解码方法
class Solution {public int numDecodings(String s) {if(s.charAt(0) == '0') return 0;int[] dp = new int[s.length() + 1];dp[0] = 1;dp[1] = (s.charAt(0) == '0') ? 0 : 1;for(int i = 2; i < dp.length; i++) {if(s.charAt(i - 1) != '0') dp[i] += dp[i - 1];int two = Integer.parseInt(s.substring(i - 2, i));if(two >= 10 && two <= 26) dp[i] += dp[i - 2];}return dp[s.length()];}
}
√ 97.交错字符串
class Solution {public boolean isInterleave(String s1, String s2, String s3) {if(s1.length() + s2.length() != s3.length()) return false;boolean[][] dp = new boolean[s1.length() + 1][s2.length() + 1];dp[0][0] = true;for(int i = 0; i <= s1.length(); i++) {for(int j = 0; j <= s2.length(); j++) {if(i > 0 && dp[i - 1][j] && s1.charAt(i - 1) == s3.charAt(i + j - 1)) dp[i][j] = true;if(j > 0 && dp[i][j - 1] && s2.charAt(j - 1) == s3.charAt(i + j - 1)) dp[i][j] = true;}}return dp[s1.length()][s2.length()];}
}
115.不同的子序列
bfs:
127.单词接龙
√ 126.单词接龙II + dfs
class Solution {Map<String, Integer> stepMap = new HashMap<>();Map<String, Set<String>> preMap = new HashMap<>();List<List<String>> res = new ArrayList<>();public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {Set<String> set = new HashSet<>(wordList);Queue<String> q = new LinkedList<>();if(!set.contains(endWord)) return res;q.offer(beginWord);stepMap.put(beginWord, 0);while(!q.isEmpty()) {String cur = q.poll();int step = stepMap.get(cur);char[] ch = cur.toCharArray();for(int i = 0; i < ch.length; i++) {char tmp = ch[i];for(char j = 'a'; j <= 'z'; j++) {if(j == tmp) continue;ch[i] = j;String nxt = new String(ch);if(set.contains(nxt)) {if(!stepMap.containsKey(nxt)) {stepMap.put(nxt, step + 1);q.offer(nxt);preMap.computeIfAbsent(nxt, k -> new HashSet<>()).add(cur);}else if(stepMap.get(nxt) == step + 1) {preMap.get(nxt).add(cur);}}}ch[i] = tmp;}}if(!preMap.containsKey(endWord)) return res;List<String> path = new ArrayList<>();path.add(endWord);dfs(beginWord, path);return res;}public void dfs(String beginWord, List<String> path) {String cur = path.getFirst();if(cur.equals(beginWord)) {res.add(new ArrayList<>(path));return;}if(!preMap.containsKey(cur)) return;for(String str: preMap.get(cur)) {path.addFirst(str);dfs(beginWord, path);path.removeFirst();}}
}
数据结构设计:
208.实现Trie(前缀树)
211.添加与搜索单词