public int[] findVerticalSeam() {
    // sequence of indices for vertical seam

    ST<Double, int[]> shortestPathTable = new ST<Double, int[]>();
    pixelEnergy = new double[width()][height()];

    for (int x = 0; x < width(); x++) {
      for (int y = 0; y < height(); y++) {
        pixelEnergy[x][y] = energy(x, y);
      }
    }

    for (int col = 0; col < width(); col++) {
      int x = col;
      int y = 0;
      int[] array = new int[height()];
      double pathLength = pixelEnergy[x][y];
      double path1, path2, path3;

      array[y] = x;
      while (y < height() - 1) {
        if (x == 0) {
          path1 = pathLength + pixelEnergy[x][y + 1];
          path2 = pathLength + pixelEnergy[x + 1][y + 1];
          if (path1 < path2) {
            pathLength = path1;
          } else {
            pathLength = path2;
            x = x + 1;
          }
        } else if (x == width() - 1) {
          path1 = pathLength + pixelEnergy[x][y + 1];
          path2 = pathLength + pixelEnergy[x - 1][y + 1];
          if (path1 < path2) {
            pathLength = path1;
          } else {
            pathLength = path2;
            x = x - 1;
          }
        } else {
          path1 = pathLength + pixelEnergy[x][y + 1];
          path2 = pathLength + pixelEnergy[x - 1][y + 1];
          path3 = pathLength + pixelEnergy[x + 1][y + 1];

          if (path1 <= path2 && path1 <= path3) {
            pathLength = path1;
          }
          if (path2 <= path1 && path2 <= path3) {
            x = x - 1;
            pathLength = path2;
          }
          if (path3 <= path1 && path3 <= path2) {
            x = x + 1;
            pathLength = path3;
          }
        }
        y = y + 1;
        array[y] = x;
      }
      shortestPathTable.put(pathLength, array);
    }

    return shortestPathTable.get(shortestPathTable.min());
  }