1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| class Solution { public int minimumTotal(List<List<Integer>> triangle) { if (triangle.size() == 0 || triangle.get(0).size() == 0) { return 0; } Deque<Pair<Integer, Integer>> indexQ = new ArrayDeque<>(); indexQ.offer(new Pair(0, triangle.get(0).get(0))); int level = 0; for (level = 0; level < triangle.size() - 1; level++) { int size = indexQ.size(); for (int i = 0; i < size; i++) { Pair<Integer, Integer> currPair = indexQ.poll(); int currIndex = currPair.getKey(); int sumSoFar = currPair.getValue(); if (i > 0) { Pair<Integer, Integer> previousPair = indexQ.peekLast(); if (sumSoFar + triangle.get(level + 1).get(currIndex) < previousPair.getValue()) { indexQ.pollLast(); indexQ.offer(new Pair(currIndex, sumSoFar + triangle.get(level + 1).get(currIndex))); } } else { indexQ.offer(new Pair(currIndex, sumSoFar + triangle.get(level + 1).get(currIndex))); } indexQ.offer(new Pair(currIndex + 1, sumSoFar + triangle.get(level + 1).get(currIndex + 1))); } } int min = Integer.MAX_VALUE; while (!indexQ.isEmpty()) { min = Math.min(min, indexQ.poll().getValue()); } return min; } }
|
最正常的brute force, 也就是BFS. 但是要优化一下, 在遍历每一行, 添加下一行的candidates的时候, 除了最左边的数字, 每个数字添加的左邻居都会和之前一个数字添加的右邻居重合. 此时可以进行一个判断, 如果当前添加这个左邻居得到的sum比之前添加的右邻居的sum要小, 那就把之前添加的poll出来, 改为现在添加的. 如果比之前大, 那现在就没必要添加了. 这样每个位置只会添加一次.
时间复杂度: O(n ^ 2) 因为把triangle每一个位置都遍历了.
空间复杂度: O(n) 每次只是装着一层, 然后添加下一层. 最多也就是n.
1 2 3 4 5 6 7 8 9 10 11 12
| class Solution { public int minimumTotal(List<List<Integer>> triangle) { for (int i = triangle.size() - 2; i >= 0; i--) { List<Integer> currRow = triangle.get(i); List<Integer> nextRow = triangle.get(i + 1); for (int j = 0; j < currRow.size(); j++) { currRow.set(j, Math.min(nextRow.get(j), nextRow.get(j + 1)) + currRow.get(j)); } } return triangle.get(0).get(0); } }
|
从底部到上往上爬. 看哪个路到顶部最小.
时间复杂度: O(n^2) 因为要遍历每个位置.
空间复杂度: O(1)