Python DP solution
class Solution:\n    # @return a boolean\n    def isMatch(self, s, p):\n        length = len(s)\n        if len(p) - p.count('*') > length:\n            return 
    class Solution:\n    # @return a boolean\n    def isMatch(self, s, p):\n        length = len(s)\n        if len(p) - p.count('*') > length:\n            return False\n        dp = [True] + [False]*length\n        for i in p:\n            if i != '*':\n                for n in reversed(range(length)):\n                    dp[n+1] = dp[n] and (i == s[n] or i == '?')\n            else:\n                for n in range(1, length+1):\n                    dp[n] = dp[n-1] or dp[n]\n            dp[0] = dp[0] and i == '*'\n        return dp[-1]\n\ndp[n] means the substring s[:n] if match the pattern i\n\ndp[0] means the empty string '' or s[:0] which only match the pattern '*'\n\nuse the reversed builtin because for every dp[n+1] we use the previous 'dp'\n\n\n\nadd Java O(m*n) version code\n\n    public boolean isMatch(String s, String p) {\n        int count = 0;\n        for (char c : p.toCharArray()) {\n            if (c == '*')\n                count++;\n        }\n        if (p.length() - count > s.length())\n            return false;\n        boolean[][] dp = new boolean[p.length() + 1][s.length() + 1];\n        dp[0][0] = true;\n        for (int j = 1; j <= p.length(); j++) {\n            char pattern = p.charAt(j - 1);\n            dp[j][0] = dp[j - 1][0] && pattern == '*';\n            for (int i = 1; i <= s.length(); i++) {\n                char letter = s.charAt(i - 1);\n                if (pattern != '*') {\n                    dp[j][i] = dp[j - 1][i - 1] && (pattern == '?' || pattern == letter);\n                } else\n                    dp[j][i] = dp[j][i - 1] || dp[j - 1][i];\n            }\n        }\n        return dp[p.length()][s.length()];\n    }
['Python']