2021-08-15 数组:其他小题
除自身以外数组的乘积
-
挖掘几点信息:
- 除自身以外:即左边乘积*右边乘积
- 乘积:累乘,可以利用先前结果(用两个变量维护)
- 记录:直接使用答案数组记录,左至右左边乘积,反之亦然,然后乘以变量即为累积的另一边的成绩。故而至少需要两个数组,无法进行原地覆盖。
class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
n = len(nums)
ans = [1]*n
per, suf = 1, 1
for i in range(n):
ans[i] = ans[i] * per
ans[n-i-1] = ans[n-i-1] * suf
per = per * nums[i]
suf = suf * nums[n-i-1]
return ans
打乱数组
- 暴力法,但要注意赋值操作实际上是对象的引用(浅拷贝),所以需要额外空间记录原数组:
class Solution:
def __init__(self, nums):
self.array = nums
# 开辟新空间
self.original = list(nums)
def reset(self):
self.array = self.original
self.original = list(self.original)
return self.array
def shuffle(self):
aux = list(self.array)
for idx in range(len(self.array)):
remove_idx = random.randrange(len(aux))
self.array[idx] = aux.pop(remove_idx)
return self.array
- Fisher-Yates 洗牌算法:在每次迭代中,生成一个范围在当前下标到数组末尾元素下标之间的随机整数。接下来,将当前元素和随机选出的下标所指的元素互相交换。注意,当前元素是可以和它本身互相交换的。
class Solution:
def __init__(self, nums):
self.array = nums
self.original = list(nums)
def reset(self):
self.array = self.original
self.original = list(self.original)
return self.array
def shuffle(self):
for i in range(len(self.array)):
swap_idx = random.randrange(i, len(self.array))
self.array[i], self.array[swap_idx] = self.array[swap_idx], self.array[i]
return self.array
两个数组的交集Ⅱ
- 排序+双指针
class Solution:
def intersect(self, nums1: [int], nums2: [int]) -> [int]:
nums1.sort()
nums2.sort()
r = []
left, right = 0, 0
while left < len(nums1) and right < len(nums2):
if nums1[left] < nums2[right]:
left += 1
elif nums1[left] == nums2[right]:
r.append(nums1[left])
left += 1
right += 1
else:
right += 1
return r
-
哈希计数:
- 两个数组分别维护自己的哈希表(相当于利用
collections.Counter()
)
class Solution: def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]: return [*(collections.Counter(nums1) & collections.Counter(nums2)).elements()] ``` - 维护单个哈希表,利用计数判断 ```python class Solution: def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]: # 节省空间,遍历较短数组 if len(nums1) > len(nums2): return self.intersect(nums2, nums1) m = collections.Counter() for num in nums1: m[num] += 1 intersection = list() for num in nums2: if (count := m.get(num, 0)) > 0: intersection.append(num) m[num] -= 1 if m[num] == 0: m.pop(num) return intersection
- 两个数组分别维护自己的哈希表(相当于利用
-
进阶3问:这个题解