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]