今天阿里面试官给出了一道题,判断字符串str是否能够由字符串数组arr中的元素组合拼接组成,arr中的字符可以重复使用。
输入示例:
str="aabbcc",arr=["a","abb","c"] true
str="helloworld",arr=["hello","world","c"] true
str="catsandog",arr=["cats","and","dog"] false
str="",arr=["ab","cd","ef"] false
str="abc",arr=[] false
面试只有20分钟,当下首先想到的就是使用双指针去匹配
面试只有20分钟,当下首先想到的就是使用双指针去匹配,用哈希表存储字符串数组:
- 左指针作为当前匹配字符串的起点,右指针作为终点
for (; right <= str.length(); right++) {
String substring = str.substring(left, right);
if (set.contains(substring)) {
// 回溯 继续判断
// 匹配到,需要跳过这个字符
if (backTrace_concat(str, arr, right, set)) {
return true;
}
} else {
}
}
- 如果当前匹配到字符串,左指针移动匹配到的字符串位置,继续往后递归判断,直到所有位置字符都能匹配到(结束标志为left移动到字符串末尾)
left >= target.length()
如果当前位置匹配到,但是后续递归没有全部匹配成功,则当前位置匹配失败,右指针移动,重新匹配。
下面是全部代码,本地测试了几个案例,都已通过,如有错误或者可以优化的地方,请网友指点。
public class test1 {
public static void main(String[] args) {
Solution solution = new Solution();
// String str = "abc";
// String[] arr = {"ab", "abc"};
// String str = "abcd";
// String[] arr = {"ab", "cd", "ef"};
// String str = "";
// String[] arr = {"ab", "cd", "ef"};
// String str = "abc";
// String[] arr = {};
String str = "abcabc";
String[] arr = {"ab", "c"};
// System.out.println(canConstruct(target, arr)); // true
System.out.println(concat(str, arr)); // 时间复杂度O(n^2)
}
public static boolean concat(String str, String[] arr) {
if (null == str || str.length() == 0 || null == arr || arr.length == 0) {
return false;
}
Set<String> set = new HashSet<>();
for (String s : arr) {
set.add(s);
}
return backTrace_concat(str, arr, 0, set);
}
public static boolean backTrace_concat(String str, String[] arr, int start, Set<String> set) {
if (start >= str.length()) {
return true;
}
int left = start;
int right = left + 1;
for (; right <= str.length(); right++) {
String substring = str.substring(left, right);
if (set.contains(substring)) {
// 回溯 继续判断
// 匹配到,需要跳过这个字符
if (backTrace_concat(str, arr, right, set)) {
return true;
}
} else {
}
}
return false;
}
}