LeetCode 5240. 串联字符串的最大长度 - Java - 回溯算法

36 篇文章 0 订阅
30 篇文章 1 订阅

一、题目

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

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

1、示例1

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

2、示例2

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

3、示例3

输入:arr = [“abcdefghijklmnopqrstuvwxyz”]
输出:26

4、提示

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

二、题解

根据提示可以看到数据不是很大。可以考虑使用 回溯算法 。至于题目的隐藏提示说的用DP,我暂时没考虑。

回溯思路很简单。

每个字符串有两种情况。
1、加到字符串 s
2、不加到字符串 s 中。
按照这两种情况试探即可。@wowpH

用一个大小为26的 boolean 型数组保存已经在字符串 s 中字符的情况。true 表示字符串 s 中有该字符。

时间复杂度 O ( 2 n ) O(2^n) O(2n)
空间复杂度 O ( n ) O(n) O(n)


三、Java代码

/**
 * @link: https://blog.csdn.net/pfdvnah/article/details/102787485
 * @date: 2019年10月29日12:16:54
 * @author: wowpH
 * @author: pfdvnah
 */
class Solution {
	public int maxLength(List<String> list) {
		return backtrack(list, 0, new boolean[26]);
	}

	private int backtrack(	List<String> list,
							int depth,
							boolean[] flag) {// 对应字符是否已存在
		if (depth == list.size()) {// 超出范围
			return 0;
		}
		// 不连接第depth个字符串
		int ret1 = backtrack(list, depth + 1, flag);
		// 尝试连接第depth个字符串
		char[] arr = list.get(depth).toCharArray();
		boolean[] nFlag = flag.clone();// 避免改变原数据
		for (char ch : arr) {
			// 已存在,说明第depth个字符串不符合要求
			if (nFlag[ch - 'a']) {
				return ret1;// 返回不连接的最大长度
			}// @pfdvnah
			nFlag[ch - 'a'] = true;// 设为存在
		}
		// 连接第depth个字符串
		int ret2 = backtrack(list, depth + 1, nFlag);// 新的字符集
		return Math.max(ret1, ret2 + arr.length);// 加上当前长度
	}
}

四、相关链接

题目链接:https://leetcode-cn.com/contest/weekly-contest-160/problems/maximum-length-of-a-concatenated-string-with-unique-characters/
参考Caloplaca代码:https://leetcode-cn.com/contest/weekly-contest-160/ranking/
原文链接:https://blog.csdn.net/pfdvnah/article/details/102787485


- End - wowpH - pfdvnah -
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值