第322题:
给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。来源:力扣(LeetCode)
1、硬币兑换和之前的爬楼梯问题有着比较相似的思路;
爬楼梯我们可以知道f(1)=1,f(2)=2,f(3)=f(1)+f(2)……f(n)=f(n-1)+f(n-2),由此可以算出怕n阶楼梯的最多方法
而兑换硬币问题我们也可用一个数组分别存储从1到amount这些总金额所需要的最少硬币数;例如amount=1、coins=[1,2,5],它就只有一种方法兑换,就将1存入dp[1]中;
amount=2时,也只有两种方法兑换,但是其中最少用硬币是一个,就将1存入dp[2]中;
依次类推,就可以将总金额amount的最小硬币数存入dp[amount]中了。
第10题:
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。
'.' 匹配任意单个字符
'*' 匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。来源:力扣(LeetCode)
说明:
s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。
示例 1:
输入:
s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。
示例 2:
输入:
s = "aa"
p = "a*"
输出: true
解释: 因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次。
1、先判断s,p是否都为空,一样就两者匹配;
先判断s和p首字母相同是否;
当p中出现*时,会出现两种情况,第一种是p内*前一位和当前s内指向的字母不同,此时就p就跳过*和它前一位,s不移动,再次递归;
第二种就是p的*前一个字母和s内指向的字母相同,此时就将s指向后移一位,再次递归判断,如果有多个相同的也可以和p中的*相匹配;
如果以上情况都不是就判断s和p内指向的值依次是否相同,相同就两者一起后移一位,不同就返回false.
2、还有就是可以利用一个二维数组来判断s上的第i为元素和p上的第j位元素是否匹配;
定义一个dp[][]数组,因为当s和p都为空时,两者一定匹配,多以dp[0][0]位true;
dp[1][0]一定时false,因为s有一个字符但是p为空的时候一定是不匹配的;
这个boolean类型的dp数组的大小应该是dp[s.length+1][p.length+1],因为我们不仅仅要分别取出s和p的所有元素,还要表示分别取s和p的0个元素时候(都为空)的情况;
当写到dp[s.length][p.length]的时候,我们就得到了最终s和p的匹配情况;
dp[1][0]~dp[s.length][0]这一列都是false,因为s不为空但是p为空一定不能匹配;
当s为空时,p可以不为空,只需要用*在p内的偶数位上就可以将其他元素都设置位0个;
然后判断当p.charAt(j)位*时,也是有两种情况:p.charAt(j-1)和s.charAt(i)相同时则就将i后移,
p.charAt(j-1)和s.charAt(i)不相同,那就舍弃j-1和j位上的元素;
判断完带*后就判断两者相同或者p.charAt(j)位'.'的情况。