查找排序相关面试题
题目链接
先将字符串转成列表,默认一个字母为一个元素,对s和t进行排序,判断排序后的列表是否相等。
class Solution(object):
def isAnagram(self, s, t):
"""
:type s: str
:type t: str
:rtype: bool
"""
ss = list(s)
tt = list(t)
ss.sort()
tt.sort()
return ss == tt
可以用sorted排序直接一句代码搞定。
class Solution(object):
def isAnagram(self, s, t):
"""
:type s: str
:type t: str
:rtype: bool
"""
return sorted(list(s)) == sorted(list(t))
上面两种方法都用到了python自带的排序,时间复杂度为O(nlogn),我们可以分别用两个字典记录两个字符串出现的单词的次数,比较两个字典是否一样来得出结果,可以降低算法的时间复杂度。
class Solution(object):
def isAnagram(self, s, t):
"""
:type s: str
:type t: str
:rtype: bool
"""
dict1={} # {a:1,b:2}
dict2={}
for i in s:
dict1[i] = dict1.get(i,0)+1
for j in t:
dict2[j] = dict2.get(j,0)+1
return dict1 == dict2
class Solution(object):
def searchMatrix(self, matrix, target):
"""
:type matrix: List[List[int]]
:type target: int
:rtype: bool
"""
for line in matrix:
if target in line:
return True
return False
假设列表有n个元素,m行k列,第一个for循环时间复杂度为O(m),判断元素是否在列表中时间复杂度为O(k),所以时间复杂度为O(mk),也即O(n),可以看作先行查找。既然列表已经有序,我们可以考虑用二分查找。
class Solution(object):
def searchMatrix(self, matrix, target):
"""
:type matrix: List[List[int]]
:type target: int
:rtype: bool
"""
h = len(matrix)
if h==0:
return False
w = len(matrix[0])
if w==0:
return False
left=0
right=h*w-1
while left<=right:
mid = (left+right)//2
i = mid // w
j = mid % w
if matrix[i][j]==target:
return True
elif matrix[i][j]>target:
right = mid-1
else:
left = mid+1
else:
return False
这里不太一样的是列表是二维的,不能直接用matrix[mid],所以要根据规律找到mid所在的行和列,分别为mid除以w和取余即可。一开始的判断是为了避免给出的列表为空列表的情况,那么matrix[0]就会超出索引导致报错。由于是二分查找,时间复杂度降为O(logn)。
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
n = len(nums)
for i in range(n):
for j in range(i):
if nums[i]+nums[j] == target:
return sorted([i,j])
两层for循环,时间复杂度为O(n^2)。如果列表已经是有序的,我们很自然地会想到用二分查找来解决。现在列表是无序的,我们可以先对其进行排序,然后进行二分查找,需要注意的是排序完后列表元素的位置与原来的位置不一样了,所以我们要创建一个二维列表,将每个元素在原列表中的位置保存起来。
class Solution(object):
def binary_search(self,li,left,right,val):
while left<=right:
mid=(left+right)//2
if li[mid][0] == val:
return mid
elif li[mid][0]>val:
right=mid-1
else:
left=mid+1
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
new_nums=[[num,i] for i,num in enumerate(nums)]
new_nums.sort(key=lambda x:x[0])
for i in range(len(new_nums)):
a=new_nums[i][0]
b=target - a
if b>=a:
j=self.binary_search(new_nums,i+1,len(new_nums)-1,b)
else:
j=self.binary_search(new_nums,0,i-1,b)
if j:
break
return sorted([new_nums[i][1],new_nums[j][1]])