zoukankan      html  css  js  c++  java
  • leetcode647- Palindromic Substrings- medium

    Given a string, your task is to count how many palindromic substrings in this string.

    The substrings with different start indexes or end indexes are counted as different substrings even they consist of same characters.

    Example 1:

    Input: "abc"
    Output: 3
    Explanation: Three palindromic strings: "a", "b", "c".
    

    Example 2:

    Input: "aaa"
    Output: 6
    Explanation: Six palindromic strings: "a", "a", "a", "aa", "aa", "aaa".
    

    Note:

    1. The input string length won't exceed 1000.

    算法:

    1.遍历确认法。写一个判断是否正确的子函数。然后主函数里双重for循环,头尾指针夹住substring去判断是不是,用cnt计数。

    2.DP。数组定义是dp[i][j]表示s.substring(i, j)是不是palindrome. 转移方程是dp[i][j] = s.charAt(i) == s.charAt(j) && ((j - i < 3) || dp[i + 1][j - 1])。而且注意因为状态转移方程里你需要的是下一个i,上一个j,所以你for循环遍历应该要i往左走,j往右走,同时j还要保证比i大,所以最后表现形式是 for(int i = s.length() - 1; i >= 0; i--) { for (int j = i + 1; j <= s.length(); j++) { ... }}。

    细节:1. char和char可以直接==对比,而且char是没有equals方法的,只有Character才有。string.charAt返回的是char不是Character,所以不要对它调用equals()方法,直接==。

    2.DP的状态转移方程里那个当字符串长度是1,2,3的特殊情况的时候写法要注意,不写那个调用之前的dp数组会出现ij大小交叉还有指针越界。

    实现

    1.遍历确认法

    class Solution {
        public int countSubstrings(String s) {
            if (s == null) {
                return 0;
            }
            int cnt = 0;
            for (int i = 0; i < s.length(); i++) {
                for (int j = i + 1; j <= s.length(); j++) {
                    if (isPalindrome(s.substring(i, j))) {
                        cnt++;
                    }
                }
            }
            return cnt;
        }
        
        private boolean isPalindrome(String s) {
            for (int i = 0, j = s.length() - 1; i < j; i++,j--) {
                if (s.charAt(i) != s.charAt(j)) {
                    return false;
                }
            }
            return true;
        }
    }

    2.DP

    class Solution {
        public int countSubstrings(String s) {
            if (s == null) {
                return 0;
            }
            int n = s.length();
            boolean[][] dp = new boolean[n][n];
            
            int cnt = 0;
            for (int i = n - 1; i >= 0; i--) {
                for (int j = i; j < n; j++) {
                    dp[i][j] = s.charAt(i) == s.charAt(j) && (j - i <= 2 || dp[i + 1][j - 1]);
                    if (dp[i][j]) {
                        cnt++;
                    }
                }
            }
            return cnt;
        }
    }
  • 相关阅读:
    Mybatis中Log4j日志的使用
    Mybatis结果集ResultMap映射
    Mybatis中的基本对象的生命周期和作用域
    IAR瑞萨单片机开发加入printf调试函数
    【转】C语言mem.h中的函数介绍
    【转】c语言位域操作—_结构体内冒号:的使用
    串口数据传输当中的共用体和结构体转换
    【转】printf格式串中的%f的输出格式和内容
    【转】缓冲区设计--环形队列(C++)
    【转】环形队列理论(C语言)
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/7927368.html
Copyright © 2011-2022 走看看