Leetcode 1046. 最后一块石头的重量
两种方法!加了详细的注释,方便日后复习,也希望能帮到其他小伙伴,如有错误,欢迎指正!
Java实现:
class Solution {
// 方法1:逻辑删除+寻找最大值法;时间击败100%
public int[] getMaxAndIndex(int[] stones){
// 该方法功能:输入一个数组,返回数组中的最大值及其索引构成的数组
int[] res = new int[2];
int tmp = 0;
int index = -1;
for (int i = 0; i < stones.length; i++){
if (res[0] < stones[i]){
res[0] = stones[i];
res[1] = i;
}
}
return res;
}
public int lastStoneWeight(int[] stones) {
// 记录当前石头剩余的总数
int n = stones.length;
// 当元素个数大于1就不断地遍历
while (n > 1){
// 获取最大值和索引,并将该索引的值置0,相当于逻辑删除,因为0一定是数组中最小的
int[] MaxAndIndex1 = getMaxAndIndex(stones);
int max1 = MaxAndIndex1[0];
stones[MaxAndIndex1[1]] = 0;
// 获取第二大的值及索引,并将该索引的值置0,相当于逻辑删除,因为0一定是数组中最小的
int[] MaxAndIndex2 = getMaxAndIndex(stones);
int max2 = MaxAndIndex2[0];
stones[MaxAndIndex2[1]] = 0;
// 如果两块石头一样重,两块都没了,就直接将石头的总数-2
if (max1 == max2){
n -= 2;
// 如果两块石头不一样重,那肯定第一块更重,直接添加一块新石头(重量为max1 - max2);
// 放在哪里都可以,这里放在了刚取出的第一块石头的位置
// 不要忘了这种情况因为加了一块石头,石头总数只需要-1即可
}else{
stones[MaxAndIndex1[1]] = max1 - max2;
n -= 1;
}
}
// 返回最大元素即可,如果没有元素了,那所有位置都是0,最大值刚好也是0,直接返回即可
return getMaxAndIndex(stones)[0];
}
// 方法2:大顶堆,直接可以用PriorityQueue,但是这种方式需要不断地排序,效率不算高
public int lastStoneWeight(int[] stones) {
// 大顶堆,生成一个最大堆,该数据结构会自动将堆排序;
// 我们传一个lambda表达式,使得堆中第一个元素为堆中的最大值,这样我们每次poll第一元素就是最大值
PriorityQueue<Integer> pd = new PriorityQueue<Integer>((a,b) -> { return b - a;});
for (int stone : stones){
pd.offer(stone);
}
// 当元素个数大于1就不断地取两块石头
while (pd.size() > 1){
// 取出最大的
int max1 = pd.poll();
// 取出第二大的
int max2 = pd.poll();
// 如果大于,那么就需要再补充一个两块石头重量的差值大小的石头
if (max1 > max2){
pd.offer(max1 - max2);
}
}
// 如果没有元素了就返回0,有就说明剩下的就是最后一块石头,直接返回即可
return pd.isEmpty() ? 0 : pd.poll();
}
}