Java [Hackerrank][性能改进]类似目的地
我目前正在解决我在Hackerrank上发现的一个难题,我需要代码优化/性能部门的一些帮助。我已经设法让代码正常工作并返回正确的结果,但在最终测试用例中失败,出现了超时错误。输入非常大,这就解释了为什么代码花费的时间比预期的要长 问题陈述:Java [Hackerrank][性能改进]类似目的地,java,algorithm,performance,Java,Algorithm,Performance,我目前正在解决我在Hackerrank上发现的一个难题,我需要代码优化/性能部门的一些帮助。我已经设法让代码正常工作并返回正确的结果,但在最终测试用例中失败,出现了超时错误。输入非常大,这就解释了为什么代码花费的时间比预期的要长 问题陈述: 我曾试图用不同的方法来修剪我的(中间)结果集,但却无法想出一些我还没有的东西。我相信find函数需要更多的调整。我已经尽了最大努力减少递归函数必须采用的路径数,但最终,它必须查看每个目的地,以得到正确的结果。但是,如果目的地之间的公共标记数低于min限制,
我曾试图用不同的方法来修剪我的(中间)结果集,但却无法想出一些我还没有的东西。我相信
find
函数需要更多的调整。我已经尽了最大努力减少递归函数必须采用的路径数,但最终,它必须查看每个目的地,以得到正确的结果。但是,如果目的地之间的公共标记数低于min
限制,我确实终止了递归路径。这里还有什么我可以做的吗
我的代码如下:-
static class Destination {
String dest;
List<String> tags;
public Destination(String dest, List<String> tags) {
this.dest = dest;
this.tags = tags;
}
@Override
public String toString() {
return dest;
}
}
static List<Destination> allDest = new ArrayList<Destination>();
static int min;
static Set<String> keysTracker = new HashSet<String>();
static Set<String> tagsTracker = new HashSet<String>();
static Map<String, List<String>> keysAndTags = new HashMap<String, List<String>>();
static void find(List<String> commonKey, List<String> commonTags, int index) {
if (index >= allDest.size())
return;
if (commonTags.size() < min)
return;
if (tagsTracker.contains(commonTags.toString()) || keysTracker.contains(commonKey.toString())) {
return;
}
String dest = allDest.get(index).dest;
commonKey.add(dest);
for (int i = index + 1; i < allDest.size(); ++i) {
List<String> tempKeys = new ArrayList<String>(commonKey);
List<String> tags = allDest.get(i).tags;
List<String> tempTags = new ArrayList<String>(commonTags);
tempTags.retainAll(tags);
find(tempKeys, tempTags, i);
if (tempTags.size() >= min) {
if (!tagsTracker.contains(tempTags.toString())
&& !keysTracker.contains(tempKeys.toString())) {
tagsTracker.add(tempTags.toString());
keysTracker.add(tempKeys.toString());
StringBuilder sb = new StringBuilder();
for (int j = 0; j < tempKeys.size(); ++j) {
sb.append(tempKeys.get(j));
if (j + 1 < tempKeys.size())
sb.append(",");
}
keysAndTags.put(sb.toString(), tempTags);
}
}
}
}
public static void main(String[] args) {
init();
sort();
calculate();
answer();
}
static void init() {
Scanner s = new Scanner(System.in);
min = s.nextInt();
s.nextLine();
String line;
while (s.hasNextLine()) {
line = s.nextLine();
if (line.isEmpty())
break;
String[] tokens = line.split(":");
String dest = tokens[0];
tokens = tokens[1].split(",");
List<String> tags = new ArrayList<String>();
for (int j = 0; j < tokens.length; ++j)
tags.add(tokens[j]);
Collections.sort(tags);
Destination d = new Destination(dest, tags);
allDest.add(d);
}
s.close();
}
static void sort() {
Collections.sort(allDest, new Comparator<Destination>() {
@Override
public int compare(Destination d1, Destination d2) {
return d1.dest.compareTo(d2.dest);
}
});
}
static void calculate() {
for (int i = 0; i < allDest.size() - 1; ++i) {
find(new ArrayList<String>(), new ArrayList<String>(allDest.get(i).tags), i);
}
}
static void answer() {
List<Map.Entry<String, List<String>>> mapInListForm = sortAnswer();
for (Map.Entry<String, List<String>> entry : mapInListForm) {
System.out.print(entry.getKey() + ":");
for (int i = 0; i < entry.getValue().size(); ++i) {
System.out.print(entry.getValue().get(i));
if (i + 1 < entry.getValue().size())
System.out.print(",");
}
System.out.println();
}
}
static List<Map.Entry<String, List<String>>> sortAnswer() {
List<Map.Entry<String, List<String>>> mapInListForm =
new LinkedList<Map.Entry<String, List<String>>>(keysAndTags.entrySet());
Collections.sort(mapInListForm, new Comparator<Map.Entry<String, List<String>>>() {
public int compare(Map.Entry<String, List<String>> e1, Map.Entry<String, List<String>> e2) {
if (e1.getValue().size() > e2.getValue().size()) {
return -1;
} else if (e1.getValue().size() < e2.getValue().size()) {
return 1;
}
return e1.getKey().compareTo(e2.getKey());
}
});
return mapInListForm;
}
静态类目的地{
字符串dest;
列出标签;
公共目的地(字符串目的地、列表标记){
this.dest=dest;
this.tags=标签;
}
@凌驾
公共字符串toString(){
返回目的地;
}
}
静态列表allDest=newarraylist();
静态int-min;
静态设置keysTracker=newhashset();
static Set tagsTracker=new HashSet();
静态映射keysAndTags=newhashmap();
静态void查找(列表commonKey、列表commonTags、int索引){
如果(索引>=allDest.size())
返回;
if(commonTags.size()=min){
如果(!tagsTracker.contains(testtags.toString())
&&!keysTracker.contains(tempKeys.toString())){
tagsTracker.add(testags.toString());
添加(tempKeys.toString());
StringBuilder sb=新的StringBuilder();
对于(int j=0;je2.getValue().size()){
返回-1;
}else if(e1.getValue().size()
非常感谢您的帮助。谢谢 经过一点选择性分析后,我成功地解决了这个问题。看来我最初的预感是对的。问题与算法无关,而与我使用的数据结构有关!罪犯使用了
查找方法。具体来说,在两个列表上调用retainal
方法时。我忘记了迭代两个列表需要O(n^2)时间。这就是它慢的原因。然后我将list
改为HashSet
。我们大多数人都知道,HashSet
在访问其值时具有O(1)时间复杂性。retainAll
方法保留了下来,但是我们现在找到的不是两个列表之间的交集,而是两个集合之间的交集!这使得总运行时间缩短了几秒钟,所有测试都通过了。:)
find
方法现在如下所示:-
static void find(List<String> commonKey, List<String> commonTags, int index) {
if (index >= allDest.size())
return;
if (commonTags.size() < min)
return;
if (tagsTracker.contains(commonTags.toString()) || keysTracker.contains(commonKey.toString())) {
return;
}
String dest = allDest.get(index).dest;
commonKey.add(dest);
for (int i = index + 1; i < allDest.size(); ++i) {
List<String> tempKeys = new ArrayList<String>(commonKey);
List<String> tags = allDest.get(i).tags;
Set<String> tempTagsSet1 = new HashSet<String>(commonTags);
Set<String> tempTagsSet2 = new HashSet<String>(tags);
tempTagsSet1.retainAll(tempTagsSet2);
List<String> tempTags = new ArrayList<String>(tempTagsSet1);
if (tempTags.size() >= min)
Collections.sort(tempTags);
find(tempKeys, tempTags, i);
if (tempTags.size() >= min) {
if (!tagsTracker.contains(tempTags.toString())
&& !keysTracker.contains(tempKeys.toString())) {
tagsTracker.add(tempTags.toString());
keysTracker.add(tempKeys.toString());
StringBuilder sb = new StringBuilder();
for (int j = 0; j < tempKeys.size(); ++j) {
sb.append(tempKeys.get(j));
if (j + 1 < tempKeys.size())
sb.append(",");
}
keysAndTags.put(sb.toString(), tempTags);
}
}
}
}
static void find(列出commonKey、列出commonTags、int索引){
如果(索引>=allDest.size())
返回;
if(commonTags.size()