LeetCode Hard难度题目题解汇总(5/150)

本文汇总了LeetCode中五道难题的解题思路与代码,包括戳破气球的最大硬币数、同一直线上的最大点数、接雨水问题、最小覆盖子串和最长连续序列。涉及动态规划、直线几何和数组操作等算法技巧。
摘要由CSDN通过智能技术生成

1. 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
示例:

输入:
[3,1,5,8]

输出:
167
解释:
nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> []
coins = 315 + 358 + 138 + 181 = 167

思路:
区间dp,dp[i][j] 代表i,j之间最大值,转移方程就是 dp[i][j] = max(dp[i][j], dp[i][m-1]+dp[m+1][j]+a[m]*a[l-1]*a[r+1])一开始自己写的时候转移写错了,注意dp[i][j]代表的是i,j之间的最大值,枚举m的时候乘以的应该是l-1,跟r+1的值,因为m消失了,他们并不会消失,而不是乘以l跟r的值,如果那样的话dp[i][j]的意义就不对了
代码:

class Solution {
   
    int dp[507][507];
public:
    int maxCoins(vector<int>& nums) {
   
        int n = nums.size();
        int b[n+10];
        b[0] = b[n+1] = 1;
        for(int i = 1; i <= n; i++) b[i] = nums[i-1];
        for(int len = 1; len <= n; len++)
        {
   
            for(int l = 1; len+l-1 <= n; l++)
            {
   
                int r = len+l-1;
                for(int m = l; m <= r; m++)
                    dp[l][r] = max(dp[l][r], b[l-1]*b[r+1]*b[m]+dp[l][m-1]+dp[m+1][r]);
                // cout << l << ' ' << r << ' ' << dp[l][r] << endl;
            }
        }
        return dp[1][n];
    }
};

2. Max Points on a Line

题目:
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
思路:
这题最直接的想法枚举两个点确定直线,然后判断有多少个点在这个直线上。再就是枚举两个点的时候,通过map来记录他们的斜率的个数,斜率相同就+1, 斜率要注意没有斜率的时候,可以用一个inf记录,但是还要特判。比较好的思路就是维护一个字符串:dx_dy的格式,同时dx,dy要是最简的,所以都除以他们的gcd就好。
代码:

/**
 * Definition for a point.
 * struct Point {
 *     int x;
 *     int y;
 *     Point() : x(0), y(0) {}
 *     Point(int a, int b) : x(a), y(b) {}
 * };
 */
class Solution {
   
public:
    int maxPoints
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值