defquickSort(self, arr: list) -> list: Larr = len(arr) if Larr <= 1: return arr pivot = arr[0] left = [x for x in arr[1:] if x <= pivot] right = [x for x in arr[1:] if x > pivot] return self.quickSort(left) + [pivot] + self.quickSort(right)
defsmallerNumbersThanCurrent(self, nums: List[int]) -> List[int]: # 先做个排序,排序后的下标数i就是比nums[i]小的个数 # 使用hash table numsSorted = self.quickSort(nums) Lnums = len(numsSorted) table = dict() table[numsSorted[0]] = 0 for i inrange(1, Lnums): # 比如1,2,2,3;若遇到相同的两个值,不用进行更新; # 或者判断numsSorted[i]是否已经在table里,如果存在,不用进行更新; if numsSorted[i] > numsSorted[i - 1]: table[numsSorted[i]] = i # 最后,按原数组的顺序展示结果 res = [0] * Lnums for i inrange(0, Lnums): res[i] = table[nums[i]]
classSolution: defvalidMountainArray(self, arr: List[int]) -> bool: TheTop = -1 L = len(arr) theMaxIndex = 0 index = 1 while index < L and arr[theMaxIndex] < arr[index]: theMaxIndex = index index += 1 theMinIndex = theMaxIndex # 此时假设已经找到峰值,后面的数据都必须逐个减少,否则就False while index < L and arr[theMinIndex] > arr[index]: theMinIndex = index index += 1 if index == L and theMaxIndex != 0and theMaxIndex != L - 1: returnTrue else: returnFalse
classSolution: defvalidMountainArray(self, arr: List[int]) -> bool: # 双指针,左指针从左向右遍历;右指针从右向左遍历,如果最终在峰值相遇 L = len(arr) if L < 3: returnFalse left = 0 right = L - 1 while left < L - 1and arr[left] < arr[left + 1]: left += 1 while right > 0and arr[right] < arr[right - 1]: right -= 1 if left == right and left !=0and right != L - 1: returnTrue returnFalse
classSolution: defmoveZeroes(self, nums: List[int]) -> None: """ Do not return anything, modify nums in-place instead. """ slow = 0 fast = 0 L = len(nums) while fast < L: if nums[fast] != 0: nums[slow] = nums[fast] slow += 1 fast += 1 for i inrange(slow, L): nums[i] = 0
我们遍历原数组,将原数组下标为 i 的元素放至新数组下标为 (i+k)modn 的位置,最后将新数组拷贝至原数组即可。
数据复制代码
时间复杂度O(N)
空间复杂度O(N)
1 2 3 4 5 6 7 8 9
classSolution: defrotate(self, nums: List[int], k: int) -> None: L = len(nums) k %= L new_nums = [0] * L for i inrange(L): new_nums[ (i + k) % L ] = nums[i] for i inrange(L): nums[i] = new_nums[i]
数组翻转思路
该方法基于如下的事实:当我们将数组的元素向右移动 k 次后,尾部 k mod n 个元素会移动至数组头部,其余元素向后移动 k mod n 个位置。
该方法为数组的翻转:我们可以先将所有元素翻转,这样尾部的 k mod n 个元素就被移至数组头部,然后我们再翻转 [0,k mod n−1] 区间的元素和 [k mod n,n−1] 区间的元素即能得到最后的答案。
defswap(self, nums: list): left = 0 L = len(nums) right = L - 1 while left < right: nums[left], nums[right] = nums[right], nums[left] left += 1 right -= 1 return nums
defrotate(self, nums: List[int], k: int) -> None: """ Do not return anything, modify nums in-place instead. """ # 整体反转、前k反转、后n-k反转 L = len(nums) nums = self.swap(nums) k = k % L nums[:k] = self.swap(nums[:k]) nums[k:] = self.swap(nums[k:])
L = len(nums) left = 0 right = L - 1 while left <= right: mid = (left + right) // 2 if nums[mid] < target: left = mid + 1 elif nums[mid] > target: right = mid - 1 else: return mid