24.第三大数
一、题目
给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致
(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/intersection-of-two-arrays-ii
二、示例
示例①
输入:[3, 2, 1]
输出:1
解释:第三大的数是 1 。
示例②
输入:[1, 2]
输出:2
解释:第三大的数不存在, 所以返回最大的数 2 。
三、代码实现
方法一: 排序
//方法一:排序
public static int ThirdMaxBySort(int[] nums){
Arrays.sort(nums);
reverse(nums);
for (int i = 1, diff = 1; i < nums.length; ++i) {
if (nums[i] != nums[i - 1] && ++diff == 3) { // 此时 nums[i] 就是第三大的数
return nums[i];
}
}
return nums[0];
}
public static void reverse(int[] nums) {
int left = 0, right = nums.length - 1;
while (left < right) {
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
left++;
right--;
}
}
方法二:有序集合
//方法二 : 有序集合
public static int ThirdMaxByOrderedSet(int[] nums){
TreeSet<Integer> s = new TreeSet<Integer>();
for (int num : nums) {
s.add(num);
if (s.size() > 3) {
s.remove(s.first());
}
}
return s.size() == 3 ? s.first() : s.last();
}
方法三:一次集合
public static int ThirdMaxByTraversal(int[] nums){
long a = Long.MIN_VALUE, b = Long.MIN_VALUE, c = Long.MIN_VALUE;
for (long num : nums) {
if (num > a) {
c = b;
b = a;
a = num;
} else if (a > num && num > b) {
c = b;
b = num;
} else if (b > num && num > c) {
c = num;
}
}
return c == Long.MIN_VALUE ? (int) a : (int) c;
}
四、复杂度分析
排序
-
时间复杂度:O(nlogn),其中 n是数组nums 的长度。排序需要O(nlogn) 的时间。
-
空间复杂度:O(logn)。排序需要的栈空间为O(logn)。
有序集合
-
时间复杂度:O(n),其中 n是数组 nums 的长度。由于有序集合的大小至多为 3,插入和删除的时间复杂度可以视作是O(1) 的,因此时间复杂度为 O(n)。
-
空间复杂度:O(1)。
一次集合
- 时间复杂度:O(n),其中 nn 是数组nums的长度。
- 空间复杂度:O(1)。