zoukankan      html  css  js  c++  java
  • Leetcode647 回文子串,转化问题建立缓存

    记忆化递归解法:

    //结果计数
        int an = 0;
    
        /**
         * @Author Niuxy
         * @Date 2020/6/30 10:38 下午
         * @Description 外部循环,以每个元素开头的子串
         * 内部循环,以每个元素结尾的子串
         * 就可以遍历到所有长度大于 1 的可能的子串
         */
        public final int countSubstrings(String s) {
            int[][] cache = new int[s.length()][s.length()];
            for (int i = 0; i < s.length(); i++) {
                for (int j = i + 1; j < s.length(); j++) {
                    isSubstring(s, i, j, cache);
                }
            }
            return an + s.length();
        }
    
        public final boolean isSubstring(String s, int begin, int end, int[][] cache) {
            if (begin == end) {
                return true;
            }
            //缓存加去重
            if (cache[begin][end] != 0) {
                return cache[begin][end] == 1 ? true : false;
            }
            if (begin == end - 1) {
                boolean re = s.charAt(begin) == s.charAt(end);
                //边界计数
                an += re == true ? 1 : 0;
                //边界去重
                cache[begin][end] = re == true ? 1 : 2;
                return re;
            }
            if (s.charAt(begin) != s.charAt(end)) {
                cache[begin][end] = 2;
                return false;
            }
            boolean re = isSubstring(s, begin + 1, end - 1, cache);
            cache[begin][end] = re == true ? 1 : 2;
            //计数
            an += re == true ? 1 : 0;
            return re;
        }

    转为递推:

    public final int countSubstringsDP(String s){
            if(s.length()==1){return 1;}
            int[][] dp=new int[s.length()][s.length()];
            int an=0;
            //初始化边界
            for(int i=0;i<s.length()-1;i++){
                dp[i][i]=1;
                an++;
                if(s.charAt(i)==s.charAt(i+1)){
                    dp[i][i+1]=1;
                    an++;
                }
            }
            // dp 开始
            for(int i=s.length()-1;i>=0;i--){
                for(int j=i+2;j<s.length();j++){
                    if(s.charAt(i)==s.charAt(j)){
                        if(dp[i+1][j-1]==1){
                            dp[i][j]=1;
                            an++;
                        }
                    }
                }
            }
            return an+1;
        }

    结果排名不是很理想,比较快的做法为马拉车算法,但做这题是为了练习 DP ,不做探讨。

  • 相关阅读:
    使用 linux kernel +busybox 定制linux系统
    记一次golang的内存泄露
    关于Queries_per_sec 性能计数器
    NUMA导致的MySQL服务器SWAP问题分析
    Drop Table对MySQL的性能影响分析
    当MySQL数据库遇到Syn Flooding
    tcp_tw_recycle参数引发的数据库连接异常
    一例数据同步异常问题分析
    MySQL大量线程处于Opening tables的问题分析
    MySQL DeadLock故障排查过程
  • 原文地址:https://www.cnblogs.com/niuyourou/p/13216646.html
Copyright © 2011-2022 走看看