剑指offer系列(十九)——数组中重复的数字,构建乘积数组,正则表达式匹配

数组中重复的数字

题目描述

在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。

解题思路:

参考:https://blog.csdn.net/u010005281/article/details/80171726?utm_source=copy

注意:

1返回数组中第一个重复的值,即不可破坏原来数组的顺序。

2这要特别注意~找到任意重复的一个值并赋值到duplication[0].

3函数返回True or False

法一:

hash表来做,相当于java中hashmap。

法二:

“数组里数字的范围在0 ~ n-1 之间”,所以可以利用现有数组设置标志,当一个数字被访问过后,可以设置对应位上的数 + n,之后再遇到相同的数时,会发现对应位上的数已经大于等于n了,那么直接返回这个数即可。

代码:

法一:

# -*- coding:utf-8 -*-
class Solution:
    # 这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
    # 函数返回True/False
    def duplicate(self, numbers, duplication):
        # write code here
        dict = {}
        for num in numbers:
            if num not in dict:
                dict[num]=0
            else:
                duplication[0]=num
                return True
        return False
# -*- coding:utf-8 -*-
class Solution:
    def duplicate(self, numbers, duplication):
        # write code here
        if not numbers:
            return False
        num = []
        
        for i in numbers:
            if i in num:
                duplication[0]=i
                return True
            else:
                num.append(i)
        return False

法二:

# -*- coding:utf-8 -*-
class Solution:
    # 这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
    # 函数返回True/False
    def duplicate(self, numbers, duplication):
        # write code here
        long = len(numbers)
        for i in range(long):
            index = numbers[i]%long if numbers[i]>=long else numbers[i]
            if numbers[index]>long:
                duplication[0] = index
                return True
            numbers[index] += long
        return False
        

构建乘积数组

题目描述

给定一个数组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]。不能使用除法。

解题思路:

第一次看理解错题意,一位B[i]为A[i]连乘到第几项。实际上题意为A[0]到A[n]连乘,缺少乘的那一项为B[i],如下所示:
        B[0] = A[1] * A[2] * A[3] * A[4] *....*A[n-1] ;(没有A[0])
        B[1 ]= A[0] * A[2] * A[3] * A[4] *....*A[n-1] ;(没有A[1])
        B[2] = A[0] * A[1] * A[3] * A[4] *....*A[n-1] ;(没有A[2])

方法一:

代码:

# -*- coding:utf-8 -*-
class Solution:
    def multiply(self, A):
        # write code here
        if not A or len(A)<0:
            return 0
        length = len(A)
        B=[1]*length
        #下三角 B[0]=1 从1开始
        for i in range(1, length):
            B[i] = B[i-1]*A[i-1]
        #上三角 ,从后向前遍历,不算最后一个(num-1)第一个for遍历过
        temp =1
        for i in range(length-2, -1, -1):
            temp *= A[i+1]
            B[i] *= temp
        return B

正则表达式匹配

题目描述

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

解题思路:

 . 表示可以是任意字符,* 表示前面的字符可以出现任意次,所以在patten中*不可能位于首位  ,

eg:     aa  a.a  ab*ac*a(b出现0次,c出现0次,这样就是aaa了)

分为如下情况:

1如果s和pattern匹配, 直接True

2如果pattern为'', 因为s和pattern不相等, 直接False

3当s为'', 如果pattern为'.', 则返回True
  当s为'', 如果pattern长度为1且不为'.', 或者pattern第二个字符不是*, 则pattern不可能为空, 返回False
  若pattern长度不为1, 且第二个字符为*, pattern还有空的可能, 从第三个字符开始迭代

4如果pattern长度不小于2, 而且pattern的第二个字符不是*的情况下
   当 pattern[0] 不等于s[0], 且不为 . 的时候, s和pattern必不相等
   否则, s 和 pattern 都右移一位, 继续比较

5如果pattern长度不小于2, 且pattern第二个字符为*的情况下
  如果s[0]不等于pattern[0], 且pattern[0]不为 . , 那么第一位比较不成功, pattern必须后移两位继续比较后面是否能和s第一位匹配
  如果s[0]等于pattern[0], 或者pattern[0]为 . , 第一位匹配, 那么会有
        1. aaa 和 a*a 这种情况, 星号代表了多个a, 因此s需要不断右移一位继续比较
        2. a 和 a*a 中这情况, 这时候星号代表0个a, 因此s不需要右移, pattern需要右移两位
        3. abc 和 a*bc 这种情况, 星号代表了1个a, s右移一位, pattern右移两位继续比较

 除去上述pattern不小于2情况, 只剩下pattern等于1的情况, 因此如果pattern为".",  而且s长度为1, 返回True

代码:

方法一:

# -*- coding:utf-8 -*-
class Solution:
    # s, pattern都是字符串
    def match(self, s, pattern):
        # write code here
        if s == pattern:
            return True
        elif pattern == '':
            return False
        elif s == '':
            if pattern == '.':
                return False
            elif len(pattern)==1 or pattern[1]!='*':
                return False
            else:
                return self.match(s, pattern[2:])
            
        if len(pattern) >=2 and pattern[1] != '*':
            if s[0] != pattern[0] and pattern[0]!='.':
                return False
            else:
                return self.match(s[1:], pattern[1:])
        elif len(pattern) >=2 and pattern[1] =='*':
            if s[0] != pattern[0] and pattern[0] !='.':
                return self.match(s, pattern[2:])
            else:
                return self.match(s[1:], pattern) or self.match(s, pattern[2:] or self.match(s[1:],pattern[2:]))
        elif pattern == '.' and len(s)==1:
            return True
        return False
            

方法二:

# -*- coding:utf-8 -*-
class Solution:
    # s, pattern都是字符串
    def match(self, s, pattern):
        # write code here
        if s == pattern: 
            return True 
        if len(pattern)>1 and pattern[1] == '*': 
            if s and (s[0]==pattern[0] or pattern[0] == '.'):
                return self.match(s,pattern[2:]) or self.match(s[1:],pattern) 
            else:
                return self.match(s,pattern[2:]) 
        elif s and pattern and (s[0] == pattern[0] or pattern[0]=='.'): 
            return self.match(s[1:],pattern[1:]) 
        return False

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值