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