Issue
In the afternoon, one of the students in the group came up with a simple algorithm problem, which means that there are more than one cubic meter boxes in a room, and multiple boxes can fall vertically together, asking: how many cubic meters of water can be stored in the remaining space (as shown in the figure).
My algorithm is not good all the time, but the brain has to adapt to the following problems.
Solving problems
In short, we are used to the questions of string, array and linked list. The author hopes to influence the following ideas of the author through a variety of ways. In fact, this problem can be an array problem, that is, the abscissa is used as the index, and the height of the ordinate box is used as the array value, so it can be simply changed into: [0,1,0,4,1,0,1,3...]
According to the barrel theory, it can be known that the influence of water content is determined by the shortest looking board, so the idea is to find the first height and the second height in the array within the specified index interval. The steps of these two indexes are taken as the width and the second height as the height, and then subtract all boxes in the interval to get the final value:
Width * height - occupied box
Code
private static int sum = 0; private static List list = new ArrayList(); list.add(0); list.add(1); list.add(0); list.add(4); list.add(1); list.add(0); list.add(1); list.add(3); list.add(0); list.add(6); list.add(0); list.add(1); list.add(0); list.add(3); getSum(0, list.size() - 1); System.out.println("sum:" + sum);
By recursion, we get the pair high value and the second high value in a given interval, and get the middle area
private static void getSum(int start, int end) { // Get the first and second highs int firstIndex = 0; int firstH = 0; int secondIndex = 0; int secondH = 0; int h = 0; for (int i = start; i <= end; i++) { h = Integer.parseInt(list.get(i).toString()); if (h > firstH) { firstH = h; firstIndex = i; } } for (int i = start; i <= end; i++) { if (i == firstIndex) continue; h = Integer.parseInt(list.get(i).toString()); if (h > secondH) { secondH = h; secondIndex = i; } } int left = firstIndex >= secondIndex ? secondIndex : firstIndex; int right = secondIndex >= firstIndex ? secondIndex : firstIndex; if (right - left == 1) return; // Get full area h = firstH > secondH ? secondH : firstH; int skip = right - left - 1; int count = skip * h; // Delete occupied block int remove = removeBlock(left + 1, right); sum += count; sum -= remove; if (left - start > 1) getSum(start, left + 1); if (end - right > 1) getSum(right - 1, end); }
Delete the entity box in the range
private static int removeBlock(int start, int end) { int remove = 0; for (int i = start; i < end; i++) { remove += Integer.parseInt(list.get(i).toString()); } return remove; }