牛妹的项链
有一个项链共有n个珠子,每个珠子都有一个颜色,这n珠子构建成一个环,牛妹想要一段最长的珠子其中同一个颜色不出现两次。
案例
输入:4,[3,1,1,2]
返回值:3
说明:
牛妹可以选择在第3个珠子的左边和右边各切一刀,截取第4个,第1个和第2个珠子连起来的连续珠子。
方法一 暴力
遍历a中的每一个珠子i,每次从第i个珠子开始往后遍历记录最长不重复颜色的珠子长度。
class Solution {
public:
int solve(int n, vector<int>& a) {
// write code here
int ans = 0;
for(int i = 0; i < n; i ++){
unordered_map<int, bool> vis;
for(int j = i; j < n * 2; j ++){ //从第i个开始统计后面最长能到多少
if(vis[a[j % n]]){ //如果存在则更新
ans = max(ans, (j - 1) - i + 1);
break;
}
vis[a[j % n]] = 1;
}
}
return ans;
}
}; 时间复杂度: 最多会是一整个项链是合法的
空间复杂度: map最多会记录一整个项链的长度
方法二 尺取
定义两个变量l和r表示l到r这一段为合法的项链段,考虑两种情况,一如果把当前遍历到的第r位加入项链中没有出现重复的颜色,那么将答案更新,如果出现重复颜色则将l的位置向前移一位并去除l位的颜色直到没有重复颜色出现为止。
class Solution {
public:
unordered_map<int, int> mp; //标记颜色是否出现
int solve(int n, vector<int>& a) {
// write code here
for(int i = 0; i < n; i ++) a.push_back(a[i]); // 奖a数组翻倍
n *= 2;
int l = 0, r = 0, ans = 0;
for(r = 0; r < n; r ++){
mp[a[r]] ++;
while(l < r && mp[a[r]] > 1) mp[a[l ++]] --; //当前的珠子时如果有重复取则将l不断加到没有重复的情况
ans = max(ans, r - l + 1);
}
return ans;
}
}; 时间复杂度: 在项链全部颜色为相同时最多会遍历2遍项链
空间复杂度: map中最多会标记整个项链的颜色

京公网安备 11010502036488号