【LEETCODE】67、分治遞歸,medium&hard級別,題目:215、312

我被這些題整哭了,你呢???

日了狗啊。。。。。。

好難啊。。。。

按照這個樣子搞,不用找工作了,回家放牛去。。。。。。。

package y2019.Algorithm.divideandconquer.medium;

/**
 * @ProjectName: cutter-point
 * @Package: y2019.Algorithm.divideandconquer.medium
 * @ClassName: FindKthLargest
 * @Author: xiaof
 * @Description: 215. Kth Largest Element in an Array
 * Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order,
 * not the kth distinct element.
 *
 * Example 1:
 *
 * Input: [3,2,1,5,6,4] and k = 2
 * Output: 5
 *
 * Example 2:
 * Input: [3,2,3,1,2,4,5,5,6] and k = 4
 * Output: 4
 *
 * 這題可以直接排序,然後獲取第K個位置的數據即可,但是這不是本題的考察點
 * 本地用快排,直接找到第k個坑的值
 *
 * @Date: 2019/8/13 8:59
 * @Version: 1.0
 */
public class FindKthLargest {

    public int solution(int[] nums, int k) {
        int l = 0, r = nums.length - 1; //定義快排的左右邊界
        while (l <= r) {
            int pos = partition(nums, l, r);
            //找到中間的位置
            if (pos == k - 1) {
                //找到對應的值
                return nums[pos];
            } else if (pos > k - 1) {
                //如果位置比第k個數要大,那麼說明第k位再左邊
                r = pos - 1;
            } else {
                l = pos + 1;
            }
        }

        return -1;
    }

    public int partition(int[] nums, int l, int r) {
        int init = nums[l], l1 = l + 1, r1 = r;
        while (l1 <= r1) {
            //遍歷交換數據
            if (nums[l1] < init && nums[r1] > init) {
                //交換位置數據
                int temp = nums[l1];
                nums[l1++] = nums[r1];
                nums[r1--] = temp;
            }

            if (nums[l1] >= init) {
                ++l1;
            }

            if (nums[r1] < init) {
                --r1;
            }
        }

        //當r1越過l1的時候,交換回來
        nums[l] = nums[r1];
        nums[r1] = init;


        return r1;
    }

    public static void main(String[] args) {
        int s[] = {3,2,3,1,2,4,5,5,6};
        int k = 4;
        int s1[] = {1};
        int k1 = 1;
        int s2[] = {99,99};
        int k2 = 1;
        int s3[] = {2,1};
        int k3 = 1;
        int s4[] = {-1, 2, 0};
        int k4 = 1;

        FindKthLargest fuc = new FindKthLargest();

        fuc.solution(s4, k4);

    }
}

 

package y2019.Algorithm.divideandconquer.hard;

/**
 * @ProjectName: cutter-point
 * @Package: y2019.Algorithm.divideandconquer.hard
 * @ClassName: MaxCoins
 * @Author: xiaof
 * @Description: 312. Burst Balloons
 * Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by array nums.
 * You are asked to burst all the balloons. If the you burst balloon i you will get nums[left] * nums[i] * nums[right] coins.
 * Here left and right are adjacent indices of i. After the burst, the left and right then becomes adjacent.
 * Find the maximum coins you can collect by bursting the balloons wisely.
 *
 * Note:
 * You may imagine nums[-1] = nums[n] = 1. They are not real therefore you can not burst them.
 * 0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100
 * Example:
 *
 * Input: [3,1,5,8]
 * Output: 167
 * Explanation: nums = [3,1,5,8] --> [3,5,8] -->   [3,8]   -->  [8]  --> []
 *              coins =  3*1*5      +  3*5*8    +  1*3*8      + 1*8*1   = 167
 * @Date: 2019/8/13 9:43
 * @Version: 1.0
 */
public class MaxCoins {

    public int solution(int[] nums) {
        //逆向思維,我們發現每次都是再已經存在的氣球中進行爆破,這裏嘗試改變想法爲,本來沒有氣球,加入氣球進行爆破
        //我們從最後一步開始思考,每次只需要遞歸到上一層有+1個氣球的時候,進行爆破得到當前環節
        //1.首先創建長度+1的數組,因爲起始和結束的位置默認爲1
        int[] resarray = new int[nums.length + 2];
        int n = 1;
        for (int x : nums) {
            //這裏排除掉爲0的數據
            if (x > 0) {
                resarray[n++] = x;
            }
        }
        resarray[0] = resarray[n++] = 1;

        //這個數組表示,再i,j區間內進行爆破的最大值
        int[][] back = new int[n][n];
        return burst(back, resarray, 0, n - 1);
    }

    public int burst(int[][] back, int[] nums, int left, int right) {
        //如果是邊界,或兩個索引之間沒有空隙了,那麼就不用插入了
        if (left + 1 == right) return 0;
        if (back[left][right] > 0) {
            //如果已經計算過了,不做重複計算
            return back[left][right];
        }
        //計算每個位置作爲最後一個爆破點的時候值
        int ans = 0;
        for (int i = left + 1; i < right; ++i) {
            ans = Math.max(ans, nums[left] * nums[i] * nums[right] + burst(back, nums, left, i) + burst(back, nums, i, right));
        }
        //修改值內容,繼續遞歸
        back[left][right] = ans;
        return ans;
    }

    
    /**
     *
     * @program: y2019.Algorithm.divideandconquer.hard.MaxCoins
     * @description: https://leetcode.com/problems/burst-balloons/discuss/76228/Share-some-analysis-and-explanations
     * @auther: xiaof
     * @date: 2019/8/13 11:20
     */
    public int maxCoins(int[] iNums) {
        int[] nums = new int[iNums.length + 2];
        int n = 1;
        for (int x : iNums) if (x > 0) nums[n++] = x;
        nums[0] = nums[n++] = 1;


        int[][] memo = new int[n][n];
        return burst2(memo, nums, 0, n - 1);
    }

    public int burst2(int[][] memo, int[] nums, int left, int right) {
        if (left + 1 == right) return 0;
        if (memo[left][right] > 0) return memo[left][right];
        int ans = 0;
        for (int i = left + 1; i < right; ++i)
            ans = Math.max(ans, nums[left] * nums[i] * nums[right]
                    + burst2(memo, nums, left, i) + burst2(memo, nums, i, right));
        memo[left][right] = ans;
        return ans;
    }

    public static void main(String[] args) {
        int s[] = {3,1,5,8};
        int[] s1 = {8,2,6,8,9,8,1,4,1,5,3,0,7,7,0,4,2,2,5};
        int[] s2 = {8,3,4,3,5,0,5,6,6,2,8,5,6,2,3,8,3,5,1,0,2};

        MaxCoins fuc = new MaxCoins();

//        fuc.solution(s2);
        fuc.maxCoins(s2);

    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章