[leetcode 周赛 160] 1239 串联字符串的最大长度

1239 Maximum Length of a Concatenated String with Unique Characters 串联字符串的最大长度

问题描述

给定一个字符串数组 arr,字符串 s 是将 arr 某一子序列字符串连接所得的字符串,如果 s 中的每一个字符都只出现过一次,那么它就是一个可行解。

请返回所有可行解 s 中最长长度。

示例 1:

输入: arr = ["un","iq","ue"]
输出: 4
解释: 所有可能的串联组合是 "","un","iq","ue","uniq" 和 "ique",最大长度为 4。

示例 2:

输入: arr = ["cha","r","act","ers"]
输出: 6
解释: 可能的解答有 "chaers" 和 "acters"。

示例 3:

输入: arr = ["abcdefghijklmnopqrstuvwxyz"]
输出: 26

提示:

  • 1 <= arr.length <= 16
  • 1 <= arr[i].length <= 26
  • arr[i] 中只含有小写英文字母

思路

  • 读题
    题目需要的字符串是一个没有重复字符的字符串, 所提供的字符串数组, 可以进行拼接, 得到最长的那个没有重复字符的字符串.

回溯法(递归)+DFS剪枝

分析算法规模: 递归深度最多16层, 运算规模最大2^17(回溯树上节点)
遍历所有可能的解, 尝试不同字符串的组合(回溯)
回溯法

代码实现

回溯法(递归)+DFS剪枝

class Solution {
    private int ans = 0;

    public int maxLength(List<String> arr) {
        if (arr == null) {
            return 0;
        }

        // 遍历整个字符串数组 获得符合条件的单个字符串最大长度
        for (String ar : arr) {
            if (nonDuplicate(ar)) {
                ans = Math.max(ar.length(), ans);
            }
        }
        // DFS 从0开始 初始字符串为空串
        helper(arr, 0, "");

        return ans;
    }

    private void helper(List<String> arr, int idx, String prev) {
        // 剪枝 没有重复(符合条件)才可以继续往下走
        if (nonDuplicate(prev)) {
            ans = Math.max(prev.length(), ans);
        } else {
            return;
        }

        // 最后一个节点 返回
        if (idx > arr.size()) {
            return;
        }
        // 当前字符串
        String cur = arr.get(idx);
        // 添加
        helper(arr, idx + 1, prev + cur);
        // 不添加
        helper(arr, idx + 1, prev);
    }

    private boolean nonDuplicate(String str) {
        return str.chars().distinct().count() == str.length();
    }
}

参考资源

第 160 场周赛 全球排名

posted @ 2019-11-08 21:52  slowbird  阅读(683)  评论(0编辑  收藏  举报