面试题51:数组中重复的数字
题目:对于一个长度为n的数组里所有的数字都在0到n-1的范围内。查找重复数字。
方法一
- 首先对数组进行排序,然后遍历数组查找重复的数字,这样的时间复杂度为O(nlogn);
- 或者建立一个哈希表,这样实在O(n)的时间查找到,但是空间复杂度O(n)。
方法二
**空间复杂度为O(1)**的算法如下,
- 因为数字在0~n-1的范围内,那么如果数字没有重复,那么当数组排序之后数字 i 将出现在下标为 i 的位置,但是有重复的话,在某个位置j出现的数字将不是j,则需要重排这个数组。
- 从头到尾依次扫描这个数组中的每个数字,
- 如果下标 i 不是出现数字 i,那么就把数字i和i处的数字进行交换使数字 i 出现在应该出现的位置,
- 如果新交换的数字还不是他应该出现的位置,继续交换,直至该处的数字 m 等于该处的下标m,
- 如果在交换的过程中,第i处的位置数字等于第m处的数字,那么我们就找到了第一个重复的数字,记录这个数字,
如果出现重复数字,这种情况下的重复数字无需交换位置 if nums[i] == nums[nums[i]]:
- 在从下一个位置继续扫描。
注意:
# 需要判断数组的组成是否合法
for i in numbers:
if i < 0 or i > len(numbers) - 1:
return False
完整代码:
class Solution(object):
def findDuplicate(self, nums):
# 判断非法输入
if nums == [] or len(nums)<=1:
return False
# 需要判断数组的组成是否合法
for i in numbers:
if i < 0 or i > len(numbers) - 1:
return False
# 遍历数组中所有元素
for i in range(len(nums)):
# 如果出现 i 位置上的元素,不等于 i
while i != nums[i]+1:
# 如果出现重复数字,这种情况下的重复数字无需交换位置
if nums[i] == nums[nums[i]]:
return nums[i]
else:
# 将数字 i 放回它本应属于的位置
index = nums[i]
nums[i], nums[index] = nums[index], nums[i]
相关题目
如果需要返回多个重复数字,则需要使用一个集合来保存遇到的所有重复数字。
class Solution(object):
def findDuplicate(self, nums):
duplication = set()
# 判断非法输入
if nums == [] or len(nums)<=1:
return False
# 遍历数组中所有元素
for i in range(len(nums)):
# 如果出现 i 位置上的元素,不等于 i
while i != nums[i]+1:
# 如果出现重复数字,这种情况下的重复数字无需交换位置
if nums[i] == nums[nums[i]]:
duplication.add(nums[i])
break
else:
# 将数字 i 放回它本应属于的位置
index = nums[i]
nums[i], nums[index] = nums[index], nums[i]
return duplication
面试题52:构建乘积数组
给定一个数组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[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]
B[i]=A[0]∗A[1]∗...∗A[i−1]∗A[i+1]∗...∗A[n−1](除 i 位置以外所有的数字)。不能使用除法。
思路梳理
时间复杂度:
O
(
N
)
O(N)
O(N)
寻找规律后发现,可以使用两次长度为 N 的循环,
- 第一层循环正向递归地将各个元素相乘(每个新B 都是前一个B 乘以下一个A 元素);
- 第二层循环反向地,从后到前地将元素相乘。
# -*- coding:utf-8 -*-
class Solution:
def multiply(self, A):
if A == [] or len(A)<=0:
return
length = len(A)
aList = [1]*length
for i in range(1, length):
aList[i] = aList[i-1] * A[i-1]
temp = 1
for i in range(length-2, -1, -1):
temp *= A[i+1]
aList[i] *= temp
return aList
面试题53:正则表达式匹配
请实现一个函数用来匹配包括
′
.
′
'.'
′.′ 和
′
∗
′
'*'
′∗′ 的正则表达式。
模式中的字符
′
∗
′
'*'
′∗′ 表示任意一个字符,而
′
∗
′
'*'
′∗′ 表示它前面的字符可以出现任意次(包含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。
例如,字符串"aaa"与模式"a.a"和
"
a
b
∗
a
c
∗
a
"
"ab*ac*a"
"ab∗ac∗a"匹配,但是与"aa.a"和
"
a
b
∗
a
"
"ab*a"
"ab∗a"均不匹配
思路梳理
困难题目:LeetCode 10
参考答案:https://github.com/Jack-Lee-Hiter/AlgorithmsByPython/blob/master/Target Offer/正则表达式匹配.py