1-7
1 用了 try catch
2 使用字符串 数字抓换 to_string stoi
stoi会直接把s转换成数字 我看他代码里最后一位是符号的话不用管
3 不断地最后一位推出 除以10的余数
1 自动机 相当于状态机
开始状态 标识符状态 数字状态 结束状态
int get_col(char c) {
if (isspace(c)) return 0;
if (c == '+' or c == '-') return 1;
if (isdigit(c)) return 2;
return 3;
ans = ans * 10 + c - '0' 减去字符0的ascii值
不然相加都是加的字符的 ascii的值
ans = sign == 1 ? min(ans, (long long)INT_MAX) : min(ans, -(long long)INT_MIN);
我估计都必须是同型号的才能比较
2 字符流
#include
class Solution {
public:
int myAtoi(string s) {
stringstream liu(s);
int n=0;
liu>>n;
return n;
}
};
c++,活用cin
读取(和忽略)处于所需数据周围的标号,例如字符串是(“12 1”)int n,c; liu>>n>>c n的值是12,c的值是1
1 我想的是从中间扩散 他的是从两边到中间
2 第二个想法是将数字本身反转,然后将反转后的数字与原始数字进行比较,如果它们是相同的,那么这个数字就是回文。
但是,如果反转后的数字大于
int.MAX
int.MAX,我们将遇到整数溢出问题。
那为什么不反转数字的一半
class Solution {
public:
bool isPalindrome(int x) {
string s=to_string(x);
int n=s.size();
if(s.length()<=1)
return true;
if(!isdigit(s[0]))
return false;
if(n%2==0)
{
int k=1;
for(int i = n/2; i<n; i++)
{
if(s[i]!=s[i-k])
return false;
k+=2;
}
}
else
{
int k=2;
for(int i = (n/2 +1); i<n; i++)
{
if(s[i]!=s[i-k])
return false;
k+=2;
}
}
return true;
}
};
bool isPalindrome(int x) {
if (x<0)return false;
if (x==0)return true;
string s=to_string(x);
int n=s.size();
for(int i=0;i<n/2;i++){
int j=n-1-i;
if(s[i]!=s[j]){
return false;
}
}
return true;
}
};
https://leetcode.cn/problems/regular-expression-matching/solution/by-flix-musv/
动态规划
dp[i][j] 表示s的前i个字符和p的前j个字符是否匹配·
原本是要看s的前i个字符和p的前j个字符是否匹配·
p[j]为* 他这里是往前看的 后面的会考虑到前面的
如果匹配两次 意味着 s的i-1和i的字符要相同 ,并且 p的j-1字符也要相同
那么 i,j的问题 就转化为了 i-2和j-2的问题 以此往前
同样,如匹配k次 那么i,j的问题便转化为i-k和j-2的匹配问题
匹配0次,那么i,j的问题就可以转化为i,j-2的问题
他用了两个方程进行转化
得到了简化的状态方程
最后他得出了三种情况的方程
1 i,j字符匹配
那么就是要找i-1和 j-1匹配
否则直接false
2,p[j]为* 那么接下来
看 s[i]和 p[j-1]是否相等
接下来又分两种情况
他这里提到了边界情况 两个都是空字符串那么 0,0位置
对于0,j 当j不是*时候,false 是的话 会引发j-2的情况 ,那么需要前面预留位置
class Solution {
public:
bool isMatch(string s, string p) {
if (p.empty()) return s.empty();
auto first_match = !s.empty() && (s[0] == p[0] || p[0] == '.');
if (p.length() >= 2 && p[1] == '*') {
return isMatch(s, p.substr(2)) || (first_match && isMatch(s.substr(1), p));
} else {
return first_match && isMatch(s.substr(1), p.substr(1));
}
}
};
class Solution {
public:
bool isMatch(string s, string p) {
if(regex_match(s,regex(p)))
{
return true;
}
return false;
}
};
class Solution {
public:
bool isMatch(string s, string p) {
return isMatch(s.c_str(), p.c_str());
}
bool isMatch(const char* s, const char* p) {
if(*p == 0) return *s == 0;
auto first_match = *s && (*s == *p || *p == '.');
if(*(p+1) == '*'){
return isMatch(s, p+2) || (first_match && isMatch(++s, p));
}
else{
return first_match && isMatch(++s, ++p);
}
}
};
class Solution {
public:
bool isMatch(string s, string p) {
int m = s.size();
int n= p.size();
vector<vector<bool>> dp(m+1, vector<bool>(n+1, false));
dp[0][0] = true;
for(int j=1; j<=n; j++)
{
if(p[j-1]=='*') dp[0][j] = dp[0][j-2];//按题意p第一个元素不可能为'*'所以不必担心j越界
}
for(int i=1; i<=m; i++)
{
for(int j=1; j<=n; j++)
{
if(s[i-1]==p[j-1] || p[j-1]=='.') dp[i][j] = dp[i-1][j-1];
else if(p[j-1]=='*')
{
if(s[i-1]!=p[j-2] && p[j-2]!='.')
{
dp[i][j] = dp[i][j-2];
}
else
{
dp[i][j] = dp[i][j-2] | dp[i-1][j];
}
}
}
}
return dp[m][n];
}
};
int maxArea(vector<int>& height) {
int max1=0;
int area=0;
int n = height.size();
for(int i=0;i<n-1;i++)
{
for(int j=i+1 ; j<n;j++)
{
area= min(height[i],height[j])*(j-i);
max1= max(area,max1);
}
}
return max1;
}
class Solution {
public:
int maxArea(vector<int>& height) {
int i = 0, j = height.size() - 1, res = 0;
while(i < j) {
res = height[i] < height[j] ?
max(res, (j - i) * height[i++]):
max(res, (j - i) * height[j--]);
}
return res;
}
};
class Solution {
public:
int maxArea(vector<int>& height) {
int i=0,j=height.size()-1,area1=0;
int max1=0;
while(i!=j)
{
area1= (j-i)*min(height[i],height[j]);
max1= max1>area1?max1:area1;
if(height[i]>height[j])
{
j--;
}
else
{
i++;
}
}
return max1;
}
};
长短板
两边 长的往里进 短的不变,长的变得更短,不可能变大
短的往里进 还有可能变大
使用单调栈
vector<int> mostCompetitive(vector<int>& nums, int k) {
int n = nums.size();
int count= n-k;
vector<int> ans;
for(int i = 0; i<n;i++)
{
while(!ans.empty() && ans.back()>nums[i] && count>0)
{
ans.pop_back();
count--;
}
ans.push_back(nums[i]);
}
while(ans.size()>k)
{
ans.pop_back();
}
return ans;
}
他这个课程表 课程数量和 有的课是相同的
for cur, pre in prerequisites:
indegrees[cur] += 1 [ xx] 在课程位置数加1 代表该课程的入度数加1
adjacency[pre].append(cur) 在 pre课程位置的 【】内加入 出度的课程号 即依赖这门课的后续课程
遍历 indegress 如果他的入度数为0 就把该位置相当于课号的加入 队列
此时 queue 应该是 按照课程号顺序排列的,并且都是入度数为0的,相当于第一层节点
当queue不为空,就不断推出队首的一个值,
然后根据这个值看依赖他的课程号,然后把该课程号的入度数减去1,并判断 这个课程入度数是否为0,是的话就推入queue
queue都遍历完了 然后 把 numcourses返回
DFS法
广度优先即按层去遍历整个图,一层访问结束后再去访问下一层。
https://blog.csdn.net/yanweiqi1754989931/article/details/109603384
https://blog.csdn.net/m0_46213598/article/details/120363633
建立依赖表 就是依赖这个课程的 课程
为每个课程建立0标签
对于每一个课程, if not dfs,返回假
不然返回真
dfs 是0的话就返回假了 基本上dfs得是1
dfs 三个参数 分别是 课程号 课程的依赖课 该课程的标签
对于i课程dfs中 对他的依赖课程dfs
要想这个不执行 得是他的依赖课程dfs都是 true
都执行完 ,该课程标签置为-1
就是判断是否有环,有环就不行了
class Solution {
public:
bool halvesAreAlike(string s) {
string o = "aeiouAEIOU";
int n = s.length();
int cout1=0,cout2=0;
for(int i=0; i< n; i++ )
{
int pose1=o.find(s[i]);
if(pose1!= -1)
{
i<n/2? cout1++:cout2++;
}
}
if(cout1 ==cout2) return true;
else return false;
}
};
https://blog.csdn.net/hnjzsyjyj/article/details/108929993
priority queue元素 队列中元素按照优先级参数排序,最小或者最大的元素总是在队列前端,并且会在每次出队的时候被删除
greater 从大到小
priority_queue
q2;//神奇的降序
大家可以看到,默认模板有三个参数,第一个是优先队列处理的类。第二个参数比较有特点,是容纳优先队列的容器。实际上,优先队列是由这个容器C++语言中关于heap的相关操作实现的。这个容器默认是vector,也可以是dequeue,因为后者功能更强大,而性能相对于vector较差,考虑到包装在优先队列后,后者功能并不能很好发挥,所以一般选择vector来做这个容器。第三个参数比较重要,支持一个比较结构,默认是less,默认情况下,会选择第一个参数决定的类的<运算符来做这个比较函数。priority_queue
qi2;//从小到大的优先级队列,可将greater改为less,即为从大到小可以使用优先队列存储每个苹果的腐烂日期 最小元素会被先取出
看一下当天pq中已经过期的 直接删掉 然后加入当天新鲜的
当pq非空,并且他的top的first元素小于等于i pq插入 腐烂的天数以及腐烂的数目 推出top 然后把腐烂数目减1 然后如果还有数目
就加入只要pq不为空 一直执行循环 , 然后首先当天去掉过期的 再次判断 是不是空了 ,空的话就推出循环,不然就拿出top并推出 int num
= min(curr.first - i, curr.second); 分析两个数字中小的, 第一个是还有几天过期,比如两天过期, 第二个是还剩下几个苹果,比如三个苹果, 那么可以吃的数量就是两个 然后一个天数一个苹果树分别加上最小值
class Solution {
public:
vector<int> findBall(vector<vector<int>>& grid) {
int col = grid[0].size();
vector<int> res;
for(int i=0; i<col;i++)
{
int j =0;
while(j<grid.size())
{
int cur = grid[j][i];
i+= grid[j][i]; //action
if(i>=0 ||i<col)
{
int nei = grid[j][i];
if(nei*cur>0) j++;
else
break;
}
}
j==grid.size()-1? res.push_back(i+1):res.push_back(-1);
}
return res;
}
};
vector<int> findBall(vector<vector<int>> &grid) {
int n = grid[0].size();
vector<int> ans(n);
for (int j = 0; j < n; ++j) {
int col = j; // 球的初始列
for (auto &row : grid) {
int dir = row[col];
col += dir; // 移动球
if (col < 0 || col == n || row[col] != dir) { // 到达侧边或 V 形
col = -1;
break;
}
}
ans[j] = col; // col >= 0 为成功到达底部
}
return ans;
}
递归
首先判断是不是空指针 是的话返回{}
然后判断他的左右节点是不是空 是的话返回0
设立了一个 vector ret
遍历左系欸但 返回的left是
class Solution {
public:
int countPairs(TreeNode* root, int distance) {
int ans = 0;
dfs(root, distance, ans);
return ans;
}
vector<int> dfs(TreeNode* root, int distance, int& ans) {
if (root == nullptr) return {};
if (root->left == nullptr && root->right == nullptr) return { 0 };
vector<int> ret;
auto left = dfs(root->left, distance, ans);
for (auto& e : left) {
if (++e > distance) continue;
ret.push_back(e);
}
auto right = dfs(root->right, distance, ans);
for (auto& e : right) {
if (++e > distance) continue;
ret.push_back(e);
}
for (auto l : left) {
for (auto r : right) {
ans += (l + r <= distance);
}
}
return ret;
}
};
静态连通
给定整个图 再给出连通性的询问
https://leetcode.cn/problems/check-if-there-is-a-valid-path-in-a-grid/solution/jian-cha-wang-ge-zhong-shi-fou-cun-zai-you-xiao-lu/
并查集
class Solution {
int m,n,dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};//0下、1右、2上、3左
int pipe[7][4]={{-1,-1,-1,-1},{-1,1,-1,3},{0,-1,2,-1},{-1,0,3,-1},{-1,-1,1,0},{3,2,-1,-1},{1,-1,-1,2}};
//记录各个拼图块路径的方向,0、1、2、3代表方向,-1代表不可走。
bool dfs(int x,int y,int dir,vector
if(xm-1&&yn-1) return 1;//到达终点
int xx=x+dx[dir];
int yy=y+dy[dir];//得到下一个准备走的坐标
if(xx<0||yy<0||xx>=m||yy>=n)return 0;//越界
int nxt=grid[xx][yy];//得到下一块拼图的编号
if(pipe[nxt][dir]!=-1)return dfs(xx,yy,pipe[nxt][dir],grid);//如果当前方向可走,则方向改变,继续走。
return 0;//无法走,返回0
}
public:
bool hasValidPath(vector
m=grid.size();
n=grid[0].size();
int sta=grid[0][0];//起点的拼图编号
for(int i=0;i<4;++i)//朝着四个方向都试一下
if(pipe[sta][i]!=-1)//当前方向可以走
if(dfs(0,0,pipe[sta][i],grid))//沿着当前方向搜索
return 1;//拼图都有两个方向可以走,只要沿着一个初始方向走通就可以。
return 0;
}
};
作者:wu-xing-que-ni-2
链接:https://leetcode.cn/problems/check-if-there-is-a-valid-path-in-a-grid/solution/cdfsjie-fa-rong-yi-li-jie-dai-ma-duan-zhu-shi-duo-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
暴力枚举
string temp=to_string(num);
reverse(temp.begin(),temp.end());
return stoi(temp);
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums)
{
vector< vector<int> > ans;
if(nums.size() < 3 || nums.empty()) return ans; // 特判
int n = nums.size();
sort(nums.begin(), nums.end()); //排序
for(int i = 0; i < n; i++) // 枚举最小值
{
if(nums[i] > 0) return ans;
if(i > 0 && nums[i] == nums[i-1]) continue; // 最小元素去重!
int l = i+1;
int r = n-1;
while(l < r) // 枚举中间值和最大值
{
int x = nums[l] + nums[r] + nums[i];
if(x == 0){ // 符合条件,存储,并且去重,双端都移到下一个位置
ans.push_back({ nums[i], nums[l], nums[r] });
while( l < r && nums[l] == nums[l+1]) l++; l++;
while( l < r && nums[r] == nums[r-1]) r--; r--;
}
else if(x > 0) // 大了就让右边最大值变小
r--;
else // 小了就让左边中间值变大
l++;
}
}
return ans;
}
};
https://blog.csdn.net/weixin_44020969/article/details/103225825
https://leetcode.cn/problems/range-product-queries-of-powers/
int numberOfBeams(vector<string>& bank) {
int row = bank.size();
int las1=0;
vector<int> num;
int ans;
for(int i=0; i<row; i++)
{
for(char c:bank[i])
{
if(c=='1')
las1++;
}
if(las1!=0)
num.push_back(las1);
las1=0;
}
for(int i=0; i<num.size()-1; i++)
{
int tem= num[i]*num[i+1];
ans+=tem;
}
return ans;
}
class Solution {
public:
int numberOfBeams(vector<string>& bank) {
int last = 0, ans = 0;
for (const string& line: bank) {
int cnt = count_if(line.begin(), line.end(), [](char ch) {return ch == '1';});
if (cnt != 0) {
ans += last * cnt;
last = cnt;
}
}
return ans;
}
};
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/number-of-laser-beams-in-a-bank/solution/yin-xing-zhong-de-ji-guang-shu-shu-liang-ad02/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public:
bool validMountainArray(vector<int>& arr) {
int n = arr.size();
if(n<3) return false;
int flag=0;
for(int i=0;i<n-1;i++)
{
if(flag==0)
{
if(arr[i]>=arr[i+1]) return false;
if(arr[i]<arr[i+1]) flag=1;
}
else if(flag==1)
{
if(arr[i]==arr[i+1]) return false;
if(arr[i]>arr[i+1]) flag=2;
}
else
{
if(arr[i]<=arr[i+1]) return false;
}
}
if(flag==2)
return true;
else
return false;
}
};
class Solution {
public:
bool validMountainArray(vector<int>& arr) {
int n = arr.size();
if(n<3) return false;
int flag=0;
for(int i=0;i<n-1;i++)
{
if(flag==0)
{
if(arr[i]>=arr[i+1]) return false;
if(arr[i]<arr[i+1]) flag=1;
}
else if(flag==1)
{
if(arr[i]==arr[i+1]) return false;
if(arr[i]>arr[i+1]) flag=2;
}
else
{
if(arr[i]<=arr[i+1]) return false;
}
}
if(flag==2)
return true;
else
return false;
}
};
const validMountainArray = (A) => {
const n = A.length;
let i = 0;
let j = n - 1;
while (i + 1 < n && A[i] < A[i + 1]) {
i++;
}
while (j - 1 >= 0 && A[j - 1] > A[j]) {
j--;
}
if (i != 0 && i == j && j != n - 1) {
return true;
}
return false;
};
可以使用两种指针,一个从左边找最高山峰,一个从右边找最高山峰,最后判断找到的是不是同一个山峰
思路 直接统计两个字符串中 不同字符的个数 是否相同
我的思路 滑动窗口法,最大宽度从 n 开始不断往下减少
一开始最大n只有一个 上标0 下标n-1
后面有两个 上标0或者1 下标 n-2 或者 n-1
class Solution {
public:
int maxWidthRamp(vector<int>& nums) {
int n=nums.size()-1;
int k=nums.size()-1;
while(n>0)
{
for(int i=0; i<=k-n;i++)
{
if(nums[i]<=nums[n+i])
return n;
}
n--;
}
return 0;
}
};
超出时间限制
递增 从栈底到栈顶是从大到小
单调递减栈就是从栈底到栈顶是从小到大
def maxWidthRamp(A):
stack = []
max_width = 0
# 构建单调递减栈
for i, num in enumerate(A):
if not stack or A[stack[-1]] > num:
stack.append(i)
# 从右向左遍历数组,查找最大宽度坡
for j in range(len(A) - 1, -1, -1):
while stack and A[stack[-1]] <= A[j]:
i = stack.pop()
max_width = max(max_width, j - i)
return max_width
作者:3k5X21s3ar
链接:https://leetcode.cn/problems/maximum-width-ramp/solution/bao-jiao-bao-hui-shi-jian-fu-za-du-onkon-3lji/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
解题思路:使用递减栈求解该最大跨度问题“找到满足 A[j] >= A[i] 的最大跨度 [i,j]”。
理论依据:1.栈中保存的元素依次为比 A 首元素逐步降低的元素索引,对于任意区间 [i,j] ,无妨设 i 不是栈顶元素,若其满足 A[j] >= A[i] ,则对于栈中比 i 小的最大索引 i_0 < i (此时 i_0 是正序遍历至 i 处时的栈顶元素),区间 [i_0,j] 必满足 A[j] > A[i_0] ,这是因为栈顶元素是递减的,因为 i 元素不在栈中而 i_0 是正序遍历至 i 处时的栈顶元素,故必有 A[i_0] < A[i] ,即区间 [i_0,j] 是比区间 [i,j] 更优的解,故,对于最优解的区间 [i,j] , i 必是某个栈顶元素;
i_0是栈里的,单调递减,他的元素起码小于等于 i上的元素,所以条件更成立,并且i_0还是小于i
2.在将 j 从 A 尾元素向左移动的过程中,若 A[j] >= A[heightStack.top()] 则可以将 heightStack.top() 弹出,因为 heightStack.top() 成为跨度左界的情况的跨度最大值已计算完毕,否则可以将 j 向左移动一位,因为 j 成为跨度右界的情况的跨度最大值已计算完毕,这是因为若 A[j] 小于当前栈顶元素,则 A[j] 必小于栈中其他元素。
算法过程:首先基于 A 数组构造递减栈;随后使用递减栈求出满足 A[j] >= A[i] 的最大跨度 [i,j] ,具体地,从 A 尾元素开始移动 j ,若 A[j] >= A[heightStack.top()] 则将 heightStack.top() 弹出,否则将 j 向左移动一位。
算法细节:当递减栈弹出至空时,可提前结束查找。
编码过程:原创手撸,本题和第 1124 题属于同一数学模型的不同物理问题。在第 1124 题后,又独立手撸了单调栈算法一次。
解题用时:0.5小时,使用单调栈求解“找到满足 A[j] > A[i] 的最大跨度 [i,j]”的问题。
作者:lyfhouyi
链接:https://leetcode.cn/problems/maximum-width-ramp/solution/962di-jian-zhan-yu-di-1124-ti-shu-yu-ton-tkux/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
栈底到栈顶是从小到大
栈顶先出,栈底后出
先出大的,后出小的,所以单调递减
构造递减栈, 遍历,只要比栈顶小,就推入,从而越来越小,压在里面的是最大的。
栈中元素从深到浅 依次为 比首元素 减小的 元素索引
那么索引可能是
0 1 2 3 索引不断增大,先出3,再出2,
class Solution {
public:
int maxScore(vector<int>& nums) {
//int score = 0;
double num =0;
//vector prefix;
sort(nums.begin(),nums.end(),greater<int>());
int i=0;
while(num>=0)
{
num+=nums[i];
i++;
if(num<=0)
{
i--;
break;}
if(i>=nums.size()) break;
}
return i;
}
};
class Solution {
public int maxScore(int[] nums) {
// 从小到大排序
Arrays.sort(nums);
int maxScore = 0;
// 前缀和
long preFixSum = 0;
// 倒序求正数前缀和
for (int i = nums.length - 1; i >= 0; i--) {
preFixSum += nums[i];
if (preFixSum > 0) {
maxScore++;
} else {
// 出现负数,终止遍历
// nums的分数是prefix数组中正整数的个数
return maxScore;
}
}
return maxScore;
}
}
作者:fa-xing-bu-luan
链接:https://leetcode.cn/problems/rearrange-array-to-maximize-prefix-score/solution/6316-zhong-pai-shu-zu-yi-de-dao-zui-da-q-ofi7/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
遍历将数位和求出并加入map
然后遍历map map后面的值的长度大于二,就将v排序,从大到小,取前两个相加。
map<int, vector<int>> mp;
一种思想就是 遍历每一条路径 ,然后把该路径的值计算
一种思想就是 每一层 然后每一层判断
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> res;
vector<int> path;
vector<vector<int>> pathsum(TreeNode* root,int taeget)
{
recur(root,target);
return res;
}
void recur(TreeNode *rott, int tar)
{
if(root==nullptr) return;
path.push_back(root-val);
tar-=root->bal;
if (tar == 0 && root->left == nullptr && root->right == nullptr) {
res.push_back(path);
}
recur(root->left, tar);
recur(root->right, tar);
path.pop_back();
}
};
https://leetcode.cn/problems/minimum-number-of-arrows-to-burst-balloons/solution/tu-jie-tan-tao-wei-shi-yao-yao-an-qu-jian-de-you-d/
贪心。 右边断点从小到大排序,然后以右端点为参考点, 不断判断下一个的左端点是否小于,是的话判断下一个, 直到不是 那么这个时候弓箭加1
按左端右端排序都是一样的,都是寻求最小交集区间。[0,9]和[0,6]交集[0,6],所以[0,6]上可以一箭射穿,[0,6]和[7,8]没有交集,所以箭数+1。
class Solution {
public:
static bool cmp(vector<int> &a,vector<int> &b)
{
return a[1] < b[1];
}
int findMinArrowShots(vector<vector<int>>& points)
{
//贪心策略:和 LeetCode 435 无重叠区间是同一个意思
const int n = points.size();
if(n < 2) return n;
std::sort(points.begin(), points.end(), cmp);//按气球的结束坐标大小,对升序排列
int ans = 1;//不相交的气球个数 = 引爆全部气球需要的弓箭数量
int tail = points[0][1];//前一个不相交的气球结束坐标
for(int i = 1; i < n; ++i)
{
if(points[i][0] > tail)//不相交的条件:后一个气球的开始坐标大于(不能等于)前一个气球的结束坐标
{
++ans;
tail = points[i][1];
}
}
return ans;
}
};
sort(points.begin(), points.end(), [](const vector<int>& a, const vector<int>&b){
return a[1] < b[1];//这里a[0]
});
int start = points[0][0];
int end = points[0][1];
int sum = 1;
for(int i = 1; i < points.size(); i++) {
if(points[i][0] > end || points[i][1] < start) {
sum++;
start = points[i][0];
end = points[i][1];
}
else {
start = max(start, points[i][0]);
end = min(end, points[i][1]);
}
}
return sum;
}