leetcode 13

在这里插入图片描述
i位置 小于等于k的 离k最近的累加和,其中最近的就是我要的答案
利用前缀和转换 所有前缀和加到有序表
如果单调性 并且都是正数可以窗口,但是这里面有正有负

import java.util.TreeSet;

public class MaxSubArraySumLessOrEqualk {
    public static int getMaxLessOrEqualk(int[] arr,int k){
        //记录i之前的缀和
        TreeSet<Integer> set = new TreeSet<>();
        //一个数也没有 一个数就是前缀和
        set.add(0);

        int max = Integer.MIN_VALUE;
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum+=arr[i];
            //原来求的问题是有没有小于等于k的子数组
            //现在的累加和是sum 转换为有没有sum减去当前位置钱买你的前缀和>=k的
            //ceiling 天花板 返回>= sum-k的最小元素
            if(set.ceiling(sum - k) != null){
                max = Math.max(max,sum-set.ceiling(sum-k));
            }
            set.add(sum);
        }
        return max;
    }
}

在这里插入图片描述
数组压缩技巧

略 没啥说的。。。

在这里插入图片描述

public class LongestIncreasingPath {
    public static int maxPath(int[][] matrix){
        int ans = Integer.MIN_VALUE;
        for(int row = 0;row < matrix.length;row++){
            for(int col = 0;col < matrix[0].length;col++){
                ans = Math.max(ans,process(matrix,row,col));
            }
        }
       return ans;
    }

    public static int process(int[][] matrix,int i,int j){
        if(i < 0 || i >= matrix.length || j < 0 || j>=matrix[0].length){
            return -1;
        }

        int next1 = 0;
        int next2 = 0;
        int next3 = 0;
        int next4 = 0;
        if(i - 1 >= 0 && matrix[i-1][j] > matrix[i][j]){
            next1 = process(matrix,i-1,j);
        }
        if(j-1 >= 0 && matrix[i][j-1] > matrix[i][j]){
            next2 = process(matrix,i,j-1);
        }
        if(j+1<matrix[0].length && matrix[i][j+1] > matrix[i][j]){
            next3 = process(matrix,i,j+1);
        }
        if(i+1 < matrix[0].length && matrix[i+1][j] > matrix[i][j]){
            next4 = process(matrix,i+1,j);
        }
        return 1+Math.max(Math.max(next1,next2),Math.max(next3,next4));
    }
    public static int process1(int[][] matrix,int i,int j,int[][] dp) {
        if (i < 0 || i >= matrix.length || j < 0 || j >= matrix[0].length) {
            return -1;
        }
        if(dp[i][j] !=0){
            return dp[i][j];
        }

        int next1 = 0;
        int next2 = 0;
        int next3 = 0;
        int next4 = 0;
        if (i - 1 >= 0 && matrix[i - 1][j] > matrix[i][j]) {
            next1 = process(matrix, i - 1, j);
        }
        if (j - 1 >= 0 && matrix[i][j - 1] > matrix[i][j]) {
            next2 = process(matrix, i, j - 1);
        }
        if (j + 1 < matrix[0].length && matrix[i][j + 1] > matrix[i][j]) {
            next3 = process(matrix, i, j + 1);
        }
        if (i + 1 < matrix[0].length && matrix[i + 1][j] > matrix[i][j]) {
            next4 = process(matrix, i + 1, j);
        }
        dp[i][j] = 1 + Math.max(Math.max(next1, next2), Math.max(next3, next4));
        return dp[i][j];
    }
}

在这里插入图片描述
f(i,j)不能重复走 深度优先遍历,可以找到一些word并且打上标签不再回头
字母表words建立前缀树

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;

public class WordSearch {
   public static class TrieNdoe {
       public TrieNdoe[] nexts;
       public int pass;//该节点需要经过几次才算结束
       public int end;//如果end>0表示以该节点结束,如果==0说明以该节点结束

       public TrieNdoe() {
           nexts = new TrieNdoe[26];
           pass = 0;
           end = 0;
       }
   }

   public static void fillWord(TrieNdoe head, String word) {
       head.pass++;
       char[] chs = word.toCharArray();
       int index = 0;
       TrieNdoe node = head;
       for (int i = 0; i < chs.length; i++) {
           index = chs[i] - 'a';
           if (node.nexts[index] == null) {
               node.nexts[index] = new TrieNdoe();
           }
           node = node.nexts[index];
           node.pass++;
       }
       node.end++;
   }

   //从前缀树 收集答案
   public static String generatePath(LinkedList<Character> path) {
       char[] str = new char[path.size()];
       int index = 0;
       for (Character cha : path) {
           str[index++] = cha;
       }
       return String.valueOf(str);
   }

   public static List<String> findWords(char[][] board, String[] words) {
       TrieNdoe head = new TrieNdoe();
       HashSet<String> set = new HashSet<>();
       for (String word : words) {
           if (!set.contains(word)) {
               fillWord(head, word);
               set.add(word);
           }
       }
       //收集答案
       List<String> ans = new ArrayList<>();
       //走过的路径
       LinkedList<Character> path = new LinkedList<>();
       for (int row = 0; row < board.length; row++) {
           for (int col = 0; col < board[0].length; col++) {
               process(board, row, col, path, head, ans);
           }
       }
       return ans;
   }
   public static int process(
           char[][] board,int row,int col,
           LinkedList<Character> path,
           TrieNdoe cur,
           List<String> res
   ){
       char cha = board[row][col];
       if(cha == 0){
           return 0;
       }
       int index = cha - 'a';

       //如果没有路了 或者 这个节点下面已经没有必要走了
       if(cur.nexts[index] == null || cur.nexts[index].pass == 0){
           return 0;
       }

       cur = cur.nexts[index];
       path.addLast(cha);
       int fix = 0;//从row和col位置出发,后续一共搞定多少答案
       if(cur.end > 0){
           res.add(generatePath(path));
           cur.end--;
           fix++;
       }

       board[row][col] = 0;
       if(row >0){
           fix += process(board,row-1,col,path,cur,res);
       }
       if(row < board.length-1){
           fix += process(board,row+1,col,path,cur,res);
       }
       if(col >0 ){
           fix +=process(board,row,col-1,path,cur,res);
       }
       if(col <board[0].length-1){
           fix += process(board,row,col+1,path,cur,res);
       }
       board[row][col] = cha;//设置是否访问过 避免重复访问
       path.pollLast();//深度遍历完恢复状态,将加入路径的节点取出来
       cur.pass -= fix;//深度恢复状态
       return fix;

}

}

在这里插入图片描述

dp[i][j]表示字符串1从0到i到字符串2从0到j有几种方法
1.不用i位置 dp[i][j] = dp[i-1][j]
2.用i位置 s1[i]=s2[j]的情况才可以 dp[i][j] = dp[i-1][j-1]


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值