无重复字符的最长子串
来源:力扣(LeetCode) 链接:leetcode.cn/problems/lo…
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
提示:
- 0 <= s.length <= 5 * 104 = s 由英文字母、数字、符号和空格组成
代码
class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length();
int maxLength = 0;
int start = 0;
Map<Character, Integer> charMap = new HashMap<>();
for (int end = 0; end < n; end++) {
char c = s.charAt(end);
if (charMap.containsKey(c)) {
start = Math.max(start, charMap.get(c) + 1);
}
charMap.put(c, end);
maxLength = Math.max(maxLength, end - start + 1);
}
return maxLength;
}
}
思路分析
- 定义一个窗口的起始位置
start、最大长度maxLength,以及一个哈希表charMap用于记录字符的索引。 - 遍历字符串
s的每个字符,使用双指针来构建滑动窗口。 - 如果当前字符
c在哈希表charMap中存在,并且其索引大于等于窗口的起始位置start,则更新start为该字符的索引加1,即将窗口的起始位置右移。 - 将当前字符
c及其索引存入哈希表charMap中。 - 计算当前窗口的长度,即
end - start + 1,并更新maxLength为最大长度。 - 重复步骤2至步骤5,直到遍历完整个字符串。
- 返回最大长度
maxLength。
最长回文子串
来源:力扣(LeetCode) 链接:leetcode.cn/problems/lo…
给你一个字符串 s,找到 s 中最长的回文子串。
如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。
示例 1:
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd"
输出:"bb"
提示:
- 1 <= s.length <= 1000
- s 仅由数字和英文字母组成
代码
class Solution {
public String longestPalindrome(String s) {
int n = s.length();
boolean[][] dp = new boolean[n][n];
int maxLength = 0;
int start = 0;
// 初始化单个字符和相邻两个字符的回文串
for (int i = 0; i < n; i++) {
dp[i][i] = true;
if (i < n - 1 && s.charAt(i) == s.charAt(i + 1)) {
dp[i][i + 1] = true;
start = i;
maxLength = 2;
}
}
// 从长度为3的回文串开始判断
for (int len = 3; len <= n; len++) {
for (int i = 0; i <= n - len; i++) {
int j = i + len - 1;
if (s.charAt(i) == s.charAt(j) && dp[i + 1][j - 1]) {
dp[i][j] = true;
start = i;
maxLength = len;
}
}
}
return s.substring(start, start + maxLength);
}
}
思路分析
- 定义一个二维布尔数组
dp,其中dp[i][j]表示字符串从索引i到索引j的子串是否为回文串。 - 初始化单个字符和相邻两个字符的回文串,即
dp[i][i] = true和dp[i][i+1] = true,并记录最长回文串的起始位置start和长度maxLength。 - 从长度为3的回文串开始判断。外层循环控制回文串的长度,内层循环遍历字符串,判断子串是否为回文串。
- 如果子串的两端字符相等,并且子串去掉两端字符后仍为回文串,则当前子串也为回文串,将
dp[i][j]设为true,并更新最长回文串的起始位置start和长度maxLength。 - 重复步骤3和步骤4,直到遍历完整个字符串。
- 返回最长回文子串,即根据起始位置
start和长度maxLength从原字符串中截取。