Surrounded Regions & Wildcard Matching

(1) Surrounded Regions 

首先,外围一圈上的O肯定会保留下来。
然后,从外围的O能达到的O也要保留。剩下其他的O就是内部的O。所以方法就是从外围的一圈进行DFS算法。
特殊用例:只有外围轮廓没有内部。比如长或者宽小于等于2,此时不存在被包围的'X'。[1]

class Solution {
private:
    void dfs(vector<vector<char>> &board ,int i,int j, int m, int n) {
        if(i>1 && board[i-1][j]=='O')
        {
            board[i-1][j]='*';
            dfs(board,i-1,j,m,n);
        }
        if(i<m-1 && board[i+1][j]=='O')
        {
            board[i+1][j]='*';
            dfs(board,i+1,j,m,n);
        }
        if(j>1 && board[i][j-1]=='O')
        {
            board[i][j-1]='*';
            dfs(board,i,j-1,m,n);
        }
        if(j<n-1 && board[i][j+1]=='O')
        {
            board[i][j+1]='*';
            dfs(board,i,j+1,m,n);
        }
    }

public:
    void solve(vector<vector<char>> &board) {
        int m=board.size();
        if(m<=2)
            return;
        int n=board[0].size();
        if(n<=2)
            return;
            
        for(int i=0;i<n;i++)
        {
            if(board[0][i]=='O')
            {
                board[0][i]='*';
                dfs(board,0,i,m,n);
            }
        }
        for(int i=0;i<n;i++)
        {
            if(board[m-1][i]=='O')
            {
                board[m-1][i]='*';
                dfs(board,m-1,i,m,n);
            }
        }
        for(int i=1;i<m-1;i++)
        {
            if(board[i][0]=='O')
            {
                board[i][0]='*';
                dfs(board,i,0,m,n);
            }
        }
        for(int i=1;i<m-1;i++)
        {
            if(board[i][n-1]=='O')
            {
                board[i][n-1]='*';
                dfs(board,i,n-1,m,n);
            }
        }
        
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++)
            {
                if(board[i][j]=='O')
                    board[i][j]='X';
                if(board[i][j]=='*')
                    board[i][j]='O';
            }
    }
};

(2) Wildcard Matching

二维动态规划,因为每次只用到上一行数据,所以空间只用2N的规模,不然N*N通不过大数据(提示空间过大)。[2]

递推式为:

if(p1[j-1]=='?')  dp[i][j]= dp[i-1][j-1];
if(p1[j-1]=='*')   dp[i][j]= dp[i][j-1] || dp[i-1][j-1] || dp[i-1][j];
else         dp[i][j]= dp[i-1][j-1] && (s[i-1]==p1[j-1]);

此题需要注意边界值的处理。

class Solution {
private:
    vector<char> simple(const char *p) {
        vector<char> ret;
        int i=0;
        while(*p!='\0')
        {
            if(*p!='*')
            {
                ret.push_back(*p);
                p++;
            }
            else
            {
                ret.push_back('*');
                while(*p=='*')
                    p++;
            }
        }
        return ret;
    }

public:
    bool isMatch(const char *s, const char *p) {
        if(s==NULL || p==NULL)
            return !s&&!p;
        
        vector<char> p1=simple(p);
        int ns=strlen(s),np=p1.size();

        if ( ns <np )
		{
			int notStar=np-count(p1.begin(),p1.end(),'*');
			if (ns < notStar )
				return false;
		}
        
        vector<vector<bool>> dp(2,vector<bool>(np+1,false));

        dp[0][0]=true;
            
        for(int j=1;j<=np;j++)  
			if(p1[j-1]=='*')  
				dp[0][j]=dp[0][j-1];  
        
        int cur,pre;
        for(int i=1;i<=ns;i++)
        {   
            cur=i%2;  
            pre=(i+1)%2;  
            dp[cur][0]=false;
            for(int j=1;j<=np;j++)
            {
                if(p1[j-1]=='?')
                    dp[cur][j]=dp[pre][j-1];
                else if(p1[j-1]=='*')
                    dp[cur][j]=dp[cur][j-1]||dp[pre][j-1]||dp[pre][j];
                else
                    dp[cur][j]=dp[pre][j-1]&&(s[i-1]==p1[j-1]);
            }
        }
        return dp[ns%2][np];
    }
};

还有一种用时比dp短的多的贪心算法[2]。


参考:

[1] http://blog.csdn.net/ojshilu/article/details/22600449

[2] http://blog.csdn.net/a83610312/article/details/9750655

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值