算法
1. 汉诺塔问题
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class Hanoi { public static void main(String[] args) { hanoi(2, 'A', 'B', 'C'); } public static void hanoi(int n, char a, char b, char c){ if(n == 1) move(1, a, c); else{ hanoi(n-1, a, c, b); // a->b move(1, a, c); // a->c hanoi(n-1, b, a, c); // b->c } } public static void move(int n, char src, char dst){ System.out.println("move sheet from " + src + " to " + dst); } }
2.1 N皇后问题(递归方式)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import java.util.Arrays; public class Queen { private static int[] queens; private final static int N = 8; private static int sum; // the count of solutions public static void main(String[] args) { queens = new int[N + 1]; queen(1, N); } public static void queen(int k, int n) { if (k > n) { sum++; printResult(); return; } for (int i = 1; i <= n; i++) { queens[k] = i; if (place(k)) queen(k + 1, n); } } public static boolean place(int k) { for (int i = 1; i < k; i++) { int delta = Math.abs(queens[k] - queens[i]); if (delta == 0 || delta == k - i) return false; } return true; } public static void printResult() { System.out.println(sum + ": " + Arrays.toString(Arrays.copyOfRange(queens, 1, queens.length))); } }
2.2 N皇后问题(回溯方式)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import java.util.Arrays; public class Queen { private static int[] queens; private static int sum; private final static int N = 8; public static void main(String[] args) { queens = new int[N + 1]; queen(N); } public static void queen(int n) { int k = 1; while (k >= 1) { queens[k]++; while (queens[k] <= n && !place(k)) // find available place for queen k queens[k]++; if (k == n && queens[k] <= n) { sum++; printResult(); } else if (k < n && queens[k] <= n) { k++; // process the next queen } else { queens[k] = 0; k--; // back to last queen } } } public static boolean place(int k) { for (int i = 1; i < k; i++) { int delta = Math.abs(queens[k] - queens[i]); if (delta == 0 || delta == k - i) return false; } return true; } public static void printResult() { System.out.println(sum + ": " + Arrays.toString(Arrays.copyOfRange(queens, 1, queens.length))); } }
3. 求轮廓
输入每个矩形坐标[Li, Ri, Hi]: [ [2 9 10], [3 7 15], [5 12 12], [15 20 10], [19 24 8] ]
输出轮廓转折点[x1,y1]:[ [2 10], [3 15], [7 12], [12 0], [15 10], [20 8], [24, 0] ]
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class Solution { public List<int[]> getSkyline(int[][] buildings) { List<int[]> result = new ArrayList<>(); List<int[]> height = new ArrayList<>(); for(int[] b:buildings) { height.add(new int[]{b[0], -b[2]}); height.add(new int[]{b[1], b[2]}); } // 起点高度标识为负数,在后面的处理中可以区分起点和终点 Collections.sort(height, (a, b) -> { if(a[0] != b[0]) return a[0] - b[0]; return a[1] - b[1]; }); // 数组元素排序 Queue<Integer> pq = new PriorityQueue<>((a, b) -> (b - a)); // 此队列表示高度的作用域 pq.offer(0); int prev = 0; for(int[] h:height) { if(h[1] < 0) { // 若为起点,则此高度加入队列 pq.offer(-h[1]); } else { // 若为终点,则将高度从此队列(作用域)中删除 pq.remove(h[1]); } int cur = pq.peek();// 取当前所有高度范围内的最大值 if(prev != cur) { result.add(new int[]{h[0], cur}); prev = cur; // 保留上一个高度 } } return result; } }
4. 求最大正方形面积
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public int maximalSquare(char[][] a) { if(a.length == 0) return 0; int m = a.length, n = a[0].length, result = 0; int[][] b = new int[m+1][n+1]; for (int i = 1 ; i <= m; i++) { for (int j = 1; j <= n; j++) { if(a[i-1][j-1] == '1') { b[i][j] = Math.min(Math.min(b[i][j-1] , b[i-1][j-1]), b[i-1][j]) + 1; // 取附近3个点的最小边长 result = Math.max(b[i][j], result); // update result } } } return result*result; }