程序笔记   发布时间:2022-07-18  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了【Leetcode】- 排序系列大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

排序

912. 排序数组【中等】

给你一个整数数组 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题,怎么利用快速排序的方式进行类似问题的解答。

【Leetcode】- 排序系列

 

 

 

 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

 

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

方法一:用快排的方式来写的,这个一定要掌握

方法二:学习在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     

 

 

347. 前 K 个高频元素【中等】

给你一个整数数组 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,请注明来意。