【问题标题】:Find number of positions containing similar length查找包含相似长度的位置数
【发布时间】:2017-12-16 07:21:01
【问题描述】:

很久以后我开始用java编程了。目前,我正在练习来自http://codingbat.com/prob/p198640的问题

以下是问题描述:

给定 2 个字符串 a 和 b,返回它们包含相同长度的 2 子字符串的位置数。所以 "xxcaazz" 和 "xxbaaz" 的结果是 3,因为 "xx"、"aa" 和 "az" 子字符串出现在两个字符串中的相同位置。

示例包括:

  • stringMatch("xxcaazz", "xxbaaz") → 3
  • stringMatch("abc", "abc") → 2
  • stringMatch("abc", "axc") → 0

以下是我对通过所有测试用例的问题的解决方案:

public int stringMatch(String a, String b) {
  int counter = 0;
  Set<String> set = new HashSet<String>();
  int[] nums = new int[a.length()];
  for(int i=0;i<nums.length;i++){
    nums[i] = 0;
  }
  for(int i=0;i<b.length()-1;i++){
    for(int j=0;j<a.length()-1;j++){
      if((a.substring(j,j+2).equals(b.substring(i,i+2))) && ((nums[j]+nums[j+1]<2)) & (!set.contains(b.substring(i,i+2)))){
        nums[j] = 1;
        nums[j+1] = 1;
        set.add(b.substring(j,j+2));
        counter = counter + 1;
      }
    }
  }
  return counter;
}

我觉得我的解决方案确实效率低下。我想我正在使用 o(n2) 时间和 o(n) 空间复杂度。有没有办法更好地解决这个问题?谢谢!

更新: 基于 cmets,我能够减少到只有一个循环。我仍然不确定 Set 是否需要 o(n) 空间。我可以将其减少到 o(1) 吗?

下面是我通过所有测试用例的工作代码:

public int stringMatch(String a, String b) {
  int counter = 0;
  Set<String> set = new HashSet<String>();
  String longer = "";
  String shorter = "";
  if(a.length() >= b.length()){
    longer = a;
    shorter = b;
  }
  else{
    longer = b;
    shorter = a;
  }
  int[] nums = new int[longer.length()];
  for(int i=0;i<shorter.length()-1;i++){
    if((shorter.substring(i,i+2).equals(longer.substring(i,i+2))) && ((nums[i]+nums[i+1]<2)) & (!set.contains(shorter.substring(i,i+2)))){
        nums[i] = 1;
        nums[i+1] = 1;
        set.add(shorter.substring(i,i+2));
        counter = counter + 1;
    }
  }
  return counter;
}

【问题讨论】:

  • 你只需要一个for循环,因为子字符串必须出现在同一个地方
  • 旁注:您无需将nums 显式设置为0。整数数组的所有值默认为0。
  • @randnum-1 感谢您的观察。我进行了更改以仅使用一个循环。您如何看待空间复杂度?我能做得更好吗?
  • @MichaelMarkidis 谢谢!
  • 为什么你有这一套?没有提到子字符串必须不同。

标签: java arrays string loops


【解决方案1】:

这个呢

  public  int stringMatch(String a, String b) {
    int counter = 0;
    for (int i = 0; i < (a.length()>b.length()?b.length():a.length()) - 1; i++) {
      if ((a.substring(i, i + 2).equals(b.substring(i, i + 2)))) {
        counter++;
      }
    }
    return counter;
  }

【讨论】:

    【解决方案2】:

    我用一组不同长度的任意字符串测试了你的代码,发现循环10000次需要258ms,在相同条件下,下面的代码需要130ms:

    public int stringMatch(String a, String b) {
        int counter = 0;
        Set<Short> set = new HashSet<Short>();
        byte[] longer, shorter;
        if (a.length() >= b.length()) {
            longer = a.getBytes();
            shorter = b.getBytes();
        } else {
            longer = b.getBytes();
            shorter = a.getBytes();
        }
        for (int i = 0; i < shorter.length - 1; i++) {
            short s = (short) (shorter[i] << 8 | shorter[i + 1]);
            if (!set.contains(s) && 
                shorter[i] == longer[i] && shorter[i + 1] == longer[i + 1])
                if (set.add(s))
                    counter++;
        }
        return counter;
    }
    

    由于您的语句不涉及重复,不检查重复字符串,以下代码需要 72 毫秒:

    public int stringMatch(String a, String b) {
        int counter = 0;
        byte[] longer, shorter;
        if (a.length() >= b.length()) {
            longer = a.getBytes();
            shorter = b.getBytes();
        } else {
            longer = b.getBytes();
            shorter = a.getBytes();
        }
        for (int i = 0; i < shorter.length - 1; i++)
            if (shorter[i] == longer[i] && shorter[i + 1] == longer[i + 1])
                counter++;
        return counter;
    }
    

    【讨论】:

    • 您需要使用字符数组而不是字节数组。请注意,有些字符需要超过一个字节。
    • @Henry 没错,但这只是一个例子,例如用 char[] 而不是 byte[] 很容易死;
    • @Henry 没错,但这只是一个例子,用 char[] 而不是 byte[] 很容易死掉,例如: ... Set set = new HashSet(); char[] 更长,更短; if (a.length() >= b.length()) { long = a.toCharArray();更短 = b.toCharArray(); ... for (int i = 0; i
    猜你喜欢
    • 2012-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-19
    • 2016-09-01
    • 1970-01-01
    相关资源
    最近更新 更多