大佬教程收集整理的这篇文章主要介绍了【Leetcode】- 排序系列,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
排序
给你一个整数数组 nums,请你将该数组升序排列。
示例 1:
输入:nums = [5,2,3,1]输出:[1,2,3,5]示例 2:
输入:nums = [5,1,1,2,0,0]输出:[0,0,1,1,2,5]
这道题很明显不只是写代码,还有就是对排序的理解和时间复杂度的掌握,重点复习了快速排序。
然后就是直接引入到215题,怎么利用快速排序的方式进行类似问题的解答。
1 class Solution: 2 def quickSort(self,nums, left,right): 3 #step1:partition操作:找到left-right范围的一个基准点,并保证基准点左边小于基准点,基准点右边大于基准点,并范围基准点位置povit 4 #step2:递归排序 left到povit的子数组 5 #step3:递归排序 povit到right的子数组 6 if left>=right: 7 return 8 povit = self.partition(nums,left,right) #注意:写的时候状态不好,这里写成0,n-1,一直超时 9 # print('povit:',povit) 10 # print('nums:',nums) 11 self.quickSort(nums,left, povit-1) 12 self.quickSort(nums,povit+1,right) 13 14 15 def partition(self,nums, left,right): 16 if left>=right: 17 return 18 p = random.randint(left,right) #注意:这里如果不是随机,对于已经已经排序好的数组时间会超时 19 # print('left:',left) 20 # print('right:',right) 21 # print('p:',p) 22 self.swap(nums,left,p) 23 24 povit = left #存储的是当前小于target的最后一个位置,当后续有小于target的位置的时候,那么就要向后移动一位,快拍这里我就记得这一种写法就新歌了 25 i = left+1 26 while i<=right: 27 if nums[i]<nums[left]: #这里就是找到了比target小的位置 28 povit+=1 29 self.swap(nums,povit,i) 30 i+=1 #注意:这里记得加1 31 self.swap(nums,povit,left) 32 return povit 33 34 35 def swap(self,nums,i,j): 36 # print('i:',i) 37 # print('j:',j) 38 tmp = nums[i] 39 nums[i] = nums[j] 40 nums[j] = tmp 41 42 def sortArray(self, nums: List[int]) -> List[int]: 43 #一定要重点掌握的快速排 44 if len(nums)<=1: 45 return nums 46 self.quickSort(nums,0,len(nums)-1) 47 return nums
在未排序的数组中找到第 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
方法一:用快排的方式来写的,这个一定要掌握
方法二:学习在python堆的调,优先队列有些麻烦,还是直接学heapq吧,跟我之前学习栈和队列的方式可以兼容
1 import heapq 2 from queue import PriorityQueue 3 class Solution: 4 def findKthLargest(self, nums: List[int], k: int) -> int: 5 #方法一:利用快速排序的方式,寻找第K个位置的元素就可以了,不用完全排序 6 # 时间复杂度:O(N),这里 NN 是数组的长度,理由可以参考本题解下用户 @ZLW 的评论,需要使用主定理进行分析。 7 # 空间复杂度:O(1),原地排序,没有借助额外的辅助空间。 8 9 # 作者:liweiwei1419 10 # 链接:https://leetcode-cn.com/problems/kth-largest-element-in-an-array/solution/partitionfen-er-zhi-zhi-you-xian-dui-lie-java-dai-/ 11 # 来源:力扣(LeetCode) 12 # 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 13 n = len(nums) 14 target = n-k 15 start = 0 16 end = n-1 17 while start<=end: #注意这个循环条件,因为早晚会return出去的,也可以改成while True: 不过这里我需要再想想 18 index = self.partition(nums,start,end) # 19 if index==target: 20 return nums[index] 21 elif target>index: 22 start = index+1 23 else: 24 end = index-1 25 26 27 def partition(self, nums, left,right): 28 if left==right: 29 return left 30 if right>left: 31 p = random.randint(left,right) 32 self.swap(nums,p,left) 33 # print('left:',left) 34 # print('right:',right) 35 povit = left 36 i = left+1 37 while i<=right: 38 if nums[i]<nums[left]: 39 povit+=1 40 self.swap(nums,i,povit) #这里要注意不要写错 41 i+=1 42 self.swap(nums,povit,left) 43 return povit 44 def swap(self,nums,i,j): 45 tmp = nums[i] 46 nums[i] = nums[j] 47 nums[j] = tmp 48 49 #方法二:堆排序,这个也是需要会的 50 #关于heapq的官方文档:https://docs.python.org/zh-cn/3/library/heapq.html 51 #主要是熟悉heapq.heappush heapq.heappop heapq.heapreplace就可以了 注意这事一个类包,对应的函数输入需要一个作为list使用的, 52 #关于这个解法的链接:https://leetcode-cn.com/problems/kth-largest-element-in-an-array/solution/partitionfen-er-zhi-zhi-you-xian-dui-lie-java-dai-/ 53 def findKthLargest(self, nums: List[int], k: int) -> int: 54 # step1: 使用容量为 k 的小顶堆 55 # step2: 元素个数小于 k 的时候,放进去就是了 56 # step3: 元素个数大于 k 的时候,小于等于堆顶元素,就扔掉,大于堆顶元素,就替换 57 n = len(nums) 58 h = [] 59 if n<k: 60 return None 61 for i in range(k): 62 heapq.heappush(h,nums[i]) 63 for i in range(k,n): 64 if nums[i]>h[0]: 65 heapq.heapreplace(h,nums[i]) 66 return h[0] 67 68 #堆竟然还有另外一种方式,这个更简单,但是时间复杂度会高一些,就是都加到堆中,然后判断size是不是大于k,如果是就把堆顶pop 69 70 n = len(nums) 71 h = [] 72 if n<k: 73 return None 74 for i in range(n): 75 heapq.heappush(h,nums[i]) 76 if len(h)>k: 77 heapq.heappop(h) 78 return h[0] 79 80 81 # #这里还有使用优先队列的方式,q = PriorityQueue()定义的方式,然后put是插入,然后get是删除最优先的,默认最小的,但是没有找到那种只查看最有效的数字,不出队列的方法,还是及heapq吧,这个感觉有些乱 82 n = len(nums) 83 h = [] 84 if n<k: 85 return None 86 q = PriorityQueue() #注意优先队列的实现方式 87 for i in range(n): 88 q.put(nums[i]) 89 if q.qsize()>k: # 90 q.get() # 91 return q.get() 92 93 94 95 96 97 98 99
给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2输出: [1,2]示例 2:
输入: nums = [1], k = 1输出: [1]
用python 写以后舒服多了,没有那么多语法需要记
三步走,记得语法结构
#时间复杂度:O(nlogk) #空间复杂度:O(n)
1 class Solution { 2 public int[] topKFrequent(int[] nums, int k) { 3 //方法一:也是容易想到的方法,就是使用堆排序,其实这个思路我是想到的,但是由于对小顶堆这种不太熟悉,所以我看了答案 4 //这道题对我来说,还是需要主要复习语法结构,太对语法结构了!!!一定要回来仔细看看, 5 //时间复杂度:O(nlogk) 空间复杂度O(n)=O(n)+O(k) 6 7 //第一步:遍历,且hash存储数字出现次数 8 int len = nums.length; 9 Map<Integer,Integer> occuMap = new HashMap<Integer,Integer>(); 10 for(int i=0;i<len;i++){ 11 occuMap.put(nums[i], occuMap.getOrDefault(nums[i],0)+1); 12 } 13 14 //第二步:建立小顶堆,每个顶点的元素存储的是一个长度为2的int数组,第一个元素是数字,第二个元素是数字出现的次数 15 PriorityQueue<int[]> queue = new PriorityQueue<int[]>( 16 //里面要记得写对比排序函数,这里的语法结构我之前是完全不知道该怎么写的!!!!!!! 17 new Comparator<int[]>(){ 18 public int compare(int[] m, int[] n){ 19 return m[1]-n[1]; 20 } 21 } 22 ); 23 24 //第三步:遍历hash表,然后更新堆结构;; 这里又有新的语法结构!!!哭了 25 for(Map.Entry<Integer,Integer> entry: occuMap.entrySet()){ //因为key和value都需要,所以用的这个结构 26 int num = entry.getKey(), count = entry.getValue(); 27 if(queue.size()==k){//注意这里的语法是size 28 if(queue.peek()[1]<count){ //取出堆顶 29 queue.poll(); //删除一个元素 30 queue.offer(new int[]{num,count}); //插入一个元素,,这里也注意语法结构 31 } 32 }else{ 33 queue.offer(new int[]{num,count}); //插入一个元素 34 } 35 36 } 37 38 //第4步:取出并返回结构 39 int[] ans = new int[k]; 40 for(int i=0;i<k;i++){ 41 ans[i] = queue.poll()[0]; 42 } 43 return ans; 44 45 46 47 //方法二:使用的是快速排序的思路,我没仔细看,有时间复习的时候可以再看 48 49 } 50 }
来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/kth-largest-element-in-an-array著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
以上是大佬教程为你收集整理的【Leetcode】- 排序系列全部内容,希望文章能够帮你解决【Leetcode】- 排序系列所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。