public class DungenonGame {
public static int needMin(int[][] matrix) {
return process(matrix, matrix.length, matrix[0].length, 0, 0);
}
public static int process(int[][] matrix, int N, int M, int row, int col) {
if (row == N - 1 && col == M - 1) {
return matrix[N - 1][M - 1] < 0 ? (-matrix[N - 1][M - 1] + 1) : 1;
}
if (row == N - 1) {
int rightNeed = process(matrix, N, M, row, col + 1);
if (matrix[row][col] < 0) {
return -matrix[row][col] + rightNeed;
} else if (matrix[row][col] > rightNeed) {
return 1;
} else {
return rightNeed - matrix[row][col];
}
}
if (col == M - 1) {
int downNeed = process(matrix, N, M, row + 1, col);
if (matrix[row][col] < 0) {
return -matrix[row][col] + downNeed;
} else if (matrix[row][col] > downNeed) {
return 1;
} else {
return downNeed - matrix[row][col];
}
}
int minNextNeed = Math.min(process(matrix, N, M, row, col + 1), process(matrix, N, M, row + 1, col));
if (matrix[row][col] < 0) {
return -matrix[row][col] + minNextNeed;
} else if (matrix[row][col] > minNextNeed) {
return 1;
} else {
return minNextNeed - matrix[row][col];
}
}
}
public class CherryPickup {
public static int comeGoMaxPathSum(int[][] matrix){
return process(matrix,0,0,0);
}
//A和B同时走 A往下右 B往右下走
//A的位置Ar Ac
//B的位置Br Ar+Ac-Br
//A和B迈出的步子一样多 所以
//如果A和B到同一个格子,只计算一次
public static int process(int[][] matrix,int Ar,int Ac,int Br){
int N = matrix.length;
int M =matrix[0].length;
//到了右下角
if(Ar == matrix.length -1 && Ac == matrix[0].length){
return matrix[Ar][Ac];
}
int Bc = Ar+Ac-Br;
//还没到右下角 四种情况
//A下 B右
//A下 B下
//A右 B右
//A右 B下
int ADownRight = -1;
if(Ar + 1 < N && Br + 1 < M){
ADownRight = process(matrix,Ar+1,Ac,Br);
}
int ADownBDown = -1;
if(Ar + 1 < N && Br+1<N){
ADownBDown = process(matrix,Ar+1,Ac,Br+1);
}
int ArightBright = -1;
if(Ac + 1 < M && Bc + 1 < M){
ADownRight = process(matrix,Ar,Ac+1,Br);
}
int ARightBDown = -1;
if(Ac + 1 < M && Br+1<N){
ARightBDown = process(matrix,Ar,Ar+1,Br+1);
}
int nextBest = Math.max(Math.max(ADownRight,ADownBDown),Math.max(ArightBright,ARightBDown));
if(Ar == Br){//A和B走到同一个位置 计算一次
return matrix[Ar][Ac] + nextBest;
}
//A和B互不相交的位置
return matrix[Ar][Ac] + matrix[Br][Bc] + nextBest;
}
}
利用桶
空桶 两侧相减 一定大于一个桶区间,准备空桶为了杀死比平凡解的内平凡解,就是一个桶内的解
public class MaxGap {
public static int maxGap(int[] nums){
if(nums == null || nums.length < 2){
return 0;
}
int len = nums.length;
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int i = 0; i < len; i++) {
min = Math.min(min,nums[i]);
max = Math.max(max,nums[i]);
}
if(min == max){
return 0;
}
//i号桶是否进来数字
boolean[] hasNum = new boolean[len+1];
//i号桶的最大值是什么
int[] maxs = new int[len+1];
//i号桶的最小值是什么
int[] mins = new int[len+1];
int bid = 0;//桶号
for (int i = 0; i < len; i++) {
//当前桶应该进的桶号
bid = bucket(nums[i],len,min,max);
mins[bid] = hasNum[bid] ? Math.min(mins[bid],nums[i]):nums[i];
maxs[bid] = hasNum[bid] ? Math.max(maxs[bid],nums[i]):nums[i];
hasNum[bid] = true;
}
int res = 0;
int lastMax = maxs[0];
int i = 1;//i从1开始
for(;i <= len;i++){
if(hasNum[i]){
res = Math.max(res,mins[i]-lastMax);
lastMax = maxs[i];
}
}
return res;
}
public static int bucket(long num,long len,long min,long max){
return (int)((num-min)*len/(max-min));
}
}
利用前缀树
import java.util.HashSet;
public class WorldBreak {
public static int ways(String str,String[] arr){
HashSet<String> set = new HashSet<>();
for(String candidate : arr){
set.add(candidate);
}
process(str,0,set);
}
public static int process(String str,int i,HashSet<String> set){
if(i == str.length()){
return 1;
}
int ways = 0;
for(int end = i;end < str.length();end++){
String pre = str.substring(i,end+1);
if(set.contains(pre)){
ways += process(str,end+1,set);
}
}
return ways;
}
public static int way3(String str,String[] arr){
if(str == null || str.length() == 0){
return 0;
}
Node root = new Node();
for(String s:arr){
char[] chs = s.toCharArray();
Node node = root;
int index = 0;
for (int i = 0; i < chs.length; i++) {
index = chs[i] = 'a';
if(node.nexts[index] == null){
node.nexts[index] = new Node();
}
node = node.nexts[index];
}
node.end = true;
}
return g(str.toCharArray(),root,0);
}
public static int g(char[] str,Node root,int i){
if(i == str.length){
return 1;
}
int ways = 0;
Node cur = root;
for(int end = i;end < str.length;end++){
int path = str[end] - 'a';
if(cur.nexts[path] == null){
break;
}
cur = cur.nexts[path];
if(cur.end){
ways += g(str,root,end+1);
}
}
return ways;
}
}