这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战
5. 最长回文子串
给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入:s = "babad" 输出:"bab" 解释:"aba" 同样是符合题意的答案。 示例 2:
输入:s = "cbbd" 输出:"bb" 示例 3:
输入:s = "a" 输出:"a" 示例 4:
输入:s = "ac" 输出:"a"
提示:
- 1 <= s.length <= 1000
- s 仅由数字和英文字母(大写和/或小写)组成
解题思路
数组含义
dp[i][j]代表字符串s[i...j]是否为回文子串
初始化
只有一个字符的dp[i][i]必为回文
状态转移
如果dp[i][j]为回文子串,那么必须满足dp[i+1][j-1]=true即为回文子串并且s[i]=s[j]
代码
class Solution {
public String longestPalindrome(String s) {
int n=s.length();
boolean[][] dp = new boolean[n][n];
for (int i=0;i<n;i++) dp[i][i]=true;
for (int l=2;l<=n;l++)
for (int j=0;j+l-1<n;j++)
{
if (l==2)
{
dp[j][j+l-1]=s.charAt(j) == s.charAt(j + l - 1);
}else {
dp[j][j+l-1]= s.charAt(j ) == s.charAt(j + l - 1) && dp[j + 1][j + l - 2];
}
}
for (int l=n;l>=2;l--)
for (int j=0;j+l-1<n;j++)
if (dp[j][j+l-1])
return s.substring(j,j+l);
return s.charAt(0)+"";
}
}
438. 找到字符串中所有字母异位词
给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
异位词 指字母相同,但排列不同的字符串。
示例 1:
输入: s = "cbaebabacd", p = "abc" 输出: [0,6] 解释: 起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。 起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。 示例 2:
输入: s = "abab", p = "ab" 输出: [0,1,2] 解释: 起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。 起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。 起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。
解题思路
使用滑动窗口,窗口的大小为p的长度,使用数组维护窗口内字母和字符串p的差值,当26个字母的差值都为0时,说明当前s的子串和匹配上了
代码
class Solution {
public List<Integer> findAnagrams(String s, String p) {
List<Integer> list=new ArrayList<>();
int[] pp = new int[26];
int n=s.length(),m=p.length();
if(n<m) return list;
for (int i=0;i<m;i++)
{
pp[p.charAt(i)-'a']++;
pp[s.charAt(i)-'a']--;
}
int r=m-1;
while (r<n)
{
int i=0;
for (;i<26;i++)
if (pp[i]!=0)
break;
if (i==26){
list.add(r-m+1);
}
pp[s.charAt(r-m+1)-'a']++;
r++;
if(r<n)
pp[s.charAt(r)-'a']--;
}
return list;
}
}