【LeetCode】day5

10. 正则表达式匹配

给定一个字符串 (s) 和一个字符模式 (p)。实现支持 '.' 和 '*' 的正则表达式匹配。

'.' 匹配任意单个字符。
'*' 匹配零个或多个前面的元素。

匹配应该覆盖整个字符串 (s) ,而不是部分字符串。

说明:

  • s 可能为空,且只包含从 a-z 的小写字母。
  • p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *

示例 1:

输入:
s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。

示例 2:

输入:
s = "aa"
p = "a*"
输出: true
解释: '*' 代表可匹配零个或多个前面的元素, 即可以匹配 'a' 。因此, 重复 'a' 一次, 字符串可变为 "aa"。

示例 3:

输入:
s = "ab"
p = ".*"
输出: true
解释: ".*" 表示可匹配零个或多个('*')任意字符('.')。

示例 4:

输入:
s = "aab"
p = "c*a*b"
输出: true
解释: 'c' 可以不被重复, 'a' 可以被重复一次。因此可以匹配字符串 "aab"。

示例 5:

输入:
s = "mississippi"
p = "mis*is*p*."
输出: false
思路:动态规划 参考:https://blog.csdn.net/gatieme/article/details/51049244
#utf-8
def isMatch(s, p):
	#dp[i][j]表示s[0...i-1]是否能被p[0...j-1]匹配
	dp = [[False for i in range(len(p) + 1)] for  i in range(len(s) + 1)]
	#s p中都无字符
	dp[0][0] = True
	#p中无字符时
	for index in range(1,len(s) + 1):
		dp[index][0] = False
	#s中无字符时 当且仅当p为x*时可以匹配
	for index in range(2,len(p) + 1):
		dp[0][index] = p[index - 1] == '*' and dp[0][index - 2]
	#当p不为"*"时,dp[i][j] = dp[i - 1][j - 1]&&(s[i] == p[j] || p[j] == ".")
	#当p为"*"时,两种情况符合一种就匹配(p: Ax*):
	#1.p中x出现0次匹配s 此时dp[i][j] = dp[i][j-2]
	#2.p中x出现1次或多次 此时x == s[i] dp[i][j] = (s[i] == p[j - 1] || p[j - 1] == ".") && dp[i -1][j]
	for index1 in range(1,len(s) + 1):
		for index2 in range(1,len(p) + 1):
			if p[index2 - 1] != '*':
				dp[index1][index2] = dp[index1 - 1][index2 - 1]  and (s[index1 - 1] == p[index2 - 1] or p[index2 - 1] == ".")
				#print("dp[%d][%d]:"%(index1,index2) + str(dp[index1][index2]))
			else:
				dp[index1][index2] = dp[index1][index2 - 2] or (s[index1 - 1] == p[index2 - 2] or p[index2 - 2] == ".") and dp[index1 - 1][index2]
	return dp[len(s)][len(p)]

 

11. 盛最多水的容器

给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (iai) 。画 n 条垂直线,使得垂直线 i 的两个端点分别为 (iai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

注意:你不能倾斜容器,n 至少是2。

思路:前后两个指针 最开始位置在a1和an,因为此时宽度最大,然后移动指针并计算area,每次向内移动高度低的线的位置的指针,因为低的线限制了面积大小,移动高的线对增加面积没有任何帮助

class Solution:
    def maxArea(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        maxarea = 0
        i = 0
        j = len(height) - i - 1
        while(j > i):
            area = (j - i) * min(height[i],height[j])
            maxarea = max(area,maxarea)
            if(height[i] > height[j]):
                j -= 1
            else:
                i += 1
        return maxarea

15. 三数之和

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

思路:把三数之和转化为两数之和问题 即 a = -(b + c) 

两数之和的解法:将数组排序后设置左右两个指针 如果指针处两数和等于零 记为一个解 并向内移动左右指针 如果指针处两数和小于零 说明小的数太小 左指针移动 如果指针处两数和大于零 说明大的数过大 右指针移动

此题还需注意去重

class Solution:
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        s = []
        nums.sort()
        for i in range(len(nums) - 2):
            if i == 0 or nums[i] > nums[i - 1]:
                left = i + 1
                right = len(nums) - 1
                while left < right:
                    sum = nums[i] + nums[left] + nums[right]
                    if sum == 0:
                        m = [nums[i],nums[left],nums[right]]
                        s.append(m)
                        left += 1
                        right -= 1
                        while left < right and nums[left] == nums[left-1]:    # skip duplicates
                            left += 1
                        while left < right and nums[right] == nums[right+1]:
                            right -= 1
                    elif sum < 0:
                        left += 1
                    else:
                        right -= 1		
        return s

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值