zoukankan      html  css  js  c++  java
  • LeetCode OJ-- Distinct Subsequences ** 递推

    https://oj.leetcode.com/problems/distinct-subsequences/

    对于string S 和 T求,T 是 S的几种子串。

    首先想到了递归方法,列出递归公式,奈何超时了:

    如果S[sBegin] == T[tBegin] 则是 numSubDistinct(sBegin+1,tBegin+1,S,T) + numSubDistinct(sBegin+1,tBegin,S,T);
    如果不等于,则 numSubDistinct(sBegin+1,tBegin,S,T);
    如果T的遍历指针到头了,则说明成功了一次匹配

    class Solution {
    public:
        int numDistinct(string S, string T) {
            int ans = 0;
            if(S.size()<T.size())
                return 0;
            if(S.size() == T.size())
                if(S == T)
                    return 1;
                else
                    return 0;
            return numSubDistinct(0,0,S,T);
        }
        int numSubDistinct(int sBegin,int tBegin,string &S,string &T)
        {
            if(tBegin== T.size())
                return 1;
            if(sBegin == S.size() && tBegin!= T.size())
                return 0;
            if(S[sBegin] == T[tBegin])
                return numSubDistinct(sBegin+1,tBegin+1,S,T) + numSubDistinct(sBegin+1,tBegin,S,T);
            else
                return numSubDistinct(sBegin+1,tBegin,S,T);
        }
    };

    之后,考虑用递推实现。

    根据思路来说,首先想到从后往前递推,但如果从后往前可以,则从前往后也可以。

    建立二维数组num[S.size()][T.size()]存这个过程中产生的中间结果。

    首先定义:num[i][j]是对于S从0到 i 的子串,对于T从 0 到 j 的子串,这两个字符串,T是S的子串数。

    如果S[sBegin] == T[tBegin] num[sBegin][tBegin] = num[sBegin-1][tBegin-1] + num[sBegin-1][tBegin];

    如果不等于则 num[sBegin][tBegin] = num[sBegin-1][tBegin];

    根据公式,考虑到进行两层循环,
    但是循环之前需要初始化

    class Solution {
    public:
        int numDistinct(string S, string T) {
            int ans = 0;
            if(S.size()<T.size())
                return 0;
            if(S.size() == T.size())
                if(S == T)
                    return 1;
                else
                    return 0;
    
            vector<vector<int> > num;
            num.resize(S.size());
            for(int i = 0;i<S.size();i++)
                num[i].resize(T.size());
    
            //initialize
            if(S[0] == T[0])
                num[0][0] = 1;
            else
                num[0][0] = 0;
            for(int i = 1;i<S.size();i++)
            {
                if(S[i] == T[0])
                    num[i][0] = num[i-1][0] + 1;
                else
                    num[i][0] = num[i-1][0];
            }
    
            for(int j = 1;j<T.size();j++)
            {
                num[0][j] = 0;
            }
    
            for(int sBegin = 1;sBegin<S.size();sBegin++)
                for(int tBegin = 1;tBegin<T.size();tBegin++)
                {
                    if(S[sBegin] == T[tBegin])
                        num[sBegin][tBegin] = num[sBegin-1][tBegin-1] + num[sBegin-1][tBegin];
                    else
                        num[sBegin][tBegin] = num[sBegin-1][tBegin];
                }
            
            return num[S.size()-1][T.size()-1];
        }
    };
  • 相关阅读:
    LinkedList源码解析
    四种List实现类的对比总结
    HashMap源码解析
    Flutter——Switch组件(开关组件)
    Flutter——Radio组件、RadioListTile组件(单选按钮组件)
    Flutter——Checkbox组件、CheckboxListTile(多选框组件)
    Flutter——TextField组件(文本框组件)
    Flutter——FloatingActionButton组件(浮动按钮组件)
    Flutter中的按钮组件介绍
    Flutter——Drawer、DrawerHeader、UserAccountsDrawerHeader组件(侧边栏组件)
  • 原文地址:https://www.cnblogs.com/qingcheng/p/3817175.html
Copyright © 2011-2022 走看看