438. 找到字符串中所有字母异位词 AND 5. 最长回文子串

167 阅读1分钟

这是我参与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;
    }
}