#350 Intersection of Two Arrays II
解题思路:
还是用回之前的办法,先求得两个list的intersection。然后for循环每个intersection里的元素,取元素在两个list出现次数的最小值,然后在最后result补齐该元素出现的次数。
class Solution:
def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
sml_num = min(len(nums1), len(nums2))
if sml_num == len(nums1):
intersection = set(nums2).intersection(nums1)
else:
intersection = set(nums1).intersection(nums2)
result = []
for i in intersection:
occurrence = min(nums1.count(i), nums2.count(i))
for j in range(occurrence):
result.append(i)
return result
runtime:
但这样很慢……
然后想起有种更快多次添加同个元素的办法。不用for,直接 [添加元素] * 添加次数。
class Solution:
def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
if len(nums1) < len(nums2):
intersection = set(nums2).intersection(nums1)
else:
intersection = set(nums1).intersection(nums2)
result = []
for i in intersection:
occurrence = min(nums1.count(i), nums2.count(i))
result += [i]*occurrence
return result
这样快多了。
sample solution给的是java和c++。暂时看不懂,只能等学了这两种语言再把题做一遍了。
#167 Two Sum II - Input array is sorted
解题思路:
因为一定有一对解。所以就for把list的元素过一遍,直到找到解为止。
过的时候,用target减去当前元素,然后在剩下的元素看这个差值存不存在。在就把当前这个元素的idx1,和差值的idx2输出了。(按题目设置一定有对解,所以总会找到存在的差值)。
棘手的是差值和当前元素相等,idx1和idx2会冲突。index()第一个argument是要确定index的值,第二个argument是optional的,是寻找的起始位置。用这个办法区分开来idx1和idx2。
class Solution:
def twoSum(self, numbers: List[int], target: int) -> List[int]:
idx1 = 0
for i in numbers:
num = target - i
if num == i:
if num in numbers[numbers.index(i)+1:]:
idx2 = numbers.index(num, numbers.index(i)+1)
return [idx1+1, idx2+1]
else:
if num in numbers:
idx2 = numbers.index(num)
return [idx1+1, idx2+1]
idx1 += 1
可是time limit exceeded……
谷歌查了下,说in operator as List containment 时是 O(n)。这就是慢的原因。如果是Dict lookup就是O(1)。
所以不能用if in的办法确认差值存不存在以及其index。只能用二分搜索法。
class Solution:
def twoSum(self, numbers: List[int], target: int) -> List[int]:
idx1,idx2 = 0, 0
for i in numbers:
num = target - i
l, r = idx1+1, len(numbers)-1
while l < r:
m = (l+r)//2
if num > numbers[m]:
l = m + 1
elif num < numbers[m]:
r = m
else:
if num == i:
idx2 = numbers.index(num, idx1+1)
else:
idx2 = numbers.index(num)
break
if idx2:
return [idx1+1, idx2+1]
if numbers[l] == num:
if num == i:
idx2 = numbers.index(num, idx1+1)
else:
idx2 = numbers.index(num)
return [idx1+1, idx2+1]
idx1 += 1
runtime:
还是很慢……
44ms的solution:
两指针的和大于target就右指针左移,小于target就左指针右移。直到遇到解为止。好妙。
重新写了一遍:
class Solution:
def twoSum(self, numbers: List[int], target: int) -> List[int]:
l, r = 0, len(numbers)-1
while l < r:
val = numbers[l] + numbers[r]
if val < target:
l += 1
elif val > target:
r -= 1
else:
return [l+1, r+1]
玄学runtime: