无重叠区间 划分字母区间 合并区间

1.给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。

注意: 可以认为区间的终点总是大于它的起点。 区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。

#include <bits/stdc++.h>
using namespace std;
bool cmp(const vector<int>&a,const vector<int>&b)
{
    return a[0]<b[0];
}
int find(vector<vector<int>>& num)
{
    if(num.size()==0)
    return 0;
    sort(num.begin(),num.end(),cmp);
    int count=0;
    for(int i=1;i<num.size();i++)
    {
        if(num[i][0]<num[i-1][1])
        {
            count++;
            num[i][1]=min(num[i-1][1],num[i][1]);
        }
        
    }
    return count;
 } 
 int main()
 {
     vector<vector<int>> num={{1,2},{3,6},{7,12},{4,8},{10,16}};
     int t=find(num);
     cout<<t;
     return 0;
 }

思路:首先我们要进行排序,按照右边界排序,从左向右记录非交叉区间的个数。最后用区间总数减去非交叉区间的个数就是需要移除的区间个数了

此时问题就是要求非交叉区间的最大个数。

区间,1,2,3,4,5,6都按照右边界排好序。

当确定区间 1 和 区间2 重叠后,如何确定是否与 区间3 也重贴呢?

就是取 区间1 和 区间2 右边界的最小值,因为这个最小值之前的部分一定是 区间1 和区间2 的重合部分,如果这个最小值也触达到区间3,那么说明 区间 1,2,3都是重合的。接下来就是找大于区间1结束位置的区间,是从区间4开始。

区间4结束之后,再找到区间6,所以一共记录非交叉区间的个数是三个。

总共区间个数为6,减去非交叉区间的个数3。移除区间的最小数量就是3。

2.字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。

#include <bits/stdc++.h>
using namespace std;
vector<int> find(string s)
{
    int hash[27]={0};
    for(int i=0;i<s.size();i++)
    {
        hash[s[i]-'a']=i;
    }
    int left=0;
    int right=0;
    vector<int> result;
    for(int i=0;i<s.size();i++)
    {
        right=max(hash[s[i]-'a'],right);
        if(i==right)
        {
            result.push_back(right-left+1);
            left=i+1;
        }
    }
    return result;
 } 
 int main()
 {
    string s="ababcbacadefegdehijhklij";
    vector<int> result=find(s);
    for(int n:result)
    {
        cout<<n<<" ";
        }    
     return 0;
 }

思路:这道题在遍历的过程中相当于是要找每一个字母的边界,如果找到之前遍历过的所有字母的最远边界,说明这个边界就是分割点了。此时前面出现过所有字母,最远也就到这个边界了。

可以分为如下两步:

1.统计每一个字符最后出现的位置。

2.从头遍历字符,并更新字符的最远出现下标,如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点。

3.给出一个区间的集合,请合并所有重叠的区间。

#include <bits/stdc++.h>
using namespace std;
bool cmp(const vector<int>& a,const vector<int>& b)
{
    return a[0]<b[0];
}
vector<vector<int>> find(vector<vector<int>>& num)
{
    vector<vector<int>> result;
    if(num.size()==0)
    return result;
    sort(num.begin(),num.end(),cmp);
    result.push_back(num[0]);
    for(int i=1;i<num.size();i++)
    {
        if(num[i][0]<=num[i-1][1])
        {
            result.back()[1]=max(num[i][1],result.back()[1]);
        }
        else{
            result.push_back(num[i]);
        }
    }
    return result;
 } 
 int main()
 {
     vector<vector<int>> num={{1,3},{8,10},{2,6},{15,18}};
     vector<vector<int>> t=find(num);
     for(const auto& n:t)
     {
         for(int m:n)
         {
             cout<<m<<" ";
         }
         cout<<endl;
     }
     return 0;
 }
 

思路:本题的本质是判断重叠区间问题。先排序,让所有的相邻区间尽可能的重叠在一起,按左边界,或者右边界排序都可以,处理逻辑稍有不同。按照左边界从小到大排序之后,如果 intervals[i][0] <= intervals[i - 1][1] 即intervals[i]的左边界 <= intervals[i - 1]的右边界,则一定有重叠。(本题相邻区间也算重贴,所以是<=)。

知道如何判断重复之后,剩下的就是合并了,如何去模拟合并区间呢?

其实就是用合并区间后左边界和右边界,作为一个新的区间,加入到result数组里就可以了。如果没有合并就把原区间加入到result数组。

超级强悍的 Android 手机高清视频播放利器 MX Video Player 迎来了正式版。作为安卓平台上知名度最高的手机播放器 MX Player Pro,无广告,界面非常简洁,同时播放视频解码功能也非常强大。这也是为什么在安卓平台中很多人都喜欢 MX Player Pro 的原因。如果你经常喜欢用手机播放视频,MX Player Pro 是你不错的选择。 安卓超强视频播放器 MX Player Pro 中文版M安卓超强视频播放器 MX Player Pro 中文版 MX Player Pro 是款超强的手机视频播放利器,支持3GP、AVI DIVX、F4V、FLV、MKV、MP4、MPEG、MOV、VOB、WMV、WEBM、XviD 格式。 MX Player Pro 功能特色: a) 硬体解码 – 拥有最新的硬体解码器,更多影片能受益于硬体加速。 b) 多核心解码 – 安卓第一款多核心解码影片播放器,根据在多核心设备上的测试,它比单核心解码效能提高将近70%。 c) 触控缩放手势 – 在萤幕上能轻松地缩放及使用各种手势。 d) 字幕滑动功能 – 当您滑动字幕,影片播放的位置将随字幕文字变化位置同步。 e) 儿童锁 – 让孩童保持专注而不必担心孩子随意拨打电话或接触其他应用程式。 (需要套件) f) ANDROID 4.1 – 完整支援 Android 4.1 Jelly Bean。 *DTS 最大的好处是可以直接播放其他电脑/NAS共享文件。 MX Player Pro 支持字幕格式: – DVD, DVB, SSA/ASS Subtitle tracks. – SubStation Alpha(.ssa/.ass) with full styling. – SAMI(.smi) with ruby tag support. – SubRip(.srt) – MicroDVD(.sub/.txt) – SubViewer2.0(.sub) – MPL2(.mpl/.txt) – PowerDivX(.psb/.txt) – TMPlayer(.txt)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值