LeetCode Hard难度题目题解汇总(5/150)
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(vector<Point>& points) {int ans = 0;for(int i = 0; i < points.size(); i++){unordered_map<string, int> mp;int cnt = 1;for(int j = i+1; j < points.size(); j++){if(points[i].x == points[j].x && points[i].y == points[j].y){cnt++;continue;}int dx = points[i].x-points[j].x, dy = points[i].y-points[j].y;int gcd = __gcd(dx, dy);dx /= gcd, dy /= gcd;string s = to_string(dx) + "_" + to_string(dy);mp[s]++;}ans = max(ans, cnt);for(unordered_map<string,int>::iterator it = mp.begin(); it != mp.end(); it++)ans = max(ans, it->second+cnt);}return ans;}
};
3. 接雨水
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 感谢 Marcos 贡献此图。
示例:
输入: [0,1,0,2,1,0,1,3,2,1,2,1]
输出: 6
思路:
我自己想的思路是从左往右对于每一个柱子,他往右遍历要么遇到一个跟他一样高或者比他高的柱子,那么这两个柱子形成一个坑,用这两个柱子短的那个柱子乘以他们之间的距离,然后减去两个柱子之间比他们矮的柱子,然后把第二个柱子作为起点。如果一直循环到结尾也没有比他高的,那么就找一个他右面柱子最高的柱子来跟他组成一个坑,同理减去里面比他们矮的。最坏复杂度是n2n^2n2的,如果柱子从高往低递减的话。。。
代码:
class Solution {public:int trap(vector<int>& height) {int l = 0, n = height.size()-1, ans = 0, sum = 0, maxx = -1, maxsum = 0, maxid = -1, flag = 0;while(l < n){sum = 0;maxx = -1;maxsum = -1;flag = 0;maxid = -1;for(int i = l+1; i <= n; i++){if(maxx < height[i]){maxx = height[i];maxsum = sum;maxid = i;}if(maxx >= height[l]){ans += height[l] * (i-l-1) - sum;l = i;flag = 1;break;}sum += height[i];}if(!flag){ans += maxx * (maxid-l-1) - maxsum;l = maxid;}}return ans;}
};
思路2,这个思路就牛逼了,对于每一个柱子,统计他左面的最高点跟他右面的最高点,然后如果左右最高点都比他高的话,那么他的上方一定是有水的,那么就可以很简单的知道这单个柱子上面的水有多少,如果不是都比他高的话,拿他的上面一定没有水。复杂度o(n)
代码:
class Solution {public:int trap(vector<int>& height) {int n = height.size();// left[i]表示i左边的最大值,right[i]表示i右边的最大值vector<int> left(n), right(n);for (int i = 1; i < n; i++) {left[i] = max(left[i - 1], height[i - 1]);}for (int i = n - 2; i >= 0; i--) {right[i] = max(right[i + 1], height[i + 1]);}int water = 0;for (int i = 0; i < n; i++) {int level = min(left[i], right[i]);water += max(0, level - height[i]);}return water;}
};
4. 最小覆盖子串
给定一个字符串 S 和一个字符串 T,请在 S 中找出包含 T 所有字母的最小子串。
示例:
输入: S = “ADOBECODEBANC”, T = “ABC”
输出: “BANC”
说明:
如果 S 中不存这样的子串,则返回空字符串 “”。
如果 S 中存在这样的子串,我们保证它是唯一的答案。
思路:
很简单的双指针,就是写的时候要仔细。细节比较多,维护两个数组,一个总的数量。
class Solution {public:int book[1000], cnt[1000];string minWindow(string s, string t) {int lent = t.size(), lens = s.size();int start = -1, end = -1, sum = 0, minl = INT_MAX, l = 0, r = 0;for(int i = 0; i < lent; i++)book[t[i]]++;while(r < lens && l <= r){if(!book[s[r]]){r++; // 这里别忘记r++。。。continue;}if(cnt[s[r]] < book[s[r]]) sum++; // 注意cnt[s[r]]++;while(sum == lent){if(minl > r-l+1){minl = r-l+1;start = l, end = r;}if(book[s[l]]) cnt[s[l]]--;if(cnt[s[l]] < book[s[l]]) sum--; //注意l++;}r++;}if(start == -1)return "";string ans;for(int i = start; i <= end; i++)ans += s[i];return ans;}
};
5. Longest Consecutive Sequence
题意:
在无序数组里找一个最长的连续序列,要求o(n)复杂度。
样例:
Input: [100, 4, 200, 1, 3, 2]
Output: 4
Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4.
思路:
用一个unordered_map存下每个数字是否出现,然后枚举数组,找他左右两边最长到哪里,并且取消那些元素的mp值,这样每个元素最多被遍历一次。所以就是on
代码:
class Solution {public:int longestConsecutive(vector<int>& nums) {unordered_map<int, int> mp;for(auto x : nums) mp[x] = 1;int ans = 0;for(auto x : nums){if(!mp[x]) continue;int tmp = 0, xx = x;while(mp[xx]) tmp++, mp[xx] = 0, xx--;xx = x + 1;while(mp[xx]) tmp++, mp[xx] = 0, xx++;ans = max(ans, tmp);}return ans;}
};
LeetCode Hard难度题目题解汇总(5/150)相关推荐
- LeetCode 力扣算法题解汇总,All in One
作者: 负雪明烛 id: fuxuemingzhu 个人博客: https://fuxuemingzhu.cn 关键词:LeetCode,力扣,算法,题解,汇总,解析 把自己刷过的所有题目做一个整理, ...
- PAT天梯赛Level2题目题解汇总
L2-001 紧急救援 /******************************************************************************* Date: 2 ...
- 【LeetCode刷题】二月汇总篇
学习总结 文章目录 学习总结 一.时间安排 task01 数组 task02 链表 task03 栈 task04 字符串 task05 树 task06 位运算 task07 双指针 task08 ...
- LeetCode 题解汇总
为什么80%的码农都做不了架构师?>>> LeetCode 题解汇总 转载于:https://my.oschina.net/michao/blog/801863
- 《剑指Offer》题解汇总索引表(leetcode)
<剑指Offer>题解汇总索引表(leetcode)
- MySQL--经典题目综合汇总二(进阶)--建议先把之前的看了,难度较高
MySQL--经典题目综合汇总二(进阶)--建议先把之前的看了,难度较高 1.表格创建 2.题目部分 题目一:求所有课程平均成绩排名在2到4名的同学信息(压轴) 题目二:查询不同老师所教不同课程平均分 ...
- Leetcode各种题型题目+思路+代码(共176道题)
文章目录 第一章:Leetcode 每日很多题 1.Leetcode-1047 删除字符串中的所有相邻重复项 2.剑指 Offer 53 - I. 在排序数组中查找数字 I 3.Leetcode704 ...
- C#版 - Leetcode 306. 累加数 - 题解
C#版 - Leetcode 306. 累加数 - 题解 306.Additive Number 在线提交: https://www.gaimor.cn 累加数是一个字符串,组成它的数字可以形成累加序 ...
- Leecode题解汇总(附题型归类)
虽然已找到工作,但不断地自我学习和自我磨砺是无止境的. 为方便量化和总结经验,记录一下个人的Leecode刷题记录,之前的刷题并没有收录进去,有时间会统一整理. 序号 题目 题解 类型 来源 难度 0 ...
- ptaa乘以b_PTA|团体程序设计天梯赛-练习题目题解锦集(C/C++)(持续更新中……)...
C++ CPP C++语言开发 PTA|团体程序设计天梯赛-练习题目题解锦集(C/C++)(持续更新中--) PTA|团体程序设计天梯赛-练习题目题解锦集(持续更新中) 实现语言:C/C++: ...
最新文章
- plotly基于dataframe数据绘制股票OHLC图
- infer的用法_typescript高级用法之infer的理解与使用
- 石川es6课程---4、箭头函数
- Arduino control Eeprom by IIC method of using device address in Arduino
- 如何使用Angular的@Input()装饰器
- 【转载保存】linux shell字符串切割成数组
- .set伪指令(mips)
- Linux 的内存分页管理
- 面试题10.3-变态跳台阶
- MATLAB对表达式进行降幂排列,MATLAB上机答案.doc
- 3月面经汇总-字节跳动,美团,腾讯算法岗
- JAVA:获得当前执行路径的办法
- python web工资怎么样_月薪21170的Python Web岗,学到什么程度能找到工作?
- 初学Python选什么版本?
- 通过股票数据接口如何看懂Level-2行情?
- Pyinstaller的Spec文件用法
- LeetCode--第25题K个一组翻转链表
- 服务器 12 种基本故障+排查方法
- long term recurrent convolutional networks for visual recognition and description
- 10亿数据找出前100大的数据(网易大数据面试算法题)
热门文章
- 说说vector的emplace_back和push_back
- uefi开发环境搭建
- 解决WARN Establishing SSL connection without servers identity verification is not recommended问题
- Caused by: org.elasticsearch.action.search.SearchPhaseExecutionException报错解决
- element-ui tree全部展开和全部折叠
- JavaScript数组反转教程
- Centos7系统安全漏洞及修复方案
- DX11 游戏开发笔记 (一) 资源介绍
- 【Vue】win10启动vue项目报错: errno: -4058, code: ‘ENOENT‘, syscall: ‘spawn cmd‘
- 水果店经营策略技巧汇总,第一次开一家水果店怎么经营