5018.驼峰式匹配
题目描述
如果我们可以将小写字母插入模式串 pattern
得到待查询项 query
,那么待查询项与给定模式串匹配。(我们可以在任何位置插入每个字符,也可以插入 0 个字符。)
给定待查询列表 queries
,和模式串 pattern
,返回由布尔值组成的答案列表 answer
。只有在待查项 queries[i]
与模式串 pattern
匹配时, answer[i]
才为 true
,否则为 false
。
示例1:
输入:queries = ["FooBar","FooBarTest","FootBall","FrameBuffer","ForceFeedBack"], pattern = "FB"
输出:[true,false,true,true,false]
示例:
"FooBar" 可以这样生成:"F" + "oo" + "B" + "ar"。
"FootBall" 可以这样生成:"F" + "oot" + "B" + "all".
"FrameBuffer" 可以这样生成:"F" + "rame" + "B" + "uffer".
示例2:
输入:queries = ["FooBar","FooBarTest","FootBall","FrameBuffer","ForceFeedBack"], pattern = "FoBa"
输出:[true,false,true,false,false]
解释:
"FooBar" 可以这样生成:"Fo" + "o" + "Ba" + "r".
"FootBall" 可以这样生成:"Fo" + "ot" + "Ba" + "ll".
示例3:
输出:queries = ["FooBar","FooBarTest","FootBall","FrameBuffer","ForceFeedBack"], pattern = "FoBaT"
输入:[false,true,false,false,false]
解释:
"FooBarTest" 可以这样生成:"Fo" + "o" + "Ba" + "r" + "T" + "est".
提示:
1 <= queries.length <= 100
1 <= queries[i].length <= 100
1 <=pattern.length <= 100
- 所有字符串都仅由大写和小写英文字母组成。
参考思路
采用暴力匹配模式。指定两个指针i
和j
,i
指向pattern
,j
指向queries
中的一个字符串的某个位置。三条匹配规则如下:
- queries大写字符一定要匹配
- queries小写字母不一定要匹配
- pattern中所有字母一定要匹配
具体逻辑见参考代码
参考代码
class Solution {
public:
vector<bool> camelMatch(vector<string>& queries, string pattern)
{
vector<bool> ans;
ans.clear();
int n=pattern.length();
for(auto str:queries)
{
int m=str.length(),j=0,i=0;
bool flag=true;
for(i=j=0;i<n&&j<m;)
{
while(j<m&&str[j]!=pattern[i]&&'a'<=str[j]&&str[j]<='z')
j++;
if(j>=m)
break;
if(str[j]!=pattern[i])
break;
++j;++i;
}
flag=(i==n);
for(;j<m&&flag;++j)
flag=flag&&('a'<=str[j]&&str[j]<='z'); //如果str还有大写字母,那flag最终为false
ans.push_back(flag);
}
return ans;
}
};
5019.视频拼接
题目描述
你将会获得一系列视频片段,这些片段来自于一项持续时长为 T
秒的体育赛事。这些片段可能有所重叠,也可能长度不一。
视频片段 clips[i]
都用区间进行表示:开始于 clips[i][0]
并于 clips[i][1]
结束。我们甚至可以对这些片段自由地再剪辑,例如片段 [0, 7]
可以剪切成 [0, 1] + [1, 3] + [3, 7]
三部分。
我们需要将这些片段进行再剪辑,并将剪辑后的内容拼接成覆盖整个运动过程的片段([0, T]
)。返回所需片段的最小数目,如果无法完成该任务,则返回 -1
。
示例1:
输入:clips = [[0,2],[4,6],[8,10],[1,9],[1,5],[5,9]], T = 10
输出:3
解释:
我们选中 [0,2], [8,10], [1,9] 这三个片段。
然后,按下面的方案重制比赛片段:
将 [1,9] 再剪辑为 [1,2] + [2,8] + [8,9] 。
现在我们手上有 [0,2] + [2,8] + [8,10],而这些涵盖了整场比赛 [0, 10]。
示例2:
输入:clips = [[0,1],[1,2]], T = 5
输出:-1
解释:
我们无法只用 [0,1] 和 [0,2] 覆盖 [0,5] 的整个过程。
示例3:
输入:clips = [[0,1],[6,8],[0,2],[5,6],[0,4],[0,3],[6,7],[1,3],[4,7],[1,4],[2,5],[2,6],[3,4],[4,5],[5,7],[6,9]], T = 9
输出:3
解释:
我们选取片段 [0,4], [4,7] 和 [6,9] 。
示例4:
输入:clips = [[0,4],[2,8]], T = 5
输出:2
解释:
注意,你可能录制超过比赛结束时间的视频。
提示
1 <= clips.length <= 100
0 <= clips[i][0], clips[i][1] <= 100
0 <= T <= 100
参考思路
典型的最小线段覆盖问题。
假设当前已经覆盖了区间[0,now]
,则接下来需找到一个clips[k]
,满足clips[k][0]<=now,clips[k][i]最大
这一贪心策略。
因此需对片段进行排序,按照左端点升序原则进行排序。
参考代码
const int MAXN=100+50;
struct Segment
{
int l,r;
}seg[MAXN];
int n;
inline bool cmp(const Segment &a,const Segment &b)
{
if(a.l==b.l)
return a.r>b.r;
return a.l<b.l;
}
class Solution {
public:
int videoStitching(vector<vector<int>>& clips, int T)
{
n=clips.size();//片段数
for(int i=0;i<n;i++)
{
seg[i].l=clips[i][0];
seg[i].r=clips[i][1];
}
sort(seg,seg+n,cmp);
int now=0,ans=0,i=0;
while(now<T&& i<n)
{
int mx=now;
while(i<n&&seg[i].l<=now)
{
mx=max(mx,seg[i].r);
i++;
}
if(mx==now) //出现断层
break;
now=mx;
ans++;
}
if(now<T)
return -1;
return ans;
}
};