1. 程式人生 > >劍指offer系列——陣列中重複的數字,構建乘積陣列,正則表示式匹配

劍指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