中文题目
给定一个整数数组 nums
和一个整数 k
,请返回其中出现频率前 k
高的元素。可以按 任意顺序 返回答案。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2]
示例 2:
输入: nums = [1], k = 1 输出: [1]
提示:
1 <= nums.length <= 105
k
的取值范围是[1, 数组中不相同的元素的个数]
- 题目数据保证答案唯一,换句话说,数组中前
k
个高频元素的集合是唯一的
进阶:所设计算法的时间复杂度 必须 优于 O(n log n)
,其中 n
是数组大小。
注意:本题与主站 347 题相同:https://leetcode-cn.com/problems/top-k-frequent-elements/
通过代码
高赞题解
思路和心得:
(一)最小堆
1.维持一个容量为k的最小堆
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
num_freq = collections.Counter(nums)
minHeap = []
for x, f in num_freq.items():
if len(minHeap) == k:
if minHeap[0][0] < f:
heapq.heappop(minHeap)
heapq.heappush(minHeap, (f, x))
else:
heapq.heappush(minHeap, (f, x))
res = []
while minHeap:
f, x = heapq.heappop(minHeap)
res.append(x)
return res
class Solution
{
public:
struct cmp1
{
bool operator () (pair<int,int> & a, pair<int, int> & b)
{
return a.second > b.second;
}
};
vector<int> topKFrequent(vector<int>& nums, int k)
{
unordered_map<int, int> num_freq;
for (int x : nums)
num_freq[x] ++;
priority_queue<pair<int,int>, vector<pair<int,int>>, cmp1> minHeap;
for (auto [x, f] : num_freq)
{
if (minHeap.size() == k)
{
if (minHeap.top().second < f)
{
minHeap.pop();
minHeap.push({x, f});
}
}
else
{
minHeap.push({x, f});
}
}
vector<int> res;
while (!minHeap.empty())
{
auto [x, f] = minHeap.top(); minHeap.pop();
res.push_back(x);
}
return res;
}
};
class xf
{
public int x;
public int f;
xf(int x_, int f_)
{
x = x_;
f = f_;
}
}
class Solution
{
public int[] topKFrequent(int[] nums, int k)
{
Map<Integer, Integer> num_freq = new HashMap<>();
for (int x : nums)
num_freq.put(x, num_freq.getOrDefault(x, 0) + 1);
PriorityQueue<xf> minHeap = new PriorityQueue<>(new Comparator<xf>()
{
public int compare(xf a, xf b)
{
return a.f - b.f;
}
});
for (Map.Entry<Integer, Integer> entry : num_freq.entrySet())
{
int x = entry.getKey();
int f = entry.getValue();
if (minHeap.size() == k)
{
if (minHeap.peek().f < f)
{
minHeap.poll();
minHeap.offer(new xf(x, f));
}
}
else
{
minHeap.offer(new xf(x, f));
}
}
int [] res = new int [k];
for (int i = 0; i < k; i ++)
{
xf a = minHeap.poll();
res[i] = a.x;
}
return res;
}
}
c++ 自定义类,运算符重载,千万不要忘记 const!!!!!!!!
struct xf
{
int x;
int f;
xf(int x_, int f_)
{
x = x_;
f = f_;
}
//重载 < 运算符
bool operator <(const xf b) const
{
return f > b.f;
}
};
class Solution
{
public:
vector<int> topKFrequent(vector<int>& nums, int k)
{
unordered_map<int, int> num_freq;
for (int x : nums)
num_freq[x] ++;
priority_queue<xf> minHeap;
for (auto [x, f] : num_freq)
{
if ((int)minHeap.size() == k)
{
if (minHeap.top().f < f)
{
minHeap.pop();
minHeap.push( xf(x, f));
}
}
else
{
minHeap.push( xf(x, f));
}
}
vector<int> res;
while (!minHeap.empty())
{
xf a = minHeap.top(); minHeap.pop();
res.push_back(a.x);
}
return res;
}
};
(二)快排–分治
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
n = len(nums)
num_freq = collections.Counter(nums)
self.res = []
xfs = list(num_freq.items())
xfn = len(xfs)
self.quick_sort(xfs, 0, xfn - 1, k)
return self.res
#-------大于等于的都交换到左侧。快排的第三种写法
def quick_sort(self, xfs, l: int, r: int, k: int) -> None:
pivot_xf = xfs[l]
pivot_f = xfs[l][1]
idx = l
for i in range(l + 1, r + 1, 1):
if xfs[i][1] >= pivot_f:
idx += 1
xfs[idx], xfs[i] = xfs[i], xfs[idx]
xfs[l], xfs[idx] = xfs[idx], xfs[l]
if k == idx - l + 1:
for i in range(l, idx + 1):
self.res.append(xfs[i][0])
elif k < idx - l + 1:
self.quick_sort(xfs, l, idx - 1, k)
else:
for i in range(l, idx + 1):
self.res.append(xfs[i][0])
self.quick_sort(xfs, idx + 1, r, k - (idx - l + 1))
class Solution
{
public:
vector<pair<int, int>> xfs;
vector<int> res;
vector<int> topKFrequent(vector<int>& nums, int k)
{
unordered_map<int, int> num_freq;
for (int x : nums)
num_freq[x] ++;
for (auto xf: num_freq)
xfs.push_back(xf);
int xfn = xfs.size();
quick_sort(0, xfn -1, k);
return res;
}
void quick_sort(int l, int r, int k)
{
pair<int, int> pivot_xf = xfs[l];
int pivot_f = pivot_xf.second;
int idx = l;
for (int i = l + 1; i < r + 1; i ++)
{
if (pivot_f <= xfs[i].second)
{
idx ++;
swap(xfs[idx], xfs[i]);
}
}
swap(xfs[l], xfs[idx]);
if (k == idx - l + 1)
{
for (int i = l; i < idx + 1; i ++)
{
res.push_back(xfs[i].first);
}
}
else if (k < idx - l + 1)
{
quick_sort(l, idx - 1, k);
}
else
{
for (int i = l; i < idx + 1; i ++)
res.push_back(xfs[i].first);
quick_sort(idx + 1, r, k - (idx - l + 1));
}
}
};
class Node
{
int x;
int f;
Node(int x_, int f_)
{
x = x_;
f = f_;
}
}
class Solution
{
List<Node> xfs = new ArrayList<>();
int [] res;
int res_i = 0;
public int[] topKFrequent(int[] nums, int k)
{
res = new int [k];
Map<Integer, Integer> num_freq = new HashMap<>();
for (int x : nums)
num_freq.put(x, num_freq.getOrDefault(x, 0) + 1);
for (Map.Entry<Integer, Integer> entry : num_freq.entrySet())
{
int x = entry.getKey();
int f = entry.getValue();
xfs.add(new Node(x, f));
}
int xfn = xfs.size();
quick_sort(0, xfn - 1, k);
return res;
}
public void quick_sort(int l, int r, int k)
{
Node pivot_xf = xfs.get(l);
int pivot_f = pivot_xf.f;
int idx = l;
for (int i = l + 1; i < r + 1; i ++)
{
if (pivot_f <= xfs.get(i).f)
{
idx ++;
Node tmp = xfs.get(idx);
xfs.set(idx, xfs.get(i));
xfs.set(i, tmp);
}
}
Node tmp = xfs.get(idx);
xfs.set(idx, xfs.get(l));
xfs.set(l, tmp);
if (k == idx - l + 1)
{
for (int i = l; i < idx + 1; i ++)
res[res_i ++] = xfs.get(i).x;
}
else if (k < idx - l + 1)
{
quick_sort(l, idx - 1, k);
}
else
{
for (int i = l; i < idx + 1; i ++)
res[res_i ++] = xfs.get(i).x;
quick_sort(idx + 1, r, k - (idx - l + 1));
}
}
}
统计信息
通过次数 | 提交次数 | AC比率 |
---|---|---|
3656 | 5393 | 67.8% |
提交历史
提交时间 | 提交结果 | 执行时间 | 内存消耗 | 语言 |
---|