【发布时间】:2020-12-08 22:40:03
【问题描述】:
给定一个整数数组(长度为 n),找到并返回输入数组的所有子集。 所以我已经解决了这个问题,但我不确定这里的基本概念。
这是正确的解决方案。
public static int[][] subsets(int input[]) {
return subsets(input,0);
}
private static int[][] subsets(int input[], int index){
if(index == input.length){
int[][] a = new int[1][0];
return a;
}
int[][] smallAns = subsets(input,index+1);
int[][] ans = new int[2*(smallAns.length)][];
for(int i = 0 ; i < smallAns.length ; ++i){
ans[i] = smallAns[i];
}
for(int i = 0 ; i < smallAns.length ; ++i){
ans[i+smallAns.length] = new int[smallAns[i].length+1];
}
for(int i = 0 ; i < smallAns.length ; ++i){
for(int j = 0 ; j < ans[i+smallAns.length].length ; ++j){
if(j == 0){
ans[i+smallAns.length][j] = input[index];
}
else{
ans[i+smallAns.length][j] = smallAns[i][j-1];
}
}
}
return ans;
}
这是我最初的解决方案:
public static int[][] subsets(int input[]) {
return subsets(input,0);
}
private static int[][] subsets(int input[], int index){
if(index == input.length){
int[][] a = new int[1][1];
return a;
}
int[][] smallAns = subsets(input,index+1);
int[][] ans = new int[2*(smallAns.length)][];
for(int i = 0 ; i < smallAns.length ; ++i){
ans[i] = smallAns[i];
}
for(int i = 0 ; i < smallAns.length ; ++i){
ans[i+smallAns.length] = new int[smallAns[i].length+1];
}
for(int i = 0 ; i < smallAns.length ; ++i){
for(int j = 0 ; j < ans[i+smallAns.length].length ; ++j){
if(j == 0){
ans[i+smallAns.length][j] = input[index];
}
else{
ans[i+smallAns.length][j] = smallAns[i][j-1];
}
}
}
return ans;
}
我的原始(第二个代码错误)代码在所有子集的末尾添加了 0。像这样
开头给出的正确代码解决了问题。这两个代码之间的唯一区别是第一个基本情况返回一个 1X1 矩阵(错误的),第二个基本情况返回一个 1X0 矩阵(正确一个)。但我很好奇在基本情况下返回一个 1X0 矩阵.有人可以解释一下当我尝试访问列的长度等时如何不抛出 nullPointerExceptions。
【问题讨论】:
-
1 x 0 矩阵与 1 x 1 矩阵并没有太大区别。在这两种情况下
a.length == 1和在这两种情况下,a[0]都是对int[]的有效、非空引用。因此,在这两种情况下,使用a[0].length询问列数都是安全的:毫无疑问,1x1 为 1,1x0 为 0。只是不要试图查看a[0][0]在 1x0 矩阵上是什么:你会得到ArrayIndexOutOfBoundsException: 0! -
@KevinAnderson 感谢您的洞察力,我现在很清楚。所以代码的工作方式是这样的,它获取递归的结果(smallAns(第一种情况下的 1X0 矩阵))复制它,并在递归结果的每个条目中添加一个数字,并将它们组合成一个更大的矩阵。我的疑问是,当它不存在时,在 1X0 矩阵的条目/条目的开头附加所选数字意味着什么。为什么没有 OurOfIndex 或 NullPointer 异常。我问题中的第一个代码正在工作,我只是不知道具体如何。谢谢。
-
考虑当你复制一个任意长度的数组“a”时会发生什么; 1) 设置计数器
j=0; 2)如果j >= a.length停止; 3)将a[j]复制到其目的地; 4) 递增 j (++j);并返回到第 2 步。如果数组的长度为 1,您将在j==a.length之前执行第 3 步一次,此时您就完成了。现在,如果a.length == 0会发生什么? 1) 设置计数 j=0; 2) 如果j >= a.length停止。j==0,a.length == 0,所以已经j >= a.length。循环永远不会到达第 (3) 步,您甚至都不会尝试访问a[0],所以没有ArrayIndexOutOfBoundsException。