Hackerrank: 夏洛克与字谜

huangapple go评论76阅读模式
英文:

Hackerrank: Sherlock and Anagrams

问题

static int sherlockAndAnagrams(String s) {
    HashMap<String, Integer> map = new HashMap<String, Integer>();
    int d, i, k = 0;
    int length = s.length();
    int n = length * (length + 1) / 2;
    String[] sub = new String[n];
    for (d = 0; d < length; d++) {
        for (i = d + 1; i <= length; i++) {
            sub[k++] = s.substring(d, i);
        }
    }
    int[] c = new int[26];

    int result = 0;
    for (int l = 0; l < n; l++) {
        for (int m = 0; m < 25; m++) {
            c[m] = 0;
        }
        char[] suba = sub[l].toCharArray();
        for (char ch : suba) {
            c[ch - 'a'] += 1;
        }
        String temp = Arrays.toString(c);
        Integer x = map.get(temp);
        if (x != null) {
            result = result + x;
            map.put(temp, ++x);
        } else {
            map.put(temp, 1);
        }
    }
    return result;
}
英文:

Problem description: <https://www.hackerrank.com/challenges/sherlock-and-anagrams>

Adding a snapshot of the problem statement:
Hackerrank: 夏洛克与字谜

I am getting only few test cases correct. My algorithm is:
<ol>
<li>Find all substrings of given string.
<li>create code for each substring by using array for each alphabet.
<li>converting that code to string and map that string using hashmap.
<li>increment result if a substring's map value contains non zero value.
</ol>
My code:

 static int sherlockAndAnagrams(String s) {
 HashMap&lt;String,Integer&gt; map = new HashMap&lt;String,Integer&gt;();
 int d,i,k=0;
 int length = s.length();
 int n = length*(length+1)/2;
 String []sub = new String[n]; 
 for (d = 0; d &lt; length; d++){
     for(i = d+1; i &lt;= length; i++)
      {
        sub[k++] = s.substring(d, i);
      }
  }
int []c = new int[26];

  int result=0;;
for(int l=0;l&lt;n;l++){
    for(int m=0;m&lt;25;m++){
    c[m] = 0;
    }
   char []suba = sub[l].toCharArray();  
  for(char ch : suba){
      c[ch-&#39;a&#39;]+=1;
  }
  String temp = Arrays.toString(c);
  Integer x = map.get(temp);
  if(x!=null){
      result = result+x;
    map.put(temp,++x);}
  else{
  map.put(temp,1);
   }
  }
  return result;
}

答案1

得分: 2

好的,这里有几件事情。

  • 你需要计算配对数,而不是计算碰撞次数。

  • 因此,应该是 result = result + x;

  • 另外,map.put(...,x++) 应该改为 map.put(...,++x);,因为我们将会用一个预增加的值来更新。

  • 另外,你对 c 的填充范围是从 024,但应该是从 025。最好的做法是直接使用 Arrays.fill(c, 0)


为了节省空间,我们可以完全避免在数组中获取每个子数组,而是根据字符对子数组进行排序。这样,每个字谜都会映射到地图中的相同键,帮助你避免在 sub 字符串数组中显式存储每个数组。然而,整体的空间复杂度仍将保持不变。

英文:

Ok, so a couple of things here.

  • You have to count pairs and not how many collide.

  • So, it would be result = result + x;

  • Also, map.put(...,x++) should be map.put(...,++x); as we are going to update with a pre-incremented value.

  • Also, your filling of c goes from 0 to 24 but it should be 0 to 25. It's a better practice to just do Arrays.fill(c,0) for that matter.


For space efficiency, we can completely avoid taking each subarray in an array and rather just sort the subarray based on characters. This way, every anagram will map to the same key in the map, helping you to avoid storing each array explicitly in the sub string array. However, the overall space complexity would remain the same.

huangapple
  • 本文由 发表于 2020年4月7日 21:14:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/61080856.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定