C排名第一,该题是HJ71 字符串通配符的简化版本。不用动态规划和递归,用双指针回溯法,只遍历一次,不占用额外空间。由于模式串中的字符 '*' 表示它前面的字符可以出现任意次,为了方便处理 '*' 和它前面的字符,在这里逆序匹配字符。

思路:

指针 i,j 分别表示 str 串和 pattern 串当前字符的位置,从后向前按匹配规则匹配,直至 str 串访问完毕。
判断条件:当遇到 pattern 串的 '*' 时,用 i_prev 和 j_prev 记录当前 str 串和 pattern 串字符位置,此时 j 指向 '*' 前面的字符,对比 i 所指字符是否相同:
  1. 若不同,该 '*' 作废, i 不变,j 前移一位,继续按匹配规则匹配;
  2. 若相同, i 不变,j 前移一位,继续按匹配规则匹配(开始时 '*' 的匹配数为0)。当之后遇到匹配错误的情况,回溯 i_prev 和 j_prev 记录的值返还给 i,j,此时 i 前移一位,'*' 的匹配数+1,回到判断条件继续判断;
若 str 串与 pattern 串都访问完毕则匹配成功,若 pattern 串还有剩余,则判断接下来的剩余串是否是 "...x*x* " 类型的组合,是则匹配成功,不是则匹配失败。
代码:
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param str string字符串 
     * @param pattern string字符串 
     * @return bool布尔型
     */
    bool match(string str, string pattern) {
        // write code here
        int i=str.size()-1,j=pattern.size()-1;//逆序匹配
        int i_prev,j_prev,flag=0;//i_prev,j_prev指针用来回溯,flag为回溯标志
        while(i>-1){//str串匹配到头就结束
            if(str[i]==pattern[j] || pattern[j]=='.'){
                i--;j--;
            }
            else if(pattern[j]=='*'){
                if(str[i]!=pattern[j-1] && pattern[j-1]!='.'){//若'*'前面的字符不匹配,pattern的指针前移
                    j-=2;
                }
                else{//若'*'前面的字符可以匹配,则从匹配0个字符开始,直至遇到之后不匹配时回溯,i_prev,j_prev为回溯指针
                    i_prev=i;
                    j_prev=j;
                    j-=2;
                    flag=1;
                }
            }
            else if(flag){//出现字符不匹配情况,回溯
                i=i_prev-1;//回溯之后'*'的匹配数+1
                j=j_prev;
                flag=0;
            }
            else{
                return false;
            }
        }
        while(j>-1){//若pattern串还有字符,则只要出现非'*'字符单走就一定匹配失败
            if(pattern[j]!='*' && pattern[j+1]!='*'){
                return false;
            }
            j--;
        }
        return true;
    }
};