【算法题】面试题:给定字符串数组是否可以拼接成指定字符串

今天阿里面试官给出了一道题,判断字符串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;
    }

}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值