java - 尝试给出很长的字符串时,SubString 给出 OutOfMemory 异常
问题描述
我正在编写这段代码,以应对来自 leet 代码的编码挑战。
这段代码适用于 987 个测试用例中的 986 个。对于非常长的字符串(长度 ~ 31600)的情况,它会失败。子字符串函数抛出 java.lang.OutOfMemoryError: Java heap space。
我尝试创建“子字符串” new SubString(s.substring(i,j)); 和 s.substring(i,j).intern(); 在看到其他堆栈溢出的建议之后。但徒劳
private static Map<String, Integer> findAllSubStrings(String s) {
Map<String, Integer> allSubStrings = new HashMap<>();
for(int i = 0; i<s.length(); i++) {
for(int j=i+1; j<=s.length(); j++) {
String substring = s.substring(i,j);
allSubStrings.put(substring, substring.length());
}
}
return allSubStrings;
}
例外是,
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.base/java.util.Arrays.copyOfRange(Arrays.java:4031)
at java.base/java.lang.StringLatin1.newString(StringLatin1.java:782)
at java.base/java.lang.String.substring(String.java:1888)
at main.LongestSubstring.findAllSubStrings(LongestSubstring.java:76)
at main.LongestSubstring.getLengthOfLongestSubString(LongestSubstring.java:44)
at main.LongestSubstring.main(LongestSubstring.java:38)
我正在寻找可以帮助我理解和解决此问题的人。
提前致谢。
解决方案
正如例外所说,您的空间不足。
对于长度为的字符串,n
需要n(n-1)/2
创建不同的子字符串;当 n 大约为 32,000 时,这相当于大约 5亿个子字符串。每个String
对象至少占用 16 个字节的堆(但可能更多,甚至假设它们都共享相同的底层char[]
,这样我们就不需要单独计算内容),所以你需要至少 8 GB 来代表它们。您的默认 Java 堆限制可能没有那么大。
您需要回到绘图板并提出一种算法,该算法不依赖于同时存在于内存中的所有子字符串。
推荐阅读
- php - 当 SQL 字符串具有“%f”时,Wordpress wpdp->getResults 不执行我的 sql
- ios - 将 Flutter 集成到 CocoaTouch SDK 中?
- system-verilog - 将 8 位值传递给 1 位端口?
- protocol-buffers - 如何将 OpenAPI Spec (Swagger 2.0) 转换为 proto3?
- python - 从坐标列表中分配所有可能的顶点组合并对其进行缩放
- c# - 即使在使用事务时,C# SQLite Bulk 参数化 DELETE 也会很慢?
- php - 在 Woocommerce 商店循环中添加限制为可用数量的产品数量字段
- angular - 在 Kubernetes 中运行 npm 应用程序
- android - 完成应用卸载后,Android 会“记住”共享偏好
- android - 使用 edujugon 推送通知的 Laravel Web 推送通知