Leetcode414. 第三大的数
题目:
给定一个非空数组,返回此数组中第三大的数。如果不存在,则返回数组中最大的数。要求算法时间复杂度必须是O(n)。
示例 1:
输入: [3, 2, 1]
输出: 1
解释: 第三大的数是 1.
示例 2:
输入: [1, 2]
输出: 2
解释: 第三大的数不存在, 所以返回最大的数 2 .
示例 3:
输入: [2, 2, 3, 1]
输出: 1
解释: 注意,要求返回第三大的数,是指第三大且唯一出现的数。
存在两个值为2的数,它们都排第二。
题解:
方案一:使用红黑树方式
红黑树简介:红黑树是一种平衡的二叉查找树,说他平衡的意思是他不会变成“瘸子”,左腿特别长或者右腿特别长。除了符合二叉查找树的特性之外,还具体下列的特性:
- 节点是红色或者黑色
- 根节点是黑色
- 每个叶子的节点都是黑色的空节点(NULL)
- 每个红色节点的两个子节点都是黑色的。
- 从任意节点到其每个叶子的所有路径都包含相同的黑色节点。
方案二:定义三个变量存第一、第二、第三大的值。
java代码:
public static int thirdMax2(int[] nums) {
int one = nums[0];
int two = Integer.MIN_VALUE;
int three = Integer.MIN_VALUE;
for (int i = 1; i < nums.length; i++) {
int now = nums[i];
if (now > one) {
three = two;
two = one;
one = now;
} else if (now > two) {
three = two;
two = now;
} else {
three = now;
}
}
if (three == Integer.MIN_VALUE) {
return one;
} else {
return three;
}
}
scala代码:
/**
* 使用红黑树进行操作
* 时间复杂度: O(n * log3) == O(n)
*
* @param nums
* @return
*/
def thirdMax(nums: Array[Int]): Int = {
val set = new java.util.TreeSet[Int]()
for (num <- nums) {
set.add(num)
if (set.size > 3) {
set.remove(set.first())
}
}
if (set.size < 3) {
set.last()
} else {
set.first()
}
}
/**
* 定义三个变量,存放第一、第二、第三大的值
*时间复杂度: O(n)
* @param nums
* @return
*/
def thirdMax2(nums: Array[Int]): Int = {
var result = 0
var one = nums(0)
var two = Long.MinValue
var three = Long.MinValue
for (i <- 1 until nums.length) {
val now = nums(i)
//退出本次循环
breakable {
if (now == one || now == two || now == three) {
println(now, "now ==========")
break
}
if (now > one) {
three = two
two = one
one = now
} else if (now > two) {
three = two
two = now
} else if (now > three) {
three = now
}
println(now, "********************")
}
}
if (three == Long.MinValue) {
result = one
} else {
result = three.toInt
}
result
}