动态规划学习专题3

//字串 只能是去掉某些字符,不能改变某些字符

 

 

 

 

 

 

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

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值