Skip to content

Instantly share code, notes, and snippets.

@IngeFrodo
Created April 12, 2020 22:01
Show Gist options
  • Save IngeFrodo/676f30b8b8b83a7bcdf05ebc3b74fba2 to your computer and use it in GitHub Desktop.
Save IngeFrodo/676f30b8b8b83a7bcdf05ebc3b74fba2 to your computer and use it in GitHub Desktop.
class LastStoneWeight {
public int lastStoneWeight(int[] stones) {
if (stones == null || stones.length == 0) {
return 0;
}
PriorityQueue<Integer> stonesPQ = new PriorityQueue<>(stones.length, Comparator.reverseOrder());
for (int stone : stones) {
stonesPQ.offer(stone);
}
int lastStoneWeight;
while (stonesPQ.size() > 1) {
lastStoneWeight = stonesPQ.poll() - stonesPQ.poll();
if (lastStoneWeight != 0) {
stonesPQ.offer(lastStoneWeight);
}
}
return stonesPQ.isEmpty() ? 0 : stonesPQ.poll();
}
}
@IngeFrodo
Copy link
Author

This is a fastest solution because the input is size is <= 30 and after the first sort, the other sorts will be much faster because it will only have one element in wrong order:

class Solution {
public int lastStoneWeight(int[] stones) {
if (stones == null || stones.length == 0) {
return 0;
}
Arrays.sort(stones);
for (int i = stones.length - 1; i > 0; i--) {
stones[i - 1] = stones[i] - stones[i - 1];
Arrays.sort(stones);
}
return stones[0];
}
}

@munguial
Copy link

Nice approach. A few minor comments that I have:

  1. The if statement in line 3 is not needed. I have never seen a test case in Leetcode that tests what your code does for a null input, so you can assume (at least for Leetcode problems) that the input objects will be always non null. The case for when the array is empty is already covered by the logic at line 17.

  2. The lastStoneWeight variable can be initialized at the same time you assign the value in line 12. You won't access that variable outside of the while loop.

  3. In your comment above you mention that the solution you pasted is faster than the original one because the sort operation on the array is faster after the first sort since it only has to place one element in the right position. As per my understanding, that might be correct (although I am not entirely sure how it is implemented) because it seems like the Arrays.sort method is smart enough to apply a slightly faster algorithm depending on the characteristics of the input (in this case I think is the size of the input), although sorting the whole array (even with the fastest sorting algorithm) takes at least O(n) time, and given the fact that adding an element to the priority queue takes log(n) I don't see any scenario where I would prefer the second approach over the first one.
    If the comparison is made based on the execution times that Leetcode provides then that is not reliable, it depends on the test cases and hardware limitations, I am pretty sure that for larger inputs the first approach would perform a lot better than the second one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment