剑指offer刷题0406

构建乘积数组

正则表达式匹配

构建乘积数组

问题
给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],其中B中的元素B[i]=A[0]A[1]…A[i-1]A[i+1]…A[n-1]。不能使用除法。
分析: 思路1:
其实对B的每一个元素,都可以以下标i,把整个乘积分为前后两个部分:B[i]=A[i-1]及之前的累计乘积* A[i]之后到A[n-1]的乘积(以A

[i]为分界点),分别对前后去求,然后更新。
实现细节:以对角线A[i]为界,分为左下部分与右上两部分。可以先做左下部分,从上往下,做一个循环,B中前半部分的当前的每一个元素,是A中对应的一个值和前一个B的值相乘得到。然后再对右上部分做一个循环,从下往上,开一个temp 记录右侧已有的乘积,再把右侧的值乘以原来左侧的值,更新B[i]. 


思路2:能否做一个循环,当计算B[i]再循环时,碰到A[i],就用1来作为值去乘. 虽然,相对1,计算量重复了一些.但bingo!

思路1代码:

# -*- coding:utf-8 -*-
class Solution:
    def multiply(self,A):
        if not A:
            return []
        B=[1]*len(A)
        #先做左下部分,从上往下累乘左下半
        for i in range(1,len(A)):
            B[i]=B[i-1]*A[i-1]

        #再做右上部分,这时可以从右下往上乘积。注意此时需要开辟一个temp来存储右侧A的累乘积了
        temp=1
        for i in range(len(A)-2,-1,-1):
            temp=temp*A[i+1]
            B[i]=B[i]*temp   #左侧的*右侧的,更新了 B[i]

        return B 

思路2代码:

##**思路2:能否做一个循环,当计算B[i]再循环时,碰到A[i],就用1来作为值去乘.** 
def multiply_two(A):
    if not A:
        return []
    B=[1]*len(A)
    for i in range(len(B)):
        temp=1
        for j in range(len(A)):
            if i==j:
                temp=temp*1
            else:
                temp=temp*A[j]
        B[i]=temp
    return B
A_two=[1,2,3,4,5]
BB_two=multiply_two(A)
print(BB_two)
                        

正则表达式匹配

问题

请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配

思路

这道题相对比较复杂。重点是要思路清晰,注意用到递归去判断…要注意讨论各种各样的情况,导致无法通过所有用例。

对初始输入的判断:
如果s和pattern都为空,则True;如果s不空,而pattern为空,则直接False.

然后来读取pattern中的每个字符:

  • 如果当前pattern字符的后面不是* ,则说明只可匹配1个
    • 如果当前pattern字符是.的话,可匹配1个任意字符
    • 如果不是点,则只能匹配给出的字符,若不匹配则直接返回
    • 完成后两者均往后+1,继续判断
  • 如果当前pattern字符的后面是* ,说明当前pattern字符可匹配0-任意多个。
    • 如果当前pattern字符与串的字符不一致,而且pattern当前字符不是点,则当作是 * 的未匹配的情况,pattern往后+2而字符串不变(如aaa与ab*ac*中b*的情况)(此处自己改动后还是好理解多了)
    • 否则其他情况:
      • 要么共匹配0个,pattern往后+2,字符串不变
      • 要么共匹配1个,字符串往后+1, pattern 往后+2
      • 要么先匹配1个,留待继续匹配,此时字符串+1, pattern不变
  • 然后继续匹配后面的是否match
    # -*- coding:utf-8 -*-
    class Solution:
        # s, pattern都是字符串
        def match(self,s,pattern):
            #如果s和pattern都为空,则返回true
            if len(s)==0 and len(pattern)==0:
                return True
            #如果s不为空,pattern为空,则返回false
            elif len(s)!=0 and len(pattern)==0:
                return False
    
            #如果s为空,而pattern不为空,则需要判断
            elif len(s)==0 and len(pattern)!=0:
                #pattern的第二个字符为*,则pattern后移两位继续比较
                if len(pattern)>1 and pattern[1]=="*":
         ######           ##注意用递归  #########
                    return self.match(s,pattern[2:])
                else:
                    return False
            else: #s 与pattern 都不为空的情况
                #pattern 的第二个字符为*的情况
                if len(pattern)>1 and pattern[1]=="*":
    
                    # s与pattern的第一个元素不同,则s不变,pattern后移两位,相当于pattern前两位看成空
                    if s[0]!=pattern[0] and pattern[0]!=".":
                        return self.match(s,pattern[2:])
                    else:
                        #如果s[0]与pattern[0]相同,且pattern[1]为*,这时有三种情况
                            #pattern后移2个,s不变;相当于也把pattern前两位看成空,匹配后面的
                            #pattern 后移两位,s后移1位,相当于pattern的前两位与s[0]匹配
        ####此注意与s多位情况     #pattern不变,s后移1个;相当于pattern前两位与s中多位进行 匹配,因为*可以匹配多位
                        return self.match(s,pattern[2:]) or self.match(s[1:],pattern[2:]) or self.match(s[1:],pattern)
    
                 #pattern第二个字符不为*的情况
                else:
                    if s[0]==pattern[0]  or pattern[0]==".":
                        return self.match(s[1:],pattern[1:])
                    else:
                        return False
                

猜你喜欢

转载自blog.csdn.net/wangwangstone/article/details/89052928