Leetcode_排序
题目来源于LeetCode,挑选来自CyC2018,记录自己的刷题过程
215. 数组中的第K个最大元素
在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
链接:https://leetcode-cn.com/problems/kth-largest-element-in-an-array/
解题思路
方法1:sort排序,输出n-k位
class Solution(object):
def findKthLargest(self, nums, k):
nums.sort()
return nums[len(nums)-k]
方法2:利用nlargest,输出倒数第k位
class Solution(object):
def findKthLargest(self, nums, k):
from heapq import nlargest
return nlargest(k,nums)[-1]
方法3:利用最大堆heap,heap是从小到大排列前k个最大,输出k[0]即可。
heappush(heap,a),把a放在heap中
heaprepalce(heap,b),把b替换掉heap中的最小位置。
class Solution(object):
def findKthLargest(self, nums, k):
from heapq import heappush,heapreplace
#最大堆
heap = []
for i in range(len(nums)):
if i < k:
heappush(heap,nums[i])
else:
if nums[i] > heap[0]:
heapreplace(heap,nums[i])
return heap[0]
347.前k个高频元素
给定一个非空的整数数组,返回其中出现频率前 k 高的元素。
链接:https://leetcode-cn.com/problems/top-k-frequent-elements/
解题思路
方法:堆
- collections库中的Counter函数用于统计字符出现个数,如:‘a’:2,表示a出现两次。讲解:https://www.liaoxuefeng.com/wiki/897692888725344/973805065315456
- lambda x:Jihe(x) 冒号前x表示键也就是上面的a,Jihe[x]表示输出的值,也就是上面的次数2。Jihe这个是随便取得名字
- 用heapq.nlargest(k,Jihe)输出集合中的第k个最大值
代码
class Solution(object):
def topKFrequent(self, nums, k):
from collections import Counter
from heapq import nlargest
Jihe = Counter(nums)
return heapq.nlargest(k,Jihe,key=lambda x:Jihe[x])
451.根据字符出现频率排序
给定一个字符串,请将字符串里的字符按照出现的频率降序排列。
链接:https://leetcode-cn.com/problems/sort-characters-by-frequency/
解题思路
- 用Counter统计出现次数,most_common函数将出现次数从大到小排序。
- 循环遍历加入列表a中,用join函数组合
代码
class Solution(object):
def frequencySort(self, s):
from collections import Counter
m = Counter(s).most_common()
a = []
for i,j in m:
a += i*j
return "".join(a)
75.颜色分类
- 给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
- 此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色
- 链接:https://leetcode-cn.com/problems/sort-colors
- 不能使用代码库中的排序函数来解决这道题。
解题思路
荷兰国旗包含三种颜色:红、白、蓝。
有三种颜色的球,算法的目标是将这三种球按颜色顺序正确地排列。它其实是三向切分快速排序的一种变种,在三向切分快速排序中,每次切分都将数组分成三个区间:小于切分元素、等于切分元素、大于切分元素,而该算法是将数组分成三个区间:等于红色、等于白色、等于蓝色。
三个指针p0,curr,p2
p0在头,p2在尾,cur指针移动用来找0&2
1.找到0,跟po的数交换,cur,p0往右移一位
2.找到2,根p2的数交换,curr不动,p2往左移一位
(从p2交换过来的数curr还未扫描,所以curr不++)
代码
class Solution(object):
def sortColors(self, nums):
p0,curr,p2=0,0,len(nums)-1
while curr<=p2:
if nums[curr] == 0:
nums[curr],nums[p0] = nums[p0],nums[curr]
p0 += 1
curr += 1
elif nums[curr] == 2:
nums[curr],nums[p2] = nums[p2],nums[curr]
p2 -= 1
else:
curr += 1
315. 计算右侧小于当前元素的个数
链接:https://leetcode-cn.com/problems/count-of-smaller-numbers-after-self
给定一个整数数组 nums,按要求返回一个新数组 counts。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。
example:
输入: [5,2,6,1]
输出: [2,1,1,0]
解释:
5 的右侧有 2 个更小的元素 (2 和 1).
2 的右侧仅有 1 个更小的元素 (1).
6 的右侧有 1 个更小的元素 (1).
1 的右侧有 0 个更小的元素.
解题思路
思路来源于:dglinxu
- 排序:sort对列表重排,index返回下标即为该数前有几个小于的数(index时间复杂度O(1)),因为nums本身无序,所以需要从重排列表中删除用过的数
- 时间复杂度:O(n),空间复杂度:O(n)
代码
class Solution(object):
def countSmaller(self, nums):
res = []
num = sorted(nums)
for x in nums:
t= num.index(x)
res.append(t)
del num[t]
return res