763. 劃分字母區間
知識點:貪心、指針
時間:2020年10月22日
題目連結:https://leetcode-cn.com/problems/partition-labels/
題目
字元串 S 由小寫字母組成。我們要把這個字元串劃分為盡可能多的片段,同一個字母隻會出現在其中的一個片段。傳回一個表示每個字元串片段的長度的清單。
示例 1:
輸入
S = “ababcbacadefegdehijhklij”
輸出:
[9,7,8]
解釋:
劃分結果為 “ababcbaca”, “defegde”, “hijhklij”。
每個字母最多出現在一個片段中。
像 “ababcbacadefegde”, “hijhklij” 的劃分是錯誤的,因為劃分的片段數較少。
提示:
- S的長度在[1, 500]之間。
- S隻包含小寫字母 ‘a’ 到 ‘z’ 。
解法
方法一:
- 周遊字元串 找到每個字元開始以及結束的位置
- 對這些字元按照 開始位置小的排序
- 使用貪心的思想,周遊每個字元結構體
- 如果接下來的字元start位置已經超過現在的end位置,這個開始位置到結束位置的距離放入答案
- 如果這個字元end位置比現在的end位置大,更新,切的距離變多
a[0,8] b[1,5] c[4,7] start = 0 end = 8
d[9,14] e[10,15] f[11,11] g[13,13] start = 9 end = 15
h[16,19] i[17,22] j[18,23] k[20,20] l[21,21] start = 16 end = 23
方法二:
- 周遊字元串 找到每個字元結束的位置
- 從左到右周遊字元串 對于每個通路到的字母x,切分的位置end一定要大于等于他最後結束的位置x_end,更新标記end=max(end,x_end)
- 如果通路到結束位置,說明這段結束,放入答案
代碼
#include <stdio.h>
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
struct node{
int start;
int end;
node():start(600),end(600){}//初始化為最大值 題中S長度最大為500
node(int s,int e):start(s),end(e){}
};
bool cmp(struct node x,struct node y){
return x.start < y.start;
}
class Solution {
public:
vector<int> partitionLabels(string S) {
vector<int> ans;
vector<node> dic(26);
for(int i = 0; i < S.length();i++){
int index = S[i] - 'a';
//如果第一次讀到此字元
if(dic[index].start == 600 && dic[index].end == 600){dic[index].start = i;dic[index].end = i;}
else if(dic[index].start > i){dic[index].start = i;}
else if(dic[index].end < i ){dic[index].end = i;}
}
//按照第一次出現的位置排序
sort(dic.begin(), dic.end(),cmp);
int begin = dic[0].start, end = dic[0].end;
for(int i=1;i<26;i++){
//如果接下來的字元start位置已經超過現在的end位置,這個開始位置到結束位置的距離放入答案
if(dic[i].start > end){
ans.emplace_back(end-begin+1);
begin = dic[i].start;
end = dic[i].end;
//如果這個字元end位置比現在的end位置大,更新,切的距離變多
}else if(dic[i].end > end){
end = dic[i].end;
}
}
//注意邊界
if(end-begin!=0)
ans.emplace_back(end-begin+1);
return ans;
}
};
/*
class Solution {
public:
vector<int> partitionLabels(string S) {
int last[26];
for (int i = 0; i < S.length(); i++) {
last[S[i]-'a'] = i;
}
vector<int> ans;
int start = 0, end = 0;
for (int i = 0; i < S.length(); i++) {
end = max(end, last[S[i] - 'a']);
if (i == end) {
ans.emplace_back(end - start + 1);
start = end + 1;
}
}
return ans;
}
};
*/
int main()
{
string S{"ababcbacadefegdehijhklij"};
Solution s;
vector<int> ans = s.partitionLabels(S);
for(int x:ans)
cout<<x<<endl;
return 0;
}
今天也是愛zz的一天哦!