赞
踩
class Solution: def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None: """ Do not return anything, modify nums1 in-place instead. """ res = [] pos1 = pos2 = 0 while len(res) < m + n: # 已遍历完成的数组,取出的元素值设为无限大 num1 = float('inf') if pos1 >= m else nums1[pos1] num2 = float('inf') if pos2 >= n else nums2[pos2] if num1 < num2: res.append(num1) pos1 += 1 else: res.append(num2) pos2 += 1 # 原地修改 nums1 的内容 nums1[:] = res
res
增加了空间复杂度,由于题目中 nums1
尾部有空余空间,可以直接从两个数组元素的尾部开始反向遍历,总是把较大元素覆盖到 nums1
尾部。注意到当从 nums1 本身复制一个元素到最后占据一个空位时,nums1 前面又出现一个空位,因此 nums1 中永远有足够的空间容纳 nums2 的全部元素def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None: """ Do not return anything, modify nums1 in-place instead. """ pos1 = m - 1 pos2 = n - 1 tail = -1 while pos1 >= 0 or pos2 >= 0: if pos1 == -1: nums1[tail] = nums2[pos2] pos2 -= 1 elif pos2 == -1: nums1[tail] = nums1[pos1] pos1 -= 1 elif nums1[pos1] > nums2[pos2]: nums1[tail] = nums1[pos1] pos1 -= 1 else: nums1[tail] = nums2[pos2] pos2 -= 1 tail -= 1
nums
,将不等于 val
的元素复制到左指针位置,并把左指针右移一格,当右指针遍历完成时,左指针索引位置即为新长度class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
left = 0
for right in range(len(nums)):
if nums[right] != val:
nums[left] = nums[right]
left += 1
return left
nums
有序,只需右指针遍历 nums
,将 nums[right] != nums[right-1]
的元素复制到左指针位置,并把左指针右移一格,当右指针遍历完成时,左指针索引位置即为新长度。和上一题很类似class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
left = 1
for right in range(1, len(nums)):
if nums[right] != nums[right-1]:
nums[left] = nums[right]
left += 1
return left
class Solution: def removeDuplicates(self, nums: List[int]) -> int: left, cnt = 1, 1 for right in range(1, len(nums)): if nums[right] != nums[right-1]: # 元素值变化,重置计数器 nums[left] = nums[right] left += 1 cnt = 1 else: # 元素值不变,计数器加1 cnt += 1 if cnt <= 2: # 允许保留一个重复元素 nums[left] = nums[right] left += 1 return left
nums
是有序的,所以相同元素必然连续。左右两个指针都初始化指向 2 索引位置,右指针遍历 nums
,如果 nums[right] == nums[left-2]
意味着必有 nums[right] == nums[left-1] == nums[left-2]
,这时已经有两个相同值元素,右指针指示的元素应该舍去。因此,只需将 nums[right] != nums[left-2]
的元素复制到左指针位置,并把左指针右移一格。当右指针遍历完成时,左指针索引位置即为新长度class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
left, right = 2, 2
for right in range(2, len(nums)):
if nums[right] != nums[left-2]:
nums[left] = nums[right]
left += 1
return left
def majorityElement(self, nums: List[int]) -> int:
cnts = {}
limit = len(nums) // 2
for num in nums:
if num not in cnts:
cnts[num] = 1
else:
cnts[num] += 1
if cnts[num] > limit:
break
return num
def majorityElement(self, nums: List[int]) -> int:
nums.sort()
return nums[len(nums) // 2]
def majorityElement(self, nums: List[int]) -> int: def _rec(lo, hi): # 递归边界:长度为1的列表中众数就是元素本身 if lo == hi: return nums[lo] # 分治递归计算左右两部分的众数 mid = (hi - lo) // 2 + lo left = _rec(lo, mid) right = _rec(mid + 1, hi) # 左右众数相等,则本段众数也一致 if left == right: return left # 左右众数不等,则本段众数为出现更多的那个 left_count = sum(1 for i in range(lo, hi + 1) if nums[i] == left) right_count = sum(1 for i in range(lo, hi + 1) if nums[i] == right) return left if left_count > right_count else right return _rec(0, len(nums)-1)
原始数组: [7, 7, 5, 7, 5, 1 | 5, 7 | 5, 5, 7, 7 | 7, 7, 7, 7]
候选众数: 7 7 7 7 7 7 5 5 5 5 5 5 7 7 7 7
众数计数: 1 2 1 2 1 0 1 0 1 2 1 0 1 2 3 4
def majorityElement(self, nums: List[int]) -> int:
candidate = nums[0]
cnt = 0
for num in nums:
if cnt == 0:
candidate = num
cnt = cnt + 1 if num == candidate else cnt - 1
return candidate
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。