数组中的第k个最大元素
215. 数组中的第K个最大元素 - 力扣(LeetCode)
(1)第k大的元素在排序数组中的位置是nums.length - k
。
假设我们有一个数组nums = [3, 2, 1, 5, 6, 4]
,并且我们想找到第2大的元素。
步骤 1:排序数组
首先,我们对数组进行排序:
排序后的数组: [1, 2, 3, 4, 5, 6]
步骤 2:理解第k大元素的位置
在排序后的数组中,第2大的元素是5
。它位于索引4的位置(从0开始计数)。
(2)快排的思路:
先分块,再递归。
单层递归思路:
左小右大:
先指定一个base(一般是第一个值)
右大:右指针从右向左遍历,若有值比base小,就把右指针和左指针的值交换
左小:左指针从左向右遍历,若有值比base大,就把左指针和右指针的值交换
当左右指针相遇时,把base放在这个相遇点.
class Solution {
//快排:
/*
分区,随便找一个中间值x,数组在x左边的值应该都<=x,在x右边的值应该都>=x
从子数组 a[l⋯r] 中选择任意一个元素 x 作为主元,调整子数组的元素使得左边的元素都小于等于它,右边的元素都大于等于它, (递归的思想)
x 的最终位置就是 第k大的元素。
*/
/*
快排:1.分区 2.递归找k
https://blog.csdn.net/qq_39181839/article/details/109478094
*/
public int findKthLargest(int[] nums, int k) {
//第k大元素在排序数组中的位置是nums.length - k
return quicksort(nums, 0, nums.length-1, nums.length - k);
}
public int quicksort(int[] nums, int left, int right, int k){
//递归终止条件
if (left >= right){
return nums[left];
}
//单层递归逻辑
int p = partition(nums, left, right);
if ( p==k){return nums[p];}
else if (p < k){
//需要在右侧分区继续查找
return quicksort(nums, p+1, right, k);
}
else {
// 需要在左侧分区继续查找
return quicksort(nums, left, p-1, k);
}
}
public int partition(int[] nums, int left, int right){
int base = nums[left];
while(left<right){
//从右往左
//一步步向左移,直到找到比base小的数停下来,替换此时🐻l所在位置的元素
while(left<right && base <=nums[right]){
right--;
}
nums[left] = nums[right];
//从左往右
while(left<right && base >=nums[left]){
left++;
}
nums[right] = nums[left];
}
//此时🐻l、🐻r指向同一元素
//base替换此元素
nums[left] = base;
return left;
}
}
前K个高频元素(py3)
# 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
# 示例 1:
# 输入: nums = [1,1,1,2,2,3], k = 2
# 输出: [1,2]
# 示例 2:
# 输入: nums = [1], k = 1
# 输出: [1]
import collections
class solution(object):
def topKFrequent(self, nums, k):
# 使用 collections.Counter 来统计 nums 中每个元素出现的次数。
# Counter 是一个字典,其中键是数组中的元素,值是该元素出现的次数。
# 例如,nums = [1, 1, 1, 2, 2, 3] 的 count 将会是 {1: 3, 2: 2, 3: 1}。
count = collections.Counter(nums)
result = []
# 使用 Counter 的 most_common 方法,该方法返回一个列表,包含 count 中出现频率最高的 k 个元素及其对应的频率。
# 例如,count.most_common(2) 返回 [(1, 3), (2, 2)],表示元素 1 出现了 3 次,元素 2 出现了 2 次。
for item in count.most_common(k):
result.append(item[0])
return result
nums1 = [1,1,1,2,2,3]
k1 = 2
res = solution().topKFrequent(nums1, k1)
print(res)
只出现一次的数字
也是用的collections.Counter
# 给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
# 你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。
# 示例 1 :
# 输入:nums = [2,2,1]
# 输出:1
# 示例 2 :
# 输入:nums = [4,1,2,1,2]
# 输出:4
# 示例 3 :
# 输入:nums = [1]
# 输出:1
import collections
from typing import List
class solution(object):
def singleNumber(self, nums):
count = collections.Counter(nums)
print(count)
for item in count.most_common(len(nums)):
if item[1] == 1:
return item[0]
# set(nums) 创建了一个集合,去除了 nums 中的重复元素。
# sum(set(nums)) 是所有唯一元素的和。
# sum(nums) 是列表中所有元素的和。
# 两倍的 sum(set(nums)) 减去 sum(nums) 就是只出现一次的那个元素,因为所有重复的元素会被两次减去,而唯一的元素只被一次减去。
def singleNumber2(self, nums):
res = sum(set(nums))*2 - sum(nums)
return res
nums = [2,2,1]
res1 = solution().singleNumber(nums)
print(res1)
res2 = solution().singleNumber2(nums)
print(res2)
多数元素
# 给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
# 你可以假设数组是非空的,并且给定的数组总是存在多数元素。
# 示例 1:
# 输入:nums = [3,2,3]
# 输出:3
# 示例 2:
# 输入:nums = [2,2,1,1,1,2,2]
# 输出:2
import collections
class solution(object):
def majorityElement(self, nums):
n = len(nums)
count = collections.Counter(nums)
res = []
for item in count.most_common(n):
if item[1] > n/2:
res.append(item[0])
return res
nums = [3,2,3]
res = solution().majorityElement(nums)
print(res)