【发布时间】: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 谢谢!
-
为什么你有这一套?没有提到子字符串必须不同。