如果我使用交换和置换方法生成排列,我知道处理重复的问题here。
但是,我正在使用一种不同的方法,我在当前字符生成的所有排列的开头和结尾之间放置当前字符。
如何修改下面的代码,只在包含重复项的字符串中为我提供唯一的排列
import java.util.ArrayList;
public class Permutations {
public static void main(String[] args) {
String str = "baab";
System.out.println(fun(str, 0));
System.out.println("number of Permutations =="+fun(str, 0).size());
}
static ArrayList<String> fun(String str, int index)
{
if(index == str.length())
{
ArrayList<String> al = new ArrayList<String>();
al.add("");
return al;
}
/* get return from lower frame */
ArrayList<String> rec = fun(str, index+1);
/* get character here */
char c = str.charAt(index);
/* to each of the returned Strings in ArrayList, add str.charAt(j) */
ArrayList<String> ret = new ArrayList<String>();
for(int i = 0;i<rec.size();i++)
{
String here = rec.get(i);
ret.add(c + here);
for(int j = 0;j<here.length();j++)
ret.add(here.substring(0,j+1) + c + here.substring(j+1,here.length()));
}
return ret;
}
}
此刻,诸如“bab”之类的字符串会生成以下输出,其中包含abb和bba多次。
[bab, abb, abb, bba, bba, bab]
number of Permutations ==6
PS:我不想使用hashmap / Set来跟踪我的重复项,看看它们之前是否遇到过。
答案 0 :(得分:2)
当您在字符串中迭代并在每个位置添加字符时,如果您在字符串中找到与您要插入的字符相同的字符,请在插入新字符之后立即中断。这意味着具有相同字符的字符串不止一次只能以一种方式形成(通过以相反的顺序插入),因此不会发生重复。
for(int j = 0;j<here.length();j++)
{
if(here.charAt(j) == c)
break;
ret.add(here.substring(0,j+1) + c + here.substring(j+1,here.length()));
}
解决这些涉及生成集合而没有重复的问题的一般方法是考虑每个重复集中只有一个具有的属性,然后将其强制为约束。例如,在这种情况下,约束是&#34;所有重复的字符以相反的顺序添加&#34; (正向顺序也会起作用,但你必须翻转循环方向)。对于订单不重要的组合问题,约束可以是&#34;每个列表中的项目按升序排列&#34;。等等。