最大半径问题 - James Pan - 博客频道 - CSDN.NET
一个长度为n的数组,从中选取k个数字,若定义这k个数字的半径为排序后相邻两个数字之间的最小间隔,则k个数字所能达到的最大半径是多少?
如果k = 1,则半径为无穷大。
Read full article from 最大半径问题 - James Pan - 博客频道 - CSDN.NET
一个长度为n的数组,从中选取k个数字,若定义这k个数字的半径为排序后相邻两个数字之间的最小间隔,则k个数字所能达到的最大半径是多少?
如果k = 1,则半径为无穷大。
假设k > 0。
方法一:深度优先搜索。
class SolutionDFS { private int max = 0; public SolutionDFS(int[] nums, int k) { find(nums, 0, 0, k, 0); } private void find(int[] nums, int from, int step, int k, int min) { if (step == k) { max = Math.max(max, min); } else if (step == 0) { find(nums, 1, step + 1, k, Integer.MAX_VALUE); } else if (step == k - 1) { find(nums, nums.length, step + 1, k, Math.min(min, nums[nums.length - 1] - nums[from - 1])); } else if (min > max) { for(int i = from; i + (k - step) <= nums.length; i++) { find(nums, i + 1, step + 1, k, Math.min(min, nums[i] - nums[from - 1])); } } } public int getSolution() { return max; } }
方法二:递归+记忆化搜索。
class SolutionRecursive { private boolean[][] visit; private int[][] dp; private int[] nums; public SolutionRecursive(int[] nums, int k) { int n = nums.length; this.visit = new boolean[n + 1][k + 1]; this.dp = new int[n + 1][k + 1]; this.nums = nums; dp(n, k); } public int getSolution() { int n = dp.length - 1; int k = dp[n].length - 1; return dp[n][k]; } private int dp(int n, int k) { if (visit[n][k]) return dp[n][k]; visit[n][k] = true; if (n < k || k == 0) { dp[n][k] = 0; return dp[n][k]; } if (k == 1) { dp[n][k] = Integer.MAX_VALUE; return dp[n][k]; } int result = dp(n - 1, k); for(int i = k - 1; i < n; i++) { result = Math.max(result, Math.min(dp(i, k - 1), nums[n - 1] - nums[i - 1])); } dp[n][k] = result; return result; } }
方法三:递推+动态规划。
class SolutionIterative { private int solution; public SolutionIterative(int[] nums, int k) { int[][] radius = new int[nums.length + 1][k + 1]; for(int i = 1; i <= nums.length; i++) { radius[i][1] = Integer.MAX_VALUE; for(int j = 2; j <= k; j++) { radius[i][j] = radius[i - 1][j]; for(int m = j - 1; m < i; m++) { radius[i][j] = Math.max(radius[i][j], Math.min(radius[m][j - 1], nums[i - 1] - nums[m - 1])); } } } solution = radius[nums.length][k]; } public int getSolution() { return this.solution; } }