//字串 只能是去掉某些字符,不能改变某些字符
public int longestCommonSubsequence(String A, String B) {
// write your code here
int m =A.length();
int n =B.length();
if (m==0||n==0) return 0;
char[] s1 =A.toCharArray();
char[] s2 =B.toCharArray();
//f[i][j] 表示 A的 第i个 和b的第j个最多匹配多少
int[][] f = new int[m+1][n+1];
for (int i = 0; i <m+1 ; i++) {
for (int j = 0; j <n+1 ; j++) {
if (i==0||j==0){
f[i][j]=0;
continue;
}
f[i][j] =Math.max(f[i-1][j],f[i][j-1]);
if (s1[i-1]==s2[j-1]){
f[i][j] =Math.max(f[i][j],f[i-1][j-1]+1);
}
}
}
return f[m][n];
}
//将最长子序列打印输出
public static void main(String[] args) {
longestCommonSubsequence("jiuzhang","lijiang");
}
public static int longestCommonSubsequence(String A, String B) {
// write your code here
int m =A.length();
int n =B.length();
if (m==0||n==0) return 0;
char[] s1 =A.toCharArray();
char[] s2 =B.toCharArray();
//f[i][j] 表示 A的 第i个 和b的第j个最多匹配多少
int[][] f = new int[m+1][n+1];
int[][] pai = new int[m+1][n+1];
for (int i = 0; i <m+1 ; i++) {
for (int j = 0; j <n+1 ; j++) {
if (i==0||j==0){
f[i][j]=0;
continue;
}
f[i][j] =Math.max(f[i-1][j],f[i][j-1]);
if (f[i][j]==f[i-1][j]){
pai[i][j]=1;
}else if (f[i][j]==f[i][j-1]){
pai[i][j] =2;
}
if (j>0&&s1[i-1]==s2[j-1]){
f[i][j] =Math.max(f[i][j],f[i-1][j-1]+1);
if (f[i][j]==f[i-1][j-1]+1){
pai[i][j]=3;
}
}
}
}
// recover f[m][n]-> f[0][0]
char[] res =new char[f[m][n]];
int p =f[m][n] -1;
int i = m;
int j = n;
while (i>0&&j>0){
if (pai[i][j]==1){
--i;
}else if (pai[i][j]==2){
--j;
}else {
res[p--] = s1[i-1];
--i;
--j;
}
}
for (p = 0; p <f[m][n] ; p++) {
System.out.print(res[p]);
}
return f[m][n];
}
public boolean isInterleave(String ss1, String ss2, String ss3) {
// write your code here
char[] s1 =ss1.toCharArray();
char[] s2 =ss2.toCharArray();
char[] s3 =ss3.toCharArray();
int m = s1.length;
int n = s2.length;
if (s3.length!=m+n) return false;
boolean[][] f = new boolean[m+1][n+1];
for (int i = 0; i <m+1 ; i++) {
for (int j = 0; j <n+1 ; j++) {
if (i==0&&j==0) {
f[i][j]=true;
continue;
}
f[i][j] =false;
if (i>0&&s3[i+j-1]==s1[i-1]){
f[i][j]|=f[i-1][j];
}
if (j>0&&s3[i+j-1]==s2[j-1]){
f[i][j]|= f[i][j-1];
}
}
}
return f[m][n];
}
public int minDistance(String word1, String word2) {
// write your code here
char[] s1 = word1.toCharArray();
char[] s2 = word2.toCharArray();
int m = s1.length;
int n = s2.length;
int[][] f = new int[m+1][n+1];
for (int i = 0; i <m+1 ; i++) {
for (int j = 0; j <n+1 ; j++) {
if (i==0) {
f[i][j] = j;
continue;
}
if (j==0){
f[i][j] = i;
continue;
}
// delete add
f[i][j] = Math.min(f[i-1][j]+1,f[i][j-1]+1);
f[i][j] = Math.min(f[i][j],f[i-1][j-1]+1);//replace
if (s1[i-1]==s2[j-1]){
f[i][j] = Math.min(f[i][j],f[i-1][j-1]); //same
}
}
}
return f[m][n];
}
public int numDistinct(String S, String T) {
// write your code here
char[] s1 = S.toCharArray();
char[] s2 = T.toCharArray();
int m =s1.length;
int n =s2.length;
int[][] f =new int[m+1][n+1];
for (int i = 0; i <=m ; i++) {
for (int j = 0; j <=n ; j++) {
if (j==0){
f[i][j] = 1;
continue;
}
if (i==0){
f[i][j] =0;
continue;
}
f[i][j] = f[i-1][j];
if (s2[j-1]==s1[i-1]){
f[i][j]+= f[i-1][j-1];
}
}
}
return f[m][n];
}
public boolean isMatch(String ss, String pp) {
// write your code here
char[] s1 = ss.toCharArray();
char[] s2 = pp.toCharArray();
int m = s1.length;
int n = s2.length;
boolean[][] f = new boolean[m+1][n+1];
for (int i = 0; i <m+1 ; i++) {
for (int j = 1; j <n+1 ; j++) {
f[i][j]=false;
f[0][0] =true;
if (s2[j-1]!='*'){
if (i>0&&(s1[i-1]==s2[j-1]||s2[j-1]=='.')){
f[i][j] =f[i-1][j-1];
}
}else {
if (j>=2) f[i][j] |=f[i][j-2];
if (i>=1&&j>=2){
f[i][j] |=f[i-1][j]&&(s2[j-2]=='.'||s2[j-2]==s1[i-1]);
}
}
}
}
return f[m][n];
}
public boolean isMatch(String ss1, String ss2) {
// write your code here
char[] s1 =ss1.toCharArray();
char[] s2 = ss2.toCharArray();
int m = s1.length;
int n = s2.length;
boolean f[][] = new boolean[m+1][n+1];
f[0][0] = true;
for (int i = 0; i <m+1 ; i++) {
for (int j = 1; j <n+1 ; j++) {
if (i>0&&(s2[j-1]=='?'||s2[j-1]==s1[i-1])){
f[i][j] =f[i-1][j-1];
}
if (s2[j-1]=='*'){
f[i][j] = f[i][j-1]; // 先不选
if(i>0) f[i][j] |= f[i-1][j];
}
}
}
return f[m][n];
}
public int findMaxForm(String[] strs, int m, int n) {
// write your code here
int len =strs.length;
int[] cnt0 = new int[len];
int[] cnt1 = new int[len];
for (int i = 0; i <len ; i++) {
cnt0[i]=cnt1[i]=0;
char[] s = strs[i].toCharArray();
for (int j = 0; j <s.length ; j++) {
if (s[j]=='0'){
++cnt0[i];
}else{
++cnt1[i];
}
}
}
int[][][] f =new int[len+1][m+1][n+1];
for (int i = 0; i <=m ; i++) {
for (int j = 0; j <=n ; j++) {
f[0][i][j] = 0;
}
}
for (int i = 1; i <=len ; i++) {
for (int j = 0; j <=m ; j++) {
for (int k = 0; k <=n ; k++) {
f[i][j][k] = f[i-1][j][k];
if (j>=cnt0[i-1]&&k>=cnt1[i-1]){
f[i][j][k] = Math.max(f[i][j][k],
f[i-1][j-cnt0[i-1]][k-cnt1[i-1]]+1);
}
}
}
}
return f[len][m][n];
}
public int findMaxForm(String[] strs, int m, int n) {
// write your code here
int len =strs.length;
int[] cnt0 = new int[len];
int[] cnt1 = new int[len];
for (int i = 0; i <len ; i++) {
cnt0[i]=cnt1[i]=0;
char[] s = strs[i].toCharArray();
for (int j = 0; j <s.length ; j++) {
if (s[j]=='0'){
++cnt0[i];
}else{
++cnt1[i];
}
}
}
int[][][] f =new int[2][m+1][n+1];
int old,now =0;
for (int i = 0; i <=m ; i++) {
for (int j = 0; j <=n ; j++) {
f[now][i][j] = 0;
}
}
for (int i = 1; i <=len ; i++) {
old=now;
now=1-now;
for (int j = 0; j <=m ; j++) {
for (int k = 0; k <=n ; k++) {
f[now][j][k] = f[old][j][k];
if (j>=cnt0[i-1]&&k>=cnt1[i-1]){
f[now][j][k] = Math.max(f[now][j][k],
f[old][j-cnt0[i-1]][k-cnt1[i-1]]+1);
}
}
}
}
return f[now][m][n];
}
public int MinAdjustmentCost(List<Integer> A, int target) {
// write your code here
int n = A.size();
int[][] f =new int[n+1][101];
//init
for (int i = 1; i <=100 ; i++) {
f[1][i] = Math.abs(A.get(0)-i);
}
int res = Integer.MAX_VALUE;
for (int i = 2; i <=n ; i++) {
for (int j = 1; j <=100 ; j++) {
f[i][j] = Integer.MAX_VALUE;
for (int k = j-target; k <=j+target ; k++) {
if (k<1||k>100){
continue;
}
f[i][j] = Math.min(f[i][j],f[i-1][k]+
Math.abs(A.get(i - 1) -j)); //调整代价
if (i==n){
res=Math.min(res,f[i][j]);
}
}
}
}
return res;
}
public int kSum(int[] A, int k, int target) {
// write your code here
int n = A.length;
int[][][] f = new int[n+1][k+1][target+1];
f[0][0][0]=1;
for (int i = 1; i <=n ; i++) {
for (int j = 0; j <=k ; j++) {
for (int l = 0; l <=target ; l++) {
f[i][j][l] = f[i-1][j][l];
if (j>0&&l-A[i-1]>=0){
f[i][j][l] = f[i][j][l] +
f[i-1][j-1][l-A[i-1]];
}
}
}
}
return f[n][k][target];
}
滚动数组 版本
public int longestIncreasingSubsequence(int[] A) {
// write your code here
int n = A.length;
if (n==0) return 0;
int[] b = new int[n+1]; // 当f的只是i,最小的结尾值
int top =0; //最长子序列的长度
b[0] = Integer.MIN_VALUE;
for (int i = 0; i <n ; i++) {
int start = 0;
int stop =top;
int j=0 ; //最后一个小于它的结尾值
while (start<=stop){
int mid =(start+stop)>>1;
if (b[mid]<A[i]){
j=mid;
start = mid+1;
}
else {
stop=mid-1;
}
}
b[j+1] =A[i]; //f[i] =j+1;
if (j+1>top){
top=j+1;
}
}
return top;
}
static class TireNode{
TireNode[] sons;
boolean hasword;
String word;
public TireNode(){
sons =new TireNode[26];// a=0
for (int i = 0; i <26 ; i++) {
sons[i] = null;
}
hasword =false;
}
public static void insert(TireNode root,String wordStr){
char[] word = wordStr.toCharArray();
TireNode p =root;
for (int i = 0; i <word.length ; i++) {
int c = word[i] -'a';
if (p.sons[c]==null){
p.sons[c] = new TireNode();
}
p=p.sons[c];
}
p.hasword = true;
p.word = wordStr;
}
}
char[] target =null;
int K=0;
int[] f =null;
int n=0;
List<String> res =null;
private void dfs(TireNode p,int[] f){
int[] nf =new int[n+1];
if (p.hasword){
if (f[n]<=K){
res.add(p.word);
}
}
for (int i = 0; i <26 ; i++) {
if (p.sons[i]==null){
continue;
}
nf[0] = f[0]+1;
for (int j = 1; j <=n ; j++) {
nf[j] = Math.min(Math.min(nf[j-1]+1,f[j]+1),f[j-1]+1);
int c= target[j-1]-'a';
if (c==i){
nf[j] =Math.min(nf[j],f[j-1]);
}
}
dfs(p.sons[i],nf);
}
}
public List<String> kDistance(String[] words, String targetStr, int k) {
// write your code here
target =targetStr.toCharArray();
n = target.length;
K = k;
res = new ArrayList<String>();
//1 init tire
TireNode root = new TireNode();
for (int i = 0; i <words.length ; i++) {
TireNode.insert(root,words[i]);
}
//init f
f =new int[n+1];
for (int i = 0; i <=n ; i++) {
f[i]=i;
}
// dfs
dfs(root,f);
return res;
}
public boolean canCross(int[] A) {
// write your code here
int n =A.length;
HashMap<Integer,HashSet<Integer>> f = new HashMap<>();
for (int i = 0; i <n ; i++) {
f.put(A[i],new HashSet<>());
}
f.get(A[0]).add(0);
for (int i = 0; i <n ; i++) {
HashSet<Integer> tmp = new HashSet<>(f.get(A[i]));
for (int k :tmp) {
for (int delta = -1; delta <=1 ; delta++) {
int t =A[i] + (k+delta);
if (f.containsKey(t)){
f.get(t).add(k+delta);
}
}
}
}
return !f.get(A[n-1]).isEmpty();
}
public int maxSquare(int[][] matrix) {
// write your code here
if (matrix==null||matrix.length==0||matrix[0].length==0){
return 0;
}
int m = matrix.length;
int n = matrix[0].length;
int[][] f = new int[m][n];
int res= 0;
for (int i = 0; i <m ; i++) {
for (int j = 0; j <n ; j++) {
if (matrix[i][j] == 0){
f[i][j] = 0;
continue;
}
//A[i][j] = 1
if (i==0||j==0){
f[i][j] =1;
res = Math.max(1,res);
continue;
}
f[i][j] = Math.min(Math.min(f[i-1][j],f[i-1][j-1]),f[i][j-1])+1;
res = Math.max(f[i][j]*f[i][j],res);
}
}
return res;
}