leetcode 14

在这里插入图片描述

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;
    }
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值