• LeetCode--戳气球


    链接:https://leetcode-cn.com/problems/burst-balloons/

    题目:

      有 n 个气球,编号为0 到 n-1,每个气球上都标有一个数字,这些数字存在数组 nums 中,

      现在要求戳破所有的气球。每当戳破一个气球 i 时,可以获得 nums[left] * nums[i] * nums[right] 个硬币,其中 left 和 right 代表和 i 相邻的两个气球的序号,注意当戳破了气球 i 后,气球 left 和气球 right 就变成了相邻的气球,

      求所能获得硬币的最大数量

      说明:

        可以假设 nums[-1] = nums[n] = 1,但注意它们不是真实存在的所以并不能被戳破。0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100

    解题思路:

    解法一,我的想法是通过递归回溯来找到所能获取的最大数量的硬币,然而提交后提示时间超时,这种方法的时间复杂度达到了O(N!),其中N为气球的个数

     1 import java.util.List;
     2 import java.util.ArrayList;
     3 
     4 public class Solution {
     5     public int maxCoins(int[] nums) {
     6         List<Integer> arr = new ArrayList();
     7         for(int i = 0; i < nums.length; i++) {
     8             arr.add(nums[i]);
     9         }
    10         return helper(arr);
    11     }
    12 
    13     public int helper(List<Integer> arr) {
    14         if(arr.size() == 0) return 0;
    15         int pre = 0, next = 0;
    16         int max = 0;
    17         int len = arr.size();
    18         for(int i = 0; i < len; i++) {
    19             pre = i == 0 ? 1 : arr.get(i - 1); 
    20             next = i == arr.size()-1 ? 1 : arr.get(i + 1); 
    21             int cur = arr.get(i);
    22             arr.remove(i);
    23             max = Math.max(max, pre*cur*next + helper(arr));
    24             arr.add(i, cur);
    25         }
    26         return max;
    27     }
    28 }

      时间复杂度:O(N!);空间复杂度:O(N),其中N为气球的个数

    解法二看这里),随机选取一点作为分界点,先算出左右两边的最大值,然后算出当前的最大值,仍然超时,时间复杂度为O(N!),空间复杂度O(1),其中N为气球的个数。与解法一的区别在于,解法一是先戳破当前节点,然后计算当前节点被戳破的情况下,计算剩余节点的情况,而解法二采取的是先把剩余的节点计算出最大值,再戳破当前节点。

     1 import java.util.List;
     2 import java.util.ArrayList;
     3 
     4 public class Solution {
     5     public int maxCoins(int[] nums) {
     6         return maxCoin(nums, 0, nums.length - 1);
     7     }
     8 
     9     public int maxCoin(int[] nums, int left, int right) {
    10         if(left > right) return 0;
    11 
    12         int pre = 0, next = 0;
    13         int max = 0;
    14         for(int i = left; i <= right; i++) {
    15             pre = left == 0 ? 1 : nums[left - 1];
    16             next = right == nums.length - 1 ? 1 : nums[right + 1];
    17             max = Math.max(max, pre*nums[i]*next + maxCoin(nums, left, i - 1) + maxCoin(nums, i + 1, right));
    18         }
    19         return max;
    20     }
    21 }

    解法三看这里),动态规划,dp[i][j]表示将[i+1, j-1]范围的气球全部戳破可以获得的最大硬币数量。

     1 public class Solution {
     2     public int maxCoins(int[] nums) {
     3         if(nums == null || nums.length == 0) return 0;
     4         int length = nums.length + 2;
     5         int[] arr = new int[length];
     6         arr[0] = 1;
     7         arr[length - 1] = 1;
     8         for(int i = 1; i < length - 1; i++) {
     9             arr[i] = nums[i - 1];
    10         }
    11         int[][] dp = new int[length][length];
    12         for(int len = 2; len < length; len++) {
    13             for(int i = 0; i < length - len; i++) {
    14                 int j = i + len;
    15                 for(int k = i + 1; k < j; k++) {
    16                     dp[i][j] = Math.max(dp[i][j], arr[i]*arr[k]*arr[j] + dp[i][k] + dp[k][j]);
    17                 }
    18             }
    19         }
    20         return dp[0][length - 1];
    21     }
    22 }
  • 相关阅读:
    『HTML5挑战经典』是英雄就下100层开源讲座(一)从天而降的英雄
    Android activity界面的讲解
    五年专业编程的14个经验
    MOQL操作数(Operand) (二)
    674 Coin Change
    static用法小结
    jdk环境变量配置
    612this指针及const应用
    第六周项目一:改错
    Vijos 1082 丛林探险
  • 原文地址:https://www.cnblogs.com/OoycyoO/p/11961772.html
Copyright © 2020-2023  润新知