Leetcode 30 challenge Last Stone Weight Inspiration

take a lool at your original solution, it’s pretty bad with time complexity of O(n^2logn). and the wrost time complexity of the solution provided by leetcode is O(n2).
take a look at your code and you will find out you sort your shrinked array each time is the waste of time. instead, you did not realize that arraylist can also sorted using collection. just because you are not familiar with it. and also, you don’t have to sort the arraylist each time. as it shows in solution 1, we can just swap the largest one with the end of array, because remove the last index of arraylist only takes O(1)
however, we are here to disscussion solution 3, which uses heaps.
as you can see in solution1, we removed the maximum stone in O(N) each time, because collection.max() takes O(n). abd we add anew stone in O(1) [because we just put it at last positon, we don’t need to sort]
in solution 2, we find and remove the maxstone takes O(nlogn) time, add a new stone(which using binary search) uses O(logn).
but can we lower all those prices? space time trade off, so…max/minheap, which will make remove and add in both O(logn) time and find in O(1) time.
and the implement will be easy as hell:

class Solution {
    
    public int lastStoneWeight(int[] stones) {
        
        // Insert all the stones into a Max-Heap.
        PriorityQueue<Integer> heap = new PriorityQueue<>(Comparator.reverseOrder());
        for (int stone: stones) {//contrcut heap will takes O(n) instead of O(nlogn)
            heap.add(stone);//
        }

        // While there is more than one stone left, we need to remove the two largest
        // and smash them together. If there is a resulting stone, we need to put into
        // the heap.
        while (heap.size() > 1) { //n
            int stone1 = heap.remove();//logn
            int stone2 = heap.remove();//logn
            if (stone1 != stone2) {
                heap.add(stone1 - stone2);//logn
            }
        }

        // Check whether or not there is a stone left to return.
        return heap.isEmpty() ? 0 : heap.remove();
    }
}

solution 4 is bucket sort:
which is also use space and time trade off
and it will low the sort part into O(N) and we also need to loop through the whole buckets. so the time complxity will be O(N + W)

class Solution {
    
    public int lastStoneWeight(int[] stones) {
        
        // Set up the bucket array.
        int maxWeight = stones[0];
        for (int stone: stones) {
            maxWeight = Math.max(maxWeight, stone);
        }
        int[] buckets = new int[maxWeight + 1];

        // Bucket sort.
        for (int weight : stones) {
            buckets[weight]++;
        }

        // Scan through the buckets.
        int biggestWeight = 0;
        int currentWeight = maxWeight;
        while (currentWeight > 0) {
            if (buckets[currentWeight] == 0) {
                currentWeight--;
            } else if (biggestWeight == 0) {
                buckets[currentWeight] %= 2;
                if (buckets[currentWeight] == 1) {
                    biggestWeight = currentWeight;
                }
                currentWeight--;
            } else {
                buckets[currentWeight]--;
                if (biggestWeight - currentWeight <= currentWeight) {
                    buckets[biggestWeight - currentWeight]++;
                    biggestWeight = 0;
                } else {
                    biggestWeight -= currentWeight;
                }
            }
        }
        return biggestWeight;
    }
}
posted @ 2020-04-12 23:51  EvanMeetTheWorld  阅读(23)  评论(0)    收藏  举报