1、无重复字符的最长子串
3. 无重复字符的最长子串
滑动窗口解题。设置一个map来存储字符与其出现的位置,再定义窗口的开始与结束指针。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public static int lengthOfLongestSubstring(String s) { if (s == null || s.isEmpty()) { return 0; } int res = 0; Map<Character, Integer> map = new HashMap<>(); for (int start = 0, end = 0; end < s.length(); end++) { char c = s.charAt(end); if (map.containsKey(c)) { start = Math.max(map.get(c), start); } res = Math.max(end - start + 1, res); map.put(c, end + 1); } return res; }
|
2、 最长公共子序列
1143. 最长公共子序列
涉及到两个字符串求子序列的问题,一般都是动态规划的范畴。难点就是要找到状态转换方程。
定义一个二维数组 dp 用来存储最长公共子序列的长度,其中 dp[i][j] 表示 S1 的前 i 个字符与 S2 的前 j 个字符最长公共子序列的长度。考虑 S1i 与 S2j 值是否相等,分为下面两种情况:
参考这个!!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public static int longestCommonSubsequence(String text1, String text2) { if (text1 == null || text1.isEmpty()) { return 0; } if (text2 == null || text2.isEmpty()) { return 0; } int n1 = text1.length(), n2 = text2.length(); int[][] dp = new int[n1 + 1][n2 + 1]; for (int i = 1; i <= n1; i++) { for (int j = 1; j <= n2; j++) { if (text1.charAt(i - 1) == text2.charAt(j - 1)) { dp[i][j] = dp[i - 1][j - 1] + 1; } else { dp[i][j] = Math.max(dp[i][j - 1], dp[i - 1][j]); } } } return dp[n1][n2]; }
|
3、最长重复子数组
718. 最长重复子数组
动态规划问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public static int findLength(int[] A, int[] B) { if (A.length <= 0 || B.length <= 0) { return 0; } int result = 0; int n = A.length; int m = B.length; int[][] dp = new int[n + 1][m + 1]; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { if (A[i - 1] == B[j - 1]) { dp[i][j] = dp[i - 1][j - 1] + 1; result = Math.max(result, dp[i][j]); } } } return result; }
|
4、字符串反转
使用两个指针。
1 2 3 4 5 6 7 8 9 10 11 12 13
| public static void reverseString(char[] s) { if (s.length <= 1) { return; } int left = 0, right = s.length - 1; while (left < right) { char tmp = s[left]; s[left++] = s[right]; s[right--] = tmp; } }
|
5、字符串能否由字典中单词组成
给定一个字符串s和一个字典dict,判断字符串能否有字典中的字符串组成,字典中的字符串可以出现多次。例如s=“Ilovebytedance”,dict={“I”,“love”,“bytedance”}
用动态规划,dp[i]表示字符串s[0~i]是否可分的bool值。
字节跳动 单词拼接
139. 单词拆分
参考这里!!!
也是动态规划问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public static boolean wordBreak(String s, List<String> wordDict) { Set<String> wordDictSet = new HashSet(wordDict); boolean[] dp = new boolean[s.length() + 1]; dp[0] = true; for (int i = 1; i <= s.length(); i++) { for (int j = 0; j < i; j++) { if (dp[j] && wordDictSet.contains(s.substring(j, i))) { dp[i] = true; break; } } } return dp[s.length()]; }
|
6、给定字符串的全排列
算法题解:给定一个字符串输出其全排列形式的所有字符串(JAVA代码)
字符串的全排列 Java实现
递归加回溯思想。
总结
字符串常见的算法解决思路好多都是动态规划问题。
