一、题目 给定 M(0 < M ≤ 30)个字符(a-z),从中取出任意字符(每个字符只能用一次)拼接成长度为 N(0 < N ≤ 5)的字符串,
要求相同的字符不能相邻,计算出给定的字符列表能拼接出多少种满足条件的字符串,
输入非法或者无法拼接出满足条件的字符串则返回0。
二、输入 1 给定的字符列表和结果字符串长度,中间使用空格(" ")拼接
三、输出
四、示例 示例一
五、题解
理解题意后就是一个字符串的排列数问题
题目中求排列的字符有重复,这会造成排列结果中出现重复。这通常通过排序和剪枝(保证相同字符在排列结果中前后相对顺序)来解决
题目中还有一个约束是相同字符不能相邻,这和第 2 个约束是不同的。这个相邻体现在排列结果中;上面的体现在解法中,目的是为了结果去重
5.1 Java 实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 package org.stone.study.algo.ex202411;import java.util.Arrays;import java.util.Scanner;public class StringConcatenation { private int ans = 0 ; public static void main (String[] args) { Scanner scanner = new Scanner (System.in); String str = scanner.next(); int n = scanner.nextInt(); int ans = new StringConcatenation ().countPermutations(str, n); System.out.println(ans); } public int countPermutations (String str, int n) { char [] arr = str.toCharArray(); int m = arr.length; if (m < n) { return 0 ; } Arrays.sort(arr); boolean [] used = new boolean [m]; Arrays.fill(used, false ); dfs(arr, -1 , 0 , used, n); return ans; } private void dfs (char [] arr, int pre, int count, boolean [] used, int n) { if (count == n) { ans++; return ; } for (int i = 0 ; i < arr.length; i++) { if (used[i]) { continue ; } if (pre >= 0 && arr[i] == arr[pre]) { continue ; } if (i > 0 && arr[i] == arr[i-1 ] &&!used[i-1 ]) { continue ; } used[i] = true ; dfs(arr, i, count + 1 , used, n); used[i] = false ; } } }
5.2 Python实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 def count_permutations (s, n ): if len (s) < n: return 0 arr = sorted (s) ans = 0 used = [False ] * len (arr) def backtrack (pre, count ): nonlocal ans if count == n: ans += 1 return for i in range (len (arr)): if used[i]: continue if pre >= 0 and arr[i] == arr[pre]: continue if i > 0 and arr[i] == arr[i - 1 ] and not used[i - 1 ]: continue used[i] = True backtrack(i, count + 1 ) used[i] = False return ans backtrack(-1 , 0 ) return ans if __name__ == '__main__' : s1, s2 = input ().split() n = int (s2) print (count_permutations(s1, n))