75. 分类颜色
给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
注意:
不能使用代码库中的排序函数来解决这道题。
示例:
输入: [2,0,2,1,1,0] 输出: [0,0,1,1,2,2]
进阶:
- 一个直观的解决方案是使用计数排序的两趟扫描算法。
首先,迭代计算出0、1 和 2 元素的个数,然后按照0、1、2的排序,重写当前数组。 - 你能想出一个仅使用常数空间的一趟扫描算法吗?
计数排序:
三路快排:
class Solution: def sortColors(self, nums): """ :type nums: List[int] :rtype: void Do not return anything, modify nums in-place instead. """ zero = 0 #nums[0:zero]=0统计0的个数 two = len(nums)#nums[two:n]=2统计2的个数 #nums[zero:two]=1 if two<1: pass i = 0 while i<two: if nums[i]<1: nums[zero],nums[i]=nums[i],nums[zero] zero+=1 i+=1 elif nums[i]>1: nums[i],nums[two-1]=nums[two-1],nums[i] two-=1 else: assert(nums[i]==1) i+=1
88. 合并两个有序数组
给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。
说明:
- 初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
- 你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:
输入: nums1 = [1,2,3,0,0,0], m = 3 nums2 = [2,5,6], n = 3 输出: [1,2,2,3,5,6]归并排序中的归并:
class Solution: def merge(self, nums1, m, nums2, n): """ :type nums1: List[int] :type m: int :type nums2: List[int] :type n: int :rtype: void Do not return anything, modify nums1 in-place instead. """ i,j,k=0,0,0 nums=nums1[:] while i<m and j<n: if nums[i]<=nums2[j]: nums1[k]=nums[i] i+=1 else: nums1[k]=nums2[j] j+=1 k+=1 while i<m: nums1[k]=nums[i] i+=1 k+=1 while j<n: nums1[k]=nums2[j] j+=1 k+=1
215. 数组中的第K个最大元素
在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
示例 1:
输入: [3,2,1,5,6,4] 和
k = 2
输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6] 和
k = 4
输出: 4
说明:
你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。
快排:O(n)时间复杂度
class Solution: def findKthLargest(self, nums, k): """ :type nums: List[int] :type k: int :rtype: int nums = sorted(nums,reverse=True) return nums[k-1] """ leftmark = 0 rightmark = len(nums) - 1 mid = nums[rightmark // 2] while leftmark <= rightmark: while (nums[leftmark] > mid): leftmark += 1 while (nums[rightmark] < mid): rightmark -= 1 if (leftmark <= rightmark): nums[leftmark], nums[rightmark] = nums[rightmark], nums[leftmark] leftmark += 1 rightmark -= 1 if (k - 1 <= rightmark): return self.findKthLargest(nums[: rightmark + 1], k) if (k - 1 >= leftmark): return self.findKthLargest(nums[leftmark :], k - leftmark) return nums[k - 1]