i need you to give me code do the same work as this import java.util.*;

class RectangleGridPermutations {
    private static Set<String> uniquePositioningStates = new HashSet<>();
    private static Rectangle[] rectangles;
    private static List<Integer> minimumDimensions;
    private static String[][] grid;
    private static int totalArea;

    public static void main(String[] args) {
        long startTime = System.nanoTime();

        rectangles = new Rectangle[]{
                new Rectangle(2, 1, "A"),
                new Rectangle(2, 1, "B"),
                new Rectangle(3, 1, "C"),
                new Rectangle(3, 5, "D"),
                new Rectangle(4, 3, "E"),
                new Rectangle(4, 2, "F"),
                new Rectangle(7, 1, "G"),
                new Rectangle(7, 1, "H"),
                new Rectangle(1, 8, "I"),
                new Rectangle(8, 2, "J"),
                new Rectangle(3, 2, "K"),
                new Rectangle(5, 2, "L"),
                new Rectangle(8, 1, "M"),
                new Rectangle(8, 1, "N"),
//                new Rectangle(8, 1, "O"),
        };

        Arrays.sort(rectangles, (r1, r2) -> r2.space - r1.space); // Sort by descending area
        totalArea = Arrays.stream(rectangles).mapToInt(r -> r.space).sum();

        minimumDimensions = calculateMinimumDimensions(rectangles);
        int minHeight = minimumDimensions.get(0);
        int minWidth = minimumDimensions.get(1);

        for (int height = minHeight; height * minWidth <= totalArea; height++) {
            if (totalArea % height == 0) {
                int width = totalArea / height;
                grid = new String[height][width];
                backtrack(0);
            }
        }
        if(!uniquePositioningStates.isEmpty())
//                for (String state : uniquePositioningStates) {
//                printGrid(state);
//                System.out.println();
//            }
//            for (String state : uniquePositioningStates) {
//                printGridWithSpaces(state);
//                System.out.println();
//            }
            System.out.println("Possible positioning states number: " + uniquePositioningStates.size());

        long endTime = System.nanoTime();
        System.out.println("Elapsed time: " + (endTime - startTime) / 1_000_000_000.0 + " seconds");
    }

    private static void backtrack(int idx) {
        if (idx == rectangles.length) {
            uniquePositioningStates.add(gridToString());
            return;
        }

        Rectangle rect = rectangles[idx];
        int gridHeight = grid.length;
        int gridWidth = grid[0].length;

        for (int row = 0; row <= gridHeight - rect.height; row++) {
            for (int col = 0; col <= gridWidth - rect.width; col++) {
                if (canPlaceRectangle(row, col, rect)) {
                    placeRectangle(row, col, rect, true);
                    backtrack(idx + 1);
                    placeRectangle(row, col, rect, false);
                }
            }
        }
    }
    public static boolean checkSpaces(int index,int gridHeight,int gridWidth) {
        int lastUsedRow = 0;
        int lastUsedCol = 0;
        for (int i = 0; i < gridHeight; i++)
            for (int j = 0; j < gridWidth; j++)
                if (grid[i][j] != null) {
                    lastUsedRow = Math.max(lastUsedRow, i + 1);
                    lastUsedCol = Math.max(lastUsedCol, j + 1);
                }
        int space = lastUsedRow * lastUsedCol;
//
//        int remindsSpace =calculateTotalArea2(Arrays.copyOfRange(rectangles, index, rectangles.length));
//        int placedSpace =calculateTotalArea2(Arrays.copyOfRange(rectangles, 0, index));
//        if((space-placedSpace)>remindsSpace)
//            return false;
//        if((space-placedSpace)>totalArea)
//            return false;

        return space <= totalArea;
    }
    private static boolean canPlaceRectangle(int row, int col, Rectangle rect) {
        for (int i = row; i < row + rect.height; i++) {
            for (int j = col; j < col + rect.width; j++) {
                if (grid[i][j] != null) return false;
            }
        }
        return true;
    }

    private static void placeRectangle(int row, int col, Rectangle rect, boolean place) {
        for (int i = row; i < row + rect.height; i++) {
            for (int j = col; j < col + rect.width; j++) {
                grid[i][j] = place ? rect.name : null;
            }
        }
    }

    private static List<Integer> calculateMinimumDimensions(Rectangle[] rectangles) {
        int minWidth = Arrays.stream(rectangles).mapToInt(r -> r.width).max().getAsInt();
        int minHeight = Arrays.stream(rectangles).mapToInt(r -> r.height).max().getAsInt();
        return Arrays.asList(minHeight, minWidth);
    }

    private static String gridToString() {
        StringBuilder sb = new StringBuilder();
        for (String[] row : grid) {
            sb.append(String.join("", row)).append("\n");
        }
        return sb.toString();
    }
    private static void printGrid(String gridState) {
        System.out.println(gridState);
    }
    private static void printGridWithSpaces(String gridState) {

        for(char c :gridState.toCharArray())
            System.out.print(" "+c);
    }
    static class Rectangle {
        int width, height;
        String name;
        int space;

        Rectangle(int width, int height, String name) {
            this.width = width;
            this.height = height;
            this.name = name;
            this.space = width * height;
        }
    }
} but with o(!n) only time complexity in java