Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【Day 86 】2021-12-04 - 1046.最后一块石头的重量 #105

Open
azl397985856 opened this issue Dec 3, 2021 · 76 comments
Open

【Day 86 】2021-12-04 - 1046.最后一块石头的重量 #105

azl397985856 opened this issue Dec 3, 2021 · 76 comments
Labels

Comments

@azl397985856
Copy link
Contributor

1046.最后一块石头的重量

入选理由

暂无

题目地址

https://leetcode-cn.com/problems/last-stone-weight/

前置知识

题目描述

有一堆石头每块石头的重量都是正整数每一回合从中选出两块 最重的 石头然后将它们一起粉碎假设石头的重量分别为 x  y x <= y那么粉碎的可能结果如下如果 x == y那么两块石头都会被完全粉碎如果 x != y那么重量为 x 的石头将会完全粉碎而重量为 y 的石头新重量为 y-x最后最多只会剩下一块石头返回此石头的重量如果没有石头剩下就返回 0。

 

示例输入:[2,7,4,1,8,1]
输出1
解释先选出 7  8得到 1所以数组转换为 [2,4,1,1,1],
再选出 2  4得到 2所以数组转换为 [2,1,1,1],
接着是 2  1得到 1所以数组转换为 [1,1,1],
最后选出 1  1得到 0最终数组转换为 [1],这就是最后剩下那块石头的重量。
 

提示1 <= stones.length <= 30
1 <= stones[i] <= 1000
@yanglr
Copy link

yanglr commented Dec 3, 2021

思路:

读完题, 发现是 top K问题的变形, 于是可以使用堆(优先队列) 求解。

首先特判一下, 如果原数组的size == 1, 可以直接取出数组的第一个元素返回即可。

否则, 将数组中的数都放进一个大顶堆pq中, 使用一个while循环, 只要pq的size >= 2, 就每次从top位置取出两个数 firstBig 和 secondBig:

  • 如果 firstBig = secondBig, 就继续
  • 如果 firstBig ≠ secondBig, 就把 first-second 这个值再压入p。

如果循环结束时, pq为空则返回0, 否则pq的顶部元素即为所求。

代码:

实现语言: C++

class Solution {
public:
    int lastStoneWeight(vector<int>& stones) {
        if (stones.size() == 1) return stones.front();
        priority_queue<int> pq;
        for (auto& s : stones)
            pq.push(s);
        while (pq.size() >= 2) /* 别漏了==的情况 */
        {
            int firstBig = pq.top();
            pq.pop();
            int secondBig = pq.top();
            pq.pop();
            if (firstBig != secondBig)
                pq.push(firstBig - secondBig);
        }
        return pq.empty() ? 0 : pq.top();
    }
};

复杂度分析

  • 时间复杂度: O(N logN)
  • 空间复杂度: O(N)

@joeytor
Copy link

joeytor commented Dec 3, 2021

思路

使用堆的方法

先构建一个最大堆

每次如果堆中元素多于两个, 那么取出堆顶的两个元素, 并计算 remain, 如果 remain 不为 0, 将 remain 加入堆中继续循环

最后返回 堆顶元素如果 h 中还有元素 (代表还有一个元素), 否则返回 0, 代表没有元素剩余

import heapq
class Solution:
    def lastStoneWeight(self, stones: List[int]) -> int:
        h = [-x for x in stones]
        heapq.heapify(h)
        while len(h) >= 2:
            s1 = heapq.heappop(h)
            s2 = heapq.heappop(h)
            remain = -s1 - (-s2)
            if remain != 0:
                heapq.heappush(h, -remain)
        return 0 if not h else -h[0]

复杂度

时间复杂度: O(nlogn) 每次从堆中取出元素需要 O(logn) 的时间, 一共需要进行 O(n) 次

空间复杂度: O(n) 堆的空间复杂度

@chenming-cao
Copy link

解题思路

堆。模拟整个流程。建立大顶堆,将所有石头放入堆中,如果堆中石头多于2个,则拿出最大的两个进行粉碎,直到最后剩小于2个石头为止。

代码

class Solution {
    public int lastStoneWeight(int[] stones) {
        PriorityQueue<Integer> heap = new PriorityQueue<>((a, b) -> b - a);
        // put stones into max-heap
        for (int stone : stones) {
            heap.offer(stone);
        }
        // simulate the smash process
        while (heap.size() >= 2) {
            int y = heap.poll();
            int x = heap.poll();
            if (x != y) {
                heap.offer(y - x);
            }
        }
        return heap.size() == 0 ? 0 : heap.poll();
    }
}

复杂度分析

  • 时间复杂度:O(nlogn)
  • 空间复杂度:O(n)

@biancaone
Copy link

    def lastStoneWeight(self, stones: List[int]) -> int:
        q = [-stone for stone in stones]
        heapq.heapify(q)
        while (len(q)) > 1:
            heapq.heappush(q, heapq.heappop(q) - heapq.heappop(q))
        return -q[0]

@chakochako
Copy link

class Solution:
    def lastStoneWeight(self, stones: List[int]) -> int:
        
        heap = [-stone for stone in stones]
        heapq.heapify(heap)

       
        while len(heap) > 1:
            x,y = heapq.heappop(heap),heapq.heappop(heap)
            if x != y:
                heapq.heappush(heap,x-y)

        if heap: return -heap[0]
        return 0

@ginnydyy
Copy link

ginnydyy commented Dec 3, 2021

Problem

https://leetcode.com/problems/last-stone-weight/

Note

  • heap

Solution

class Solution {
    public int lastStoneWeight(int[] stones) {
        if(stones == null || stones.length == 0){
            return 0;
        }
        
        int n = stones.length;
        PriorityQueue<Integer> q = new PriorityQueue<>(n, Collections.reverseOrder());
        
        for(int i = 0; i < stones.length; i++){
            q.offer(stones[i]);
        }
        
        while(q.size() > 1){
            int s1 = q.poll();
            int s2 = q.poll();
            if(s1 != s2){
                q.offer(s1 - s2);
            }
        }
        
        return q.isEmpty()? 0: q.poll();
    }
}

Complexity

  • T: O(nlogn). n is the length of stones array. O(logn) for each offer and poll operation, for n stones, it requires n operations. Overall O(nlogn).
  • S: O(n) for the priority queue.

@zhangzz2015
Copy link

思路

  • 题目的关键是能快速找到最大和次大的石头,另外要修改石头重量再重新排序,heap是比较适合的数据结构,使用大顶堆,每次推出最大和次大,把非0的difference再次放入heap。时间复杂度为O(n logn) 空间复杂度为 O(n)

关键点

代码

  • 语言支持:C++

C++ Code:

class Solution {
public:
    int lastStoneWeight(vector<int>& stones) {
        
        priority_queue<int, vector<int>> pq; 
        
        for(int i=0; i< stones.size(); i++)
        {
            pq.push(stones[i]); 
        }
        
        while(pq.size()>1)
        {
            int topNode1 = pq.top(); 
            pq.pop(); 
            int topNode2 = pq.top();
            pq.pop();             
            if(topNode1-topNode2>0)
                pq.push(topNode1-topNode2); 
        }
        
        return pq.size()? pq.top(): 0;
        
    }
};

@pophy
Copy link

pophy commented Dec 3, 2021

思路

  • PQ模拟

Java Code

    public int lastStoneWeight(int[] stones) {
        PriorityQueue<Integer> pq = new PriorityQueue<>((a,b) -> (b - a));
        for (int n : stones) {
            pq.add(n);
        }
        while (pq.size() > 1) {
            int stone1 = pq.poll();
            int stone2 = pq.poll();            
            if (stone1 != stone2) {
                pq.add(Math.abs(stone1 - stone2));
            }
        }
        return pq.isEmpty() ? 0 : pq.poll();
    }

时间&空间

  • 时间 O(nlog(n))
  • 空间 O(n)

@laofuWF
Copy link

laofuWF commented Dec 3, 2021

# use min heap
# time: O(NlogN)
# space: O(N)

import heapq

class Solution:
    def lastStoneWeight(self, stones: List[int]) -> int:
        if len(stones) == 1:
            return stones[0]
        # min heap
        heap = []
        for stone in stones:
            heapq.heappush(heap, -stone)
        
        while len(heap) > 1:
            candidate1 = -heapq.heappop(heap)
            candidate2 = -heapq.heappop(heap)
            
            if candidate1 == candidate2:
                if not heap: return 0
                continue
            left = abs(candidate1 - candidate2)
            heapq.heappush(heap, -left)
        
        return -heapq.heappop(heap)

@akxuan
Copy link

akxuan commented Dec 3, 2021

class Solution:
    def lastStoneWeight(self, stones: List[int]) -> int:
        stones.sort()
        
     
        while len(stones)> 1:
            a = stones.pop()
            b = stones.pop()
            stones.append(abs(a-b))
            stones.sort()
            
        
        if stones:
            return stones[0]
        else:
            return 0 
        

@Daniel-Zheng
Copy link

思路

堆。

代码(C++)

class Solution {
public:
    int lastStoneWeight(vector<int>& stones) {
        priority_queue<int> q;
        for (int s: stones) q.push(s);
        while (q.size() > 1) {
            int a = q.top();
            q.pop();
            int b = q.top();
            q.pop();
            if (a > b) q.push(a - b);
        }
        return q.empty() ? 0 : q.top();
    }
};

复杂度分析

  • 时间复杂度:O(NLogN)
  • 空间复杂度:O(N)

@mannnn6
Copy link

mannnn6 commented Dec 4, 2021

代码

class Solution {
    public int lastStoneWeight(int[] stones) {
        PriorityQueue<Integer> pq = new PriorityQueue<Integer>((a, b) -> b - a);
        for (int stone : stones) {
            pq.offer(stone);
        }

        while (pq.size() > 1) {
            int a = pq.poll();
            int b = pq.poll();
            if (a > b) {
                pq.offer(a - b);
            }
        }
        return pq.isEmpty() ? 0 : pq.poll();
    }
}

复杂度

时间复杂度:O(NLogN)
空间复杂度:O(N)

@LAGRANGIST
Copy link

class Solution {
public:
int lastStoneWeight(vector& stones) {
priority_queue q;
for (int s: stones) q.push(s);
while (q.size() > 1) {
int a = q.top();
q.pop();
int b = q.top();
q.pop();
if (a > b) q.push(a - b);
}
return q.empty() ? 0 : q.top();
}
};

@yan0327
Copy link

yan0327 commented Dec 4, 2021

type hp []int
func (h hp) Len() int{return len(h)}
func (h hp) Less(i,j int) bool{return h[i]>h[j]}
func (h hp) Swap(i,j int) {h[i],h[j] = h[j],h[i]}
func (h *hp) Push(x interface{}){
    *h = append(*h, x.(int))
}
func (h *hp) Pop() interface{}{
    out := *h
    x := out[len(out)-1]
    *h = out[:len(out)-1]
    return x
}

func lastStoneWeight(stones []int) int {
    h := &hp{}
    for i:=0;i<len(stones);i++{
        heap.Push(h,stones[i])
    }
    for h.Len() > 1{
        x := heap.Pop(h).(int)
        y := heap.Pop(h).(int)
        if x > y{
            heap.Push(h,x-y)
        }
    }
    if h.Len()>0{
        return heap.Pop(h).(int)
    }
    return 0
}

@ZacheryCao
Copy link

Idea

Heap

Code

class Solution:
    def lastStoneWeight(self, stones: List[int]) -> int:
        heap = []
        for i in stones:
            heapq.heappush(heap, -i)
        while len(heap) > 2:
            i, j = -heapq.heappop(heap), -heapq.heappop(heap)
            if i - j != 0:
                heapq.heappush(heap,-abs(i-j))
        if len(heap) > 1:
            return abs(heapq.heappop(heap) - heapq.heappop(heap))
        elif len(heap) == 1:
            return abs(heapq.heappop(heap))
        else:
            return 0

Complexity:

Time: O(N log N). Heap pop and heap push is O(log N). We need to go through all arrays for each simulation.
Space: O(N)

@yingliucreates
Copy link

link:

https://leetcode.com/problems/last-stone-weight/

代码 Javascript

function PriorityQueue() {
  this.heap = [null];
  this.insert = function (value) {
    this.heap.push(value);
    let currentNodeIdx = this.heap.length - 1;
    let currentNodeParentIdx = Math.floor(currentNodeIdx / 2);
    while (
      this.heap[currentNodeParentIdx] &&
      value > this.heap[currentNodeParentIdx]
    ) {
      let parent = this.heap[currentNodeParentIdx];
      this.heap[currentNodeParentIdx] = value;
      this.heap[currentNodeIdx] = parent;
      currentNodeIdx = currentNodeParentIdx;
      currentNodeParentIdx = Math.floor(currentNodeIdx / 2);
    }
  };

  this.remove = function () {
    if (this.heap.length < 3) {
      const toReturn = this.heap.pop();
      this.heap[0] = null;
      return toReturn;
    }
    const toRemove = this.heap[1];
    this.heap[1] = this.heap.pop();
    let currentIdx = 1;
    let [left, right] = [2 * currentIdx, 2 * currentIdx + 1];
    let currentChildIdx =
      this.heap[right] && this.heap[right] >= this.heap[left] ? right : left;
    while (
      this.heap[currentChildIdx] &&
      this.heap[currentIdx] < this.heap[currentChildIdx]
    ) {
      let currentNode = this.heap[currentIdx];
      let currentChildNode = this.heap[currentChildIdx];
      this.heap[currentChildIdx] = currentNode;
      this.heap[currentIdx] = currentChildNode;
      currentIdx = currentChildIdx;
      [left, right] = [2 * currentIdx, 2 * currentIdx + 1];
      currentChildIdx =
        this.heap[right] && this.heap[right] >= this.heap[left] ? right : left;
    }
    return toRemove;
  };
}

const lastStoneWeight = function (stones) {
  const pq = new PriorityQueue();
  for (let i = 0; i < stones.length; i++) {
    pq.insert(stones[i]);
  }
  while (pq.heap.length > 2) {
    let x = pq.remove();
    let y = pq.remove();
    if (x != y) {
      let max = Math.max(x, y);
      let min = Math.min(x, y);
      let z = max - min;
      pq.insert(z);
    }
  }
  return pq.remove();
};

@bingyingchu
Copy link

class Solution:
    import heapq
    def lastStoneWeight(self, stones: List[int]) -> int:
        heap = [stone * -1 for stone in stones]
        heapq.heapify(heap)

        while len(heap) > 1:
            big1 = abs(heapq.heappop(heap))
            big2 = abs(heapq.heappop(heap))
            heapq.heappush(heap, -(big1-big2))

        if len(heap) == 1:
            return abs(heapq.heappop(heap))

        return 0

Time/Space: O(n)

@okbug
Copy link

okbug commented Dec 4, 2021

var lastStoneWeight = function(stones) {
    while(stones.length > 1) {
        stones.sort((a, b) => a - b);
        let a = stones.pop();
        let b = stones.pop();
        if(a !== b) stones.push(a - b);
    }
    return stones[0] || 0
};

@user1689
Copy link

user1689 commented Dec 4, 2021

题目

https://leetcode-cn.com/problems/last-stone-weight/

思路

Heap

python3

class heapq:

    def __init__(self, descend = False):
        self.heap = []
        self.descend = descend
    
    def _swap(self, idx1, idx2):
        self.heap[idx1], self.heap[idx2] = self.heap[idx2], self.heap[idx1]
    
    def _smaller(self, lst, rst):
        return lst > rst if self.descend else lst < rst
    
    def _size(self):
        return len(self.heap)

    def _top(self):
        if self.heap:
            return self.heap[0]
        return None

    def _push(self, x):
        self.heap.append(x)
        self._sift_up(self._size() - 1)
    
    def _pop(self):
        tmp = self.heap[0]
        self._swap(0, self._size() - 1)
        self.heap.pop()
        self._sift_down(0)
        return tmp
    
    def _sift_up(self, idx):
        while (idx != 0):
            parentIdx = (idx - 1) // 2

            if (self._smaller(self.heap[parentIdx], self.heap[idx])):
                break
            
            self._swap(parentIdx, idx)
            
            idx = parentIdx

    def _sift_down(self, idx):
        while (idx*2+1 < self._size()):
            smallestIdx = idx
            leftIdx = idx*2+1
            rightIdx = idx*2+2

            if (self._smaller(self.heap[leftIdx], self.heap[idx])):
                smallestIdx = leftIdx
            
            if (rightIdx < self._size() and self._smaller(self.heap[rightIdx], self.heap[smallestIdx])):
                smallestIdx = rightIdx

            if (smallestIdx == idx):
                break
            
            self._swap(smallestIdx, idx)
            idx = smallestIdx

class Solution:
    def lastStoneWeight(self, stones: List[int]) -> int:
        heap = heapq(descend = True)
        for s in stones:
            heap._push(s)
        
        while(heap._size() > 1):
            y = heap._pop()
            x = heap._pop()
            if y != x:
                heap._push(y - x)
            
        if heap._size() >= 1:
            return heap._top()
        return 0
           

复杂度分析

  • time nlogn
  • space n

相关题目

  1. 待补充

@wenjialu
Copy link

wenjialu commented Dec 4, 2021

idea

由每次取出最重的石头比较,想到需要排序。
由插入删除的时间复杂度,想到堆。

code

class Solution:
    要从大顶堆里面选出最重的。小顶堆的话就没办法取出最大的了。所以加个负号,就能让绝对值最大的变堆顶。
    def lastStoneWeight(self, stones: List[int]) -> int:
        stones_heap = [-stone for stone in stones]
        heapq.heapify(stones_heap)
        # print(stones_heap)
        while len(stones_heap) >= 2:
            s1, s2 = heapq.heappop(stones_heap), heapq.heappop(stones_heap) #s1<s2
            # print(s1,s2)
            if s1 != s2:
               heapq.heappush(stones_heap, s1 - s2) # a - b < 0       
        return -stones_heap[-1] if stones_heap else 0 

complexity

time:O(NlogN)
space: O(N)

@Laurence-try
Copy link

思路

heap

代码

使用语言:Python3

import heapq
class Solution:
    def lastStoneWeight(self, stones: List[int]) -> int:
        for i in range(len(stones)):
            stones[i] *= -1
        heapq.heapify(stones)
        while len(stones) > 1:
            stone_1 = heapq.heappop(stones)
            stone_2 = heapq.heappop(stones)
            if stone_1 != stone_2:
                heapq.heappush(stones, stone_1 - stone_2)

        return -heapq.heappop(stones) if stones else 0

复杂度分析
时间复杂度:O(nlogn)
空间复杂度:O(n)

@kennyxcao
Copy link

1046. Last Stone Weight

Intuition

  • Heap

Code

/**
 * @param {number[]} stones
 * @return {number}
 */
const lastStoneWeight = function(stones) {
  const maxHeap = new BinaryHeap((c, p) => c < p);
  stones.forEach((stone) => maxHeap.push(stone));
  while (maxHeap.size() > 1) {
    const diff = maxHeap.pop() - maxHeap.pop();
    if (diff > 0) {
      maxHeap.push(diff);
    }
  }
  return maxHeap.size() ? maxHeap.pop() : 0;
};

Complexity Analysis

  • Time: O(nlogn)
  • Space: O(n)

@RocJeMaintiendrai
Copy link

代码

class Solution {
    public int lastStoneWeight(int[] stones) {
        Queue<Integer> queue = new PriorityQueue<>((a, b) -> b - a);
        for(int i = 0; i < stones.length; i++) {
            queue.offer(stones[i]);
        }
        while(queue.size() > 1) {
            int x = queue.poll();
            int y = queue.poll();
            int diff = Math.abs(x - y);
            if(diff != 0) {
                queue.offer(diff);
            }
        }
        if(queue.isEmpty()) return 0;
        return queue.peek();
    }
}

复杂度分析

时间复杂度

O(nlogn)

空间复杂度

O(n)

@Francis-xsc
Copy link

思路

优先队列

代码

class Solution {
public:
    int lastStoneWeight(vector<int>& stones) {
        priority_queue<int> q;
        for(int s:stones){
            q.push(s);
        }
        while(q.size()>1){
            int a=q.top();
            q.pop();
            int b=q.top();
            q.pop();
            if(a>b){
                q.push(a-b);
            }
        }
        return q.empty()?0:q.top();
    }
};

复杂度分析

  • 时间复杂度:O(NlogN),其中 N 为数组长度。
  • 空间复杂度:O(N)

@ai2095
Copy link

ai2095 commented Dec 4, 2021

1046. Last Stone Weight

https://leetcode.com/problems/last-stone-weight/

Topics

-Heap

思路

Heap

代码 Python

class Solution:
    def lastStoneWeight(self, stones: List[int]) -> int:
        q = [-e for e in stones]
        heapq.heapify(q)
        while len(q) > 1:
            x = heapq.heappop(q)
            y = heapq.heappop(q)
            heapq.heappush(q, -1 * abs(x-y))
        return -1 * q[0] if len(q) == 1 else 0

复杂度分析

时间复杂度: O(N*Log(N))

空间复杂度: O(N)

@ymkymk
Copy link

ymkymk commented Dec 4, 2021

class Solution {
public int lastStoneWeight(int[] stones) {
PriorityQueue pq = new PriorityQueue((a, b) -> b - a);
for (int stone : stones) {
pq.offer(stone);
}

    while (pq.size() > 1) {
        int a = pq.poll();
        int b = pq.poll();
        if (a > b) {
            pq.offer(a - b);
        }
    }
    return pq.isEmpty() ? 0 : pq.poll();
}

@tongxw
Copy link

tongxw commented Dec 4, 2021

思路

设置一个大顶堆,所有数字入堆,然后从堆内取出最大的两个数字,把它们的差再放入堆中,直到堆内剩下的数字少于2个。最后如果堆不为空就返回堆顶,否则返回0。

代码

class Solution {
    public int lastStoneWeight(int[] stones) {
        PriorityQueue<Integer> heap = new PriorityQueue<>((e1, e2) -> e2 - e1);
        for (int stone : stones) {
            heap.offer(stone);
        }
        
        while (heap.size() > 1) {
            int stone1 = heap.poll();
            int stone2 = heap.poll();
            if (stone1 != stone2) {
                heap.offer(stone1 - stone2);
            } 
        }
        
        return heap.isEmpty() ? 0 : heap.peek();
    }
}

TC: O(nlogn)
SC: O(n)

@kidexp
Copy link

kidexp commented Dec 4, 2021

thoughts

heap 把stones数组的值取反加入heap 然后pop 出两两比较 知道最后元素个数<=1

code

import heapq

class Solution:
    def lastStoneWeight(self, stones: List[int]) -> int:
        heap = []
        for stone in stones:
            heapq.heappush(heap, -stone)
        while len(heap) > 1:
            x, y = heapq.heappop(heap), heapq.heappop(heap)
            if x == y:
                continue
            else:
                heapq.heappush(heap, x-y)
        return -heap[0] if heap else 0

complexity

Time O(nlgn)

Space O(n)

@chen445
Copy link

chen445 commented Dec 4, 2021

代码

class Solution:
    def lastStoneWeight(self, stones: List[int]) -> int:
        new_stones=[-1*stone for stone in stones]
        heapq.heapify(new_stones)
        while len(new_stones) >1:
            y=heapq.heappop(new_stones)
            x=heapq.heappop(new_stones)
            if y !=x:
                heapq.heappush(new_stones,y-x)
        if new_stones:
            return -new_stones[0]
        else:
            return 0

复杂度

Time: O(nlogn)

Space: O(n)

@JinhMa
Copy link

JinhMa commented Dec 4, 2021

class Solution {
public int lastStoneWeight(int[] stones) {
if (stones.length == 2) {
return Math.abs(stones[0] - stones[1]);
}
if (stones.length == 1) {
return stones[0];
}
Arrays.sort(stones);
if (stones[stones.length - 3] == 0) {
return stones[stones.length - 1] - stones[stones.length - 2];
}
stones[stones.length - 1] = stones[stones.length - 1] - stones[stones.length - 2];
stones[stones.length - 2] = 0;
return lastStoneWeight(stones);
}
}

@L-SUI
Copy link

L-SUI commented Dec 4, 2021

/**

  • @param {number[]} stones
  • @return {number}
    */
    var lastStoneWeight = function(stones) {
    if (stones.length == 1) { // 如果数组长度为 1 直接返回
    return stones[0];
    }
    while (stones.length > 1) { // 数组长度大于 1,循环
    let nowMaxNum = Math.max(...stones) // 获取当前数组最大值
    let maxNumIndex = stones.indexOf(nowMaxNum) // 获取最大值的索引
    stones.splice(maxNumIndex, 1) // 删除最大值
    let secondMaxNum = Math.max(...stones) // 继续获取数组最大值,这时候对于这轮来说是第二大的值
    let secondNumIndex = stones.indexOf(secondMaxNum) // 获取索引
    let reduceValue = nowMaxNum - secondMaxNum // 求差
    if (reduceValue > 0) { // 如果差值大于0,则删除当前最大值,并且插入插值
    stones.splice(secondNumIndex, 1, reduceValue)
    } else { // 否者删除当前最大值
    stones.splice(secondNumIndex, 1)
    }
    }
    return stones.length ? stones[0] : 0
    };

@wangyifan2018
Copy link

class Solution:
    def lastStoneWeight(self, stones: List[int]) -> int:
        heap = [-stone for stone in stones]
        heapq.heapify(heap)
        while len(heap) > 1:
            x, y = heapq.heappop(heap), heapq.heappop(heap)
            if x != y:
                heapq.heappush(heap, x - y)
        if heap: return -heap[0]
        return 0

@RonghuanYou
Copy link

class Solution:
    def lastStoneWeight(self, stones: List[int]) -> int:
        h = [-stone for stone in stones]
        heapq.heapify(h)

        while len(h) > 1:
            a, b = heapq.heappop(h), heapq.heappop(h)
            if a != b:
                heapq.heappush(h, a - b)
        return -h[0] if h else 0

@yibenxiao
Copy link

【Day 86】1046.最后一块石头的重量

代码

class Solution {
public:
    int lastStoneWeight(vector<int>& stones) {
        priority_queue<int> q;
        for (int s: stones) {
            q.push(s);
        }

        while (q.size() > 1) {
            int a = q.top();
            q.pop();
            int b = q.top();
            q.pop();
            if (a > b) {
                q.push(a - b);
            }
        }
        return q.empty() ? 0 : q.top();
    }
};

复杂度

时间复杂度:O(NLogN)

空间复杂度:O(N)

@HWFrankFung
Copy link

Codes

var lastStoneWeight = function(stones) {
    stones.sort((a, b) => a - b);    
    if (stones.length < 2) {
        return stones[0];
    }
    while (stones.length) {
       let len = stones.length;
       let a = stones[len - 1], b = stones[len - 2];
        stones.pop();
        stones.pop();
       if (a !== b) {
           let j = 1;
           if (!stones.length) {
              return a - b;
           }
           while (j <= stones.length) {      
               if (a - b <= stones[0]) {
                   stones.unshift(a - b);
                   break;
               }
               if (a - b >= stones[stones.length - 1]) {
                   stones.push(a - b);
                   break;
               }
               if (a - b >= stones[j - 1] && a - b <= stones[j]) {
                   stones.splice(j, 0, a - b);
                   break;
               }
               j++;
           }
       }
       if (stones.length === 1) {
           return stones[0];
       }
    }
    return 0;
};

@Zhang6260
Copy link

JAVA版本

思路:

直接使用堆来完成的,【扩展可以自己手动构建堆。。。】

class Solution {
    public int lastStoneWeight(int[] stones) {
        //这道题 使用  优先队列 是比较简单的。
        PriorityQueue<Integer> queue=new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                //降序
                return o2-o1;
            }
        });
        for(int i=0;i<stones.length;i++){
            queue.offer(stones[i]);
        }
        while(queue.size()>=2){
            int i=queue.poll();
            int j=queue.poll();
            if(i!=j){
                queue.offer(i-j);
            }
        }
        if(queue.size()==1)return queue.peek();
        else  return 0;
    }
}

时间复杂度:O(nlogn)

空间复杂度:O(n)

@mokrs
Copy link

mokrs commented Dec 4, 2021

int lastStoneWeight(vector<int>& stones) {
    priority_queue<int> q(stones.begin(), stones.end());

    while (q.size() > 1){
        int stone1 = q.top();
        q.pop();
        int stone2 = q.top();
        q.pop();

        if (stone1 != stone2){
            q.push(stone1 - stone2);
        }
    }

    if (q.size() == 1){
        return q.top();
    }
    else{
        return 0;
    }
}

@guangsizhongbin
Copy link

guangsizhongbin commented Dec 4, 2021

func lastStoneWeight(stones []int) int {
    var l int
    l = len(stones)
    if l == 0 {
        return 0
    }

    
    for ; l > 1; l = len(stones) {
        sort.Ints(stones)

        x := stones[l-2]
        y := stones[l-1]
        if x == y {
            stones = stones[0:l-2]
        } else {
            stones = append(stones[0:l-2], y-x)
        }

    }

    result := 0
    if len(stones) > 0 {
        result = stones[0]
    }
    return result

}

@Shinnost
Copy link

Shinnost commented Dec 4, 2021

class Solution {
public:
    int lastStoneWeight(vector<int>& stones) {
        priority_queue<int> q;
        for (int s: stones) {
            q.push(s);
        }

        while (q.size() > 1) {
            int a = q.top();
            q.pop();
            int b = q.top();
            q.pop();
            if (a > b) {
                q.push(a - b);
            }
        }
        return q.empty() ? 0 : q.top();
    }
};

@carterrr
Copy link

carterrr commented Dec 4, 2021

class Solution {
    public int lastStoneWeight(int[] stones) {
        MaxHeap maxHeap = new MaxHeap(stones);
        while(maxHeap.size() > 1) {
            int y = maxHeap.poll();
            int x = maxHeap.poll();
            if(y > x) {
                maxHeap.push(y - x);
            }
        }
        return maxHeap.size() == 1 ? maxHeap.poll() : 0;
    }

    private class MaxHeap{
        final int[] data;
        int tail;
        public MaxHeap(int[] data) {
            this.data = data;
            this.tail = data.length - 1;
            buildHeap();
        }

        private void heapify(int i) {
            int r = (i + 1) << 1;
            int l = r - 1;
            int max = i;
            if(r <= tail && data[max] < data[r]) max = r;
            if(l <= tail && data[max] < data[l]) max = l;
            if(max == i) return;
            swap(max, i);
            heapify(max);
        }

        private void buildHeap() {
            for(int i = ((this.tail + 1) >> 1) - 1; i >= 0; i--){
                heapify(i);
            }
        }

        private void swap(int p, int q) {
            int temp = data[p];
            data[p] = data[q];
            data[q] = temp;
        }

        public void push(int i) {
            data[++tail] = i;
            buildHeap();
        }

        public int poll() {
            int root = data[0];
            data[0] = data[tail--];
            heapify(0);
            return root;
        }

        public int size() {
            return tail + 1;
        }
    }
}

@xinhaoyi
Copy link

xinhaoyi commented Dec 4, 2021

class Solution {
public int lastStoneWeight(int[] stones) {
/* 使用优先对列保证每次能拿到最大的数 */
Queue queue = new PriorityQueue<>(new Comparator() {
@OverRide
public int compare(Integer o1, Integer o2) {
return (o2 - o1);
}
});
for (int i = 0; i < stones.length; i++) {
queue.offer(stones[i]);
}
while(queue.size() > 1) {
int x = queue.poll();
int y = queue.poll();
int diff = Math.abs(x - y);
if (diff != 0) {
queue.offer(diff);
}
}
if (queue.isEmpty()) return 0;
return queue.peek();
}
}

@KennethAlgol
Copy link

class Solution {
    public int lastStoneWeight(int[] stones) {
        PriorityQueue<Integer> pq = new PriorityQueue<Integer>((a, b) -> b - a);
        for (int stone : stones) {
            pq.offer(stone);
        }

        while (pq.size() > 1) {
            int a = pq.poll();
            int b = pq.poll();
            if (a > b) {
                pq.offer(a - b);
            }
        }
        return pq.isEmpty() ? 0 : pq.poll();
    }
}

@ysy0707
Copy link

ysy0707 commented Dec 4, 2021

class Solution {
    public int lastStoneWeight(int[] stones) {
        //利用优先队列生成一个大顶堆,需要重写,因为默认是小顶堆
        PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>((o1, o2) -> o2 - o1);
        for(int stone: stones){
            maxHeap.offer(stone);
        }
        while(maxHeap.size() > 1){
            int a = maxHeap.poll();
            int b = maxHeap.poll();
            if(a > b){
                maxHeap.offer(a - b);
            }
        }
    //队列如果是空的就返回0,不空就返回队顶
    return maxHeap.isEmpty()? 0: maxHeap.peek();
    }
}

时间复杂度:O(NlogN)
空间复杂度:O(N)

@ChenJingjing85
Copy link

class Solution:
    def lastStoneWeight(self, stones: List[int]) -> int:
        heap_max = []
        for stone in stones:
            heapq.heappush(heap_max, -stone)
        while len(heap_max) > 1:
            top1 = heapq.heappop(heap_max)
            top2 = heapq.heappop(heap_max)
            left = abs(top1-top2)
            if left > 0:
                heapq.heappush(heap_max, -left)
        if len(heap_max) > 0:
            return -heapq.heappop(heap_max)
        return 0
  • 时间 logN
  • 空间 logN

@biscuit279
Copy link

import heapq
class Solution:
    def lastStoneWeight(self, stones: List[int]) -> int:
        h = [-stone for stone in stones]
        heapq.heapify(h)

        while len(h) > 1:
            a, b = heapq.heappop(h), heapq.heappop(h)
            if a != b:
                heapq.heappush(h, a - b)
        return -h[0] if h else 0

时间复杂度:O(NlogN)
空间复杂度:O(N)

@shawncvv
Copy link

shawncvv commented Dec 4, 2021

思路

代码

JavaScript Code

var lastStoneWeight = function (stones) {
  const pq = new MaxPriorityQueue();
  for (const stone of stones) {
    pq.enqueue("x", stone);
  }

  while (pq.size() > 1) {
    const a = pq.dequeue()["priority"];
    const b = pq.dequeue()["priority"];
    if (a > b) {
      pq.enqueue("x", a - b);
    }
  }
  return pq.isEmpty() ? 0 : pq.dequeue()["priority"];
};

复杂度

令石头个数为 N

  • 时间复杂度:O(NlogN)
  • 空间复杂度:O(N)

@machuangmr
Copy link

代码

class Solution {
    public int lastStoneWeight(int[] stones) {
        PriorityQueue<Integer> pq = new PriorityQueue<Integer>((a, b) -> b - a);
        for (int stone : stones) {
            pq.offer(stone);
        }

        while (pq.size() > 1) {
            int a = pq.poll();
            int b = pq.poll();
            if (a > b) {
                pq.offer(a - b);
            }
        }
        return pq.isEmpty() ? 0 : pq.poll();
    }
}

复杂度

  • 时间复杂度 O(nlogn)
  • 空间复杂度 O(n)

@BpointA
Copy link

BpointA commented Dec 4, 2021

思路

直接模拟

Python代码

class Solution:
    def lastStoneWeight(self, stones: List[int]) -> int:
        stones.sort()
        while len(stones)>0:
            if len(stones)==1:
                return stones[0]
            elif stones[-1]==stones[-2]:
                stones.pop()
                stones.pop()
            else:
                y=stones.pop()
                x=stones.pop()
                stones.append(y-x)
                stones.sort()
        return 0

@HouHao1998
Copy link

class Solution {
    public int lastStoneWeight(int[] stones) {
        PriorityQueue<Integer> pq = new PriorityQueue<Integer>((a, b) -> b - a);
        for (int stone : stones) {
            pq.offer(stone);
        }

        while (pq.size() > 1) {
            int a = pq.poll();
            int b = pq.poll();
            if (a > b) {
                pq.offer(a - b);
            }
        }
        return pq.isEmpty() ? 0 : pq.poll();
    }
}

@liudi9047
Copy link

class Solution {
public int lastStoneWeight(int[] stones) {
PriorityQueue pq = new PriorityQueue((a, b) -> b - a);
for (int stone : stones) {
pq.offer(stone);
}

    while (pq.size() > 1) {
        int a = pq.poll();
        int b = pq.poll();
        if (a > b) {
            pq.offer(a - b);
        }
    }
    return pq.isEmpty() ? 0 : pq.poll();
}

}

@yj9676
Copy link

yj9676 commented Dec 4, 2021

class Solution {
    public int lastStoneWeight(int[] stones) {
        PriorityQueue<Integer> pq = new PriorityQueue<Integer>((a, b) -> b - a);
        for (int stone : stones) {
            pq.offer(stone);
        }

        while (pq.size() > 1) {
            int a = pq.poll();
            int b = pq.poll();
            if (a > b) {
                pq.offer(a - b);
            }
        }
        return pq.isEmpty() ? 0 : pq.poll();
    }
}

@Richard-LYF
Copy link

class Solution:
def lastStoneWeight(self, stones: List[int]) -> int:
h = [-stone for stone in stones]
heapq.heapify(h)

    while len(h) > 1:
        a, b = heapq.heappop(h), heapq.heappop(h)
        if a != b:
            heapq.heappush(h, a - b)

    return -h[0] if h else 0

@for123s
Copy link

for123s commented Dec 4, 2021

代码

  • 语言支持:C++

C++ Code:

class Solution {
public:
    int lastStoneWeight(vector<int>& stones) {
        priority_queue<int> q;
        for(int i=0;i<stones.size();++i)
            q.push(stones[i]);
        int a, b;
        while(q.size()>1)
        {
            a = q.top();
            q.pop();
            b = q.top();
            q.pop();
            q.push(a-b);
        }
        return q.top();
    }
};

@joriscai
Copy link

joriscai commented Dec 4, 2021

思路

  • 先排序,再从中选出两个最大的进行粉碎操作
  • 将粉碎结果保存,重新排序重新操作直至只有最后一个

代码

javascript

/*
 * @lc app=leetcode.cn id=1046 lang=javascript
 *
 * [1046] 最后一块石头的重量
 */

// @lc code=start
/**
 * @param {number[]} stones
 * @return {number}
 */
var lastStoneWeight = function(stones) {
  let curr = stones.length - 1
  while (curr > 0) {
    stones.sort((a, b) => a - b)
    stones[curr - 1] = stones[curr] - stones[curr - 1]
    curr--
  }
  return stones[0]
};
// @lc code=end

复杂度分析

  • 时间复杂度:O(n * nlogn),每次排序为nlogn,进行了n次
  • 空间复杂度:O(1)

@revisegoal
Copy link

Note

优先队列,大顶堆

Code

class Solution {
    public int lastStoneWeight(int[] stones) {
        PriorityQueue<Integer> q = new PriorityQueue<>((a, b) -> 
            ((Integer)b - (Integer)a));
        int n = stones.length;
        for (int i = 0; i < n; i++) {
            q.add(stones[i]);
        }
        while (q.size() > 1) {
            int x = q.remove();
            if (q.size() < 1) {
                break;
            }
            int y = q.remove();
            if (x > y) {
                q.add(x - y);
            } else if (x < y) {
                q.add(y - x);
            }
        }
        if (q.size() == 0) {
            return 0;
        }
        return q.peek();
    }
}

Complexity

  • time:O(nlogn)
  • space:O(n)

@thinkfurther
Copy link

class Solution:
    def lastStoneWeight(self, stones: List[int]) -> int:
        h = []
        for item in stones:
            heapq.heappush(h, -item)
            
        while(len(h) > 1):
            item1 = -heapq.heappop(h)
            item2 = -heapq.heappop(h)
            remaining = item1 - item2
            if remaining > 0:
                heapq.heappush(h, -remaining)
        
        if len(h) == 1:
            return -h[0]
        else:
            return 0

@shixinlovey1314
Copy link

Title:1046. Last Stone Weight

Question Reference LeetCode

Solution

Code

class Solution {
public:
    void swap(int& x, int& y) {
        if (x != y) {
            x ^= y;
            y ^= x;
            x ^= y;
        }
    }
    
    int getMaxChildIndex(vector<int>& heap, int index) {
        int l = index * 2;
        int r = index * 2 + 1;
        
        if (r > heap[0] || heap[l] > heap[r])
            return l;
        
        return r;
    }
    
    void bottom_up(vector<int>& heap, int index) {        
        while (index > 1 && heap[index] > heap[index / 2]) {
            swap(heap[index], heap[index / 2]);
            index = index / 2;
        }
    }
    
    void top_down(vector<int>& heap, int index) {
        int n = heap[0];
        
        while (index <= n/2) {
            int mc = getMaxChildIndex(heap, index);
            if (heap[index] >= heap[mc])
                break;
            
            swap(heap[index], heap[mc]);
            index = mc;
        }
    }
    
    void heapify(vector<int>& heap) {
        int n = heap[0];
        
        for (int i = n / 2; i >= 1; i--) {
            top_down(heap, i);
        }
    }
    
    int heap_pop(vector<int>& heap) {
        int max_val = heap[1];
        int n = heap[0];
        
        swap(heap[1], heap[n]);
        heap[0]--;
        
        top_down(heap, 1);
        
        return max_val;
    }
    
    void heap_push(vector<int>& heap, int v) {
        int n = heap[0];
        heap[n + 1] = v;
        heap[0]++;
        
        bottom_up(heap, n + 1);
    }
    
    int lastStoneWeight(vector<int>& stones) {
        vector<int> heap(stones.size() + 1, 0);
        heap[0] = stones.size();
        
        for (int i = 0; i < stones.size(); i++) 
            heap[i + 1] = stones[i];
        
        heapify(heap);
        
        while(heap[0] > 1) {
            int y = heap_pop(heap);
            int x = heap_pop(heap);
            
            if (x != y) {
                heap_push(heap, y - x);
            }
        }
        
        return heap[0] == 0? 0 : heap[1];
    }
};

Complexity

Time Complexity and Explanation

O(n*logn)

Space Complexity and Explanation

O(n)

@skinnyh
Copy link

skinnyh commented Dec 4, 2021

Note

  • Each turn we need to pick the heaviest stones and the result of smash need to be considered to the next turn. So it's finding the largest in rolling basis and think of using a max priority queue.
  • In python, we store the reversed sign elements to get the max heap.

Solution

class Solution:
    def lastStoneWeight(self, stones: List[int]) -> int:
        heap = []
        for s in stones:
            heapq.heappush(heap, -s)
        while len(heap) > 1:
            tmp = -heapq.heappop(heap) + heapq.heappop(heap)
            if tmp:
                heapq.heappush(heap, -tmp)
        return -heap[0] if heap else 0

Time complexity: O(NlogN)

Space complexity: O(N)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests