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 ,不做探讨。
当你看清人们的真相,于是你知道了,你可以忍受孤独
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构