尝试获取列表中的上一个条目时出现Java IndexOutOfBounds

hivapdat  于 2022-12-21  发布在  Java
关注(0)|答案(4)|浏览(120)

我正在处理一个问题,你应该返回n行pascals triangle given和int n,然后把它作为一个List of Lists返回,但是当我试图调用前一行的时候,我得到了一个index out of bounds异常,我不确定为什么
'

public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> triangle = new ArrayList<List<Integer>>();
        List<Integer> row = new ArrayList<>();
        for(int i = 0; i < numRows; i++){
            for(int j = 0; j <= i; j++){
                if(j == 0 || j == i){
                    row.add(1);
                }
                else{
                    if(i != 0 && j != 0){
                        int num = triangle.get(i-1).get(j-1) + triangle.get(i-1).get(j);
                        row.add(num);
                    }
                }
            }
            triangle.add(row);
            row.clear();
        }
        return triangle;
    }

I added the if(i != 0 && j != 0)行,希望解决该问题,但错误仍然存在。

rbl8hiat

rbl8hiat1#

我发现你的代码有问题,问题是你试图在Pascal三角形的前一行元素被添加到三角形列表之前访问它们,换句话说,你试图在i为0时访问外部循环的同一次迭代中的triangle.get(i-1)。
解决此问题的一种方法是将生成三角形每一行的内部循环移动到单独的函数。然后,您可以手动添加三角形的第一行,并调用该函数生成后续行。这将确保在您尝试访问之前,前面的行已添加到三角形列表中。
下面是修改后的代码,可以解决索引超出边界异常:

public List<List<Integer>> generate(int numRows) {
    List<List<Integer>> triangle = new ArrayList<List<Integer>>();
    if (numRows == 0) return triangle;

    // Add the first row manually
    triangle.add(Arrays.asList(1));

    // Generate the remaining rows
    for (int i = 1; i < numRows; i++) {
        List<Integer> row = new ArrayList<>();
        for (int j = 0; j <= i; j++) {
            if (j == 0 || j == i) {
                row.add(1);
            } else {
                int num = triangle.get(i-1).get(j-1) + triangle.get(i-1).get(j);
                row.add(num);
            }
        }
        triangle.add(row);
    }

    return triangle;
}

我希望这有帮助!让我知道如果你有任何问题或如果你需要进一步澄清。

iq3niunx

iq3niunx2#

计算正在执行的new语句的数量。
我只数出了两条新语句,都是在循环开始之前。

  • 这意味着有2个数组列表。总计*。

假设你的代码应该返回比这更多的列表,这是如何工作的呢?嗯,java是基于引用的。所有的非原语值实际上都是references。它就像地址簿中的一个页面,而不是一个房子。List<Integer> row = new ArrayList<>();做两件事:

  • 它建造了一座房子(这就是new ArrayList<>();部分)
  • 它把这所房子的地址写在一页上,标题是“行”。
  • triangle.add(row)将简单地创建地址簿页面**的副本,而不是房子的副本。您只需写下地址,然后走到房子前面,粉碎里面的所有东西(row.clear()),然后重新开始,你不断地重新填充同一个房子,把里面的所有东西都砸了,triangle是一个包含许多页的地址簿,每一页都有相同的地址,所有这些都通向一所房子,在那里有人反复把它装满,把它砸得粉碎。

这让我们回到:计算new
在这里,您可以选择一个5行sierpinski,总共列出6个列表:每一行1个列表,然后再一个作为列表的列表。这意味着我需要执行6个“new”语句。

798qvoo8

798qvoo83#

您需要删除row.clear();你正在清除你刚添加到三角形中的行的内容,你这样做的原因是你认为你可以继续向三角形中添加同一行;您需要为每个循环创建一个新行。

62lalag4

62lalag44#

您在如何使用/重用row的列表方面犯了一个错误。
你必须为每一行创建一个全新的List,否则,你会在三角形的每一行中放置相同的示例,并在每一行中添加完全相同的数字。
你的行为产生了这样一个“三角形”:

1

11
11

第三行必须从第二行获取值,但是它失败了,因为您在计算第三行之前清除了该行(因此同时清除了每一行)。
需要进行以下更改:

public List<List<Integer>> generate(int numRows) {
  List<List<Integer>> triangle = new ArrayList<List<Integer>>();

  for(int i = 0; i < numRows; i++){
    List<Integer> row = new ArrayList<>();  // <<-- new row instead of clearing it

    ...
  }

  trangle.add(row);
  // row.clear(); // <-- this was the second part of the mistake

相关问题