public class Solution {
    public boolean isMatch(String s, String p) {
        int idxs = 0, idxp = 0, idxmatch = 0, idxstar = -1;
        // s, p 各一个指针,   idxmatch表示s上一次真正match到的位置。
        // abgefg             *g
        // 在idxs = 2的时候,match上,idxs增加
        // 下一步知道p出界,发现是错误的match, 所以需要回到上次match的地方,即idxmatch
        
        // ab    ?*b
        // aab   ?*b
        // bab   b*b
        
        while(idxs < s.length()){
            if(idxp< p.length() && (p.charAt(idxp) == '?' || s.charAt(idxs) == p.charAt(idxp)) ) {
                idxs++;                 // idxs一旦走出去,无法返回,需要一个指针记录最后match的地方。
                idxp++;                 // match错误,idxp可以由idxstar+1重新得到
            } else if(idxp< p.length() && (p.charAt(idxp) == '*')) {
                idxmatch = idxs;        // 开始match的地方,idxs之前的必须完全match
                idxstar = idxp;         // 记录*的位置
                idxp++;                 // 尝试match 0 个,即idxs不动,idxp往后移
            } else if(idxstar != -1) {  // 上次match错误,或者match不够
                idxmatch++;             // idxmatch唯一标记上次match的地方 
                idxs = idxmatch;        // match
                idxp = idxstar + 1;     // 一次match一个
            } else {
                return false;
            }
        }
        
        while(idxp< p.length() && p.charAt(idxp) == '*') {  // trailing '*'s
            idxp++;
        }
        
        return idxp == p.length();
        
    }
}
public class Solution {
    public boolean isMatch(String s, String p) {
        boolean[][] match=new boolean[s.length()+1][p.length()+1];
        match[s.length()][p.length()]=true;
        for(int i=p.length()-1;i>=0;i--){
            if(p.charAt(i)!='*')
                break;
            else
                match[s.length()][i]=true;
        }
        for(int i=s.length()-1;i>=0;i--){
            for(int j=p.length()-1;j>=0;j--){
                if(s.charAt(i)==p.charAt(j)||p.charAt(j)=='?')
                        match[i][j]=match[i+1][j+1];
                else if(p.charAt(j)=='*')
                        // i+1, j 表示j维持原位置,i向后一位,'*'  match with s.charAt(i)
                        // i, j+1 表示i维持原位置,j向后一位,'*' match with ''(empty)
                        match[i][j]=match[i+1][j]||match[i][j+1];
                else
                    match[i][j]=false;
            }
        }
        return match[0][0];
    }
}

大米中的大米
12 声望5 粉丝

你的code是面向面试编程的,收集和整理leetcode discussion里个人认为的最优且最符合我个人思维逻辑的解法。


下一篇 »
132pattern