Java 计算给定字符串数组的所有可能不同的3位数字的数目
下面是我的代码,用于计算正确工作的不同3位字符串的数量,但是,我希望优化此代码,以提高时间复杂度。有人能帮我拿这个吗 输入:[1,2,1,4] 产出:12 谢谢Java 计算给定字符串数组的所有可能不同的3位数字的数目,java,algorithm,count,time-complexity,unique,Java,Algorithm,Count,Time Complexity,Unique,下面是我的代码,用于计算正确工作的不同3位字符串的数量,但是,我希望优化此代码,以提高时间复杂度。有人能帮我拿这个吗 输入:[1,2,1,4] 产出:12 谢谢 static int countUnique(String [] arr) { Set<String> s = new TreeSet<>(); for (int i = 0; i<arr.length; i++) { for (int j = 0; j<arr
static int countUnique(String [] arr)
{
Set<String> s = new TreeSet<>();
for (int i = 0; i<arr.length; i++)
{
for (int j = 0; j<arr.length; j++)
{
for (int k = 0; k<arr.length; k++)
{
if (i!=j && j != k && i!=k)
s.add((arr[i] +""+arr[j]+""+arr[k]));
}
}
}
return s.size();
}
static int countUnique(字符串[]arr)
{
Set s=新树集();
对于(inti=0;i这里有一个O(n)
解决方案:
依次迭代每个不同的可用数字
(A) 如果有三个实例,则添加1,表示此数字的三个字符串中的一个字符串
(B) 如果有两个实例,则将已迭代的位数增加3倍,占3。选择2种方式将此位数的两个实例与另一个已迭代的位数排列在一起
(C) 加上我们可以从迄今为止看到的两个数字中选择两个的方法的数量,考虑到每个数字只安排一个实例
(D) 最后,将两位数排列方式的计数添加到我们的记录中:如果该位数有两个实例,则添加3选择2=3,说明仅排列了该位数的两个实例。同时添加(2*3选择2=6)乘以已迭代的位数,说明将此位数与已看到的另一位数进行排列的方法的数量
例如:
1 2 1 4
1 -> D applies, add 3 to the two-digit-arrangements count
11x, 1x1, x11
2 -> C applies, add 3 to result
112, 121, 211
D applies, add 6 to the two-digit-arrangements count (total 9)
12x, 1x2, x12, 21x, 2x1, x21
4 -> C applies, add 9 to result
Result 12
随机测试的JavaScript代码,与暴力方法相比:
函数f(A){
常量计数={};
为了(让a的a)
计数[a]=计数[a]?-~计数[a]:1;
设结果=0;
设numtwodigitaranges=0;
设numSeen=0;
对于(对象键(计数)的d){
如果(计数[d]>2)
结果+=1;
如果(计数[d]>1)
结果+=3*numSeen;
结果+=数字排列数;
如果(计数[d]>1)
numtwo数字排列+=3;
numtwo数字安排+=6*numSeen;
numSeen=numSeen+1;
}
返回结果;
}
函数bruteForce(arr){
常数s=新集合();
对于(设i=0;i另一种解决方法是使用回溯算法。任何组合或排列类型的问题都可以使用回溯算法来解决。
以下是有关回溯算法的一些信息-
注意:这不是最优化的解决方案,也不是O(n)解决方案。此解决方案是O(n!*n)。但有很多机会使其更优化
使用回溯的Java代码:
int countUniqueOpt(String[] arr) {
//Set to avoid duplicates
Set<String> resultList = new HashSet<>();
backtracking(arr, 3, resultList, new ArrayList<>());
return resultList.size();
}
void backtracking(String[] arr, int k, Set<String> resultList, List<Integer> indexList) {
if (indexList.size() == k) {
String tempString = arr[indexList.get(0)] + arr[indexList.get(1)] + arr[indexList.get(2)];
resultList.add(tempString);
} else {
for (int i = 0; i < arr.length; i++) {
if (!indexList.contains(i)) {
indexList.add(i);
backtracking(arr, k, resultList, indexList);
indexList.remove(indexList.size() - 1);
}
}
}
}
int countUniqueOpt(字符串[]arr){
//设置为避免重复
Set resultList=new HashSet();
回溯(arr,3,resultList,new ArrayList());
返回resultList.size();
}
无效回溯(字符串[]arr,int k,集合结果列表,列表索引列表){
if(indexList.size()=k){
字符串tempString=arr[indexList.get(0)]+arr[indexList.get(1)]+arr[indexList.get(2)];
结果列表.add(临时字符串);
}否则{
对于(int i=0;i
不要使用暴力,你需要考虑算法。你可以从这里开始:或谷歌“java组合数学教程”对于其他来源。我想说你的问题看起来像是纯数学。作为一个提示:组合学的基础知识应该足够了。@Ecto基本组合学对于这个问题实际上是不够的,即使它对于一些类似的问题来说也是如此。为什么你的输入字符串?你需要担心会产生相同的输出字符串吗通过多组不同的输入字符串(例如,您的输入是[1,12,23,3,4]
,您可以从12
+3
+4
或1
+23
+4
)生成1234
)?或者您只是使用字符串和串联作为生成集合
的可比值的简单方法?@KarlKnechtel OP声明其代码工作正常。因此,输入元素是由OP的正确代码指示的单个数字。任务限制为3位长度。