力扣练习——26 分割数组为连续子序列
作者:互联网
1.问题描述
给你一个按升序排序的整数数组 num(可能包含重复数字),请你将它们分割成一个或多个子序列,其中每个子序列都由连续整数组成且长度至少为 3 。
一个子序列是从原始数组挑选一部分(也可以全部)元素而不改变相对位置形成的新数组
如果可以完成上述分割,则返回 true ;否则,返回 false 。
示例 1:
输入: [1,2,3,3,4,5]
输出: True
解释:
你可以分割出这样两个连续子序列 :
1, 2, 3
3, 4, 5
示例 2:
输入: [1,2,3,3,4,4,5,5]
输出: True
解释:
你可以分割出这样两个连续子序列 :
1, 2, 3, 4, 5
3, 4, 5
示例 3:
输入: [1,2,3,4,4,5]
输出: False
说明:
输入的数组长度范围为 [1, 10000]
2.输入说明
首先输入num的长度n,然后输入n个整数
3.输出说明
输出“true”或“false”,不包括引号。
4.范例
输入
8
1 2 3 3 4 4 5 5
输出
true
5.代码
#include<iostream> #include<vector> #include<string> #include<algorithm> #include<unordered_map> using namespace std; bool isPossible(vector<int>& nums) { //1.使用两个哈希表nc和tail //cnt[i] 存储原数组中数字i出现的次数 //tail[i]存储以i结尾且符合题意的连续子序列的个数 unordered_map<int, int> cnt, tail;//unordered_map:其实现使用的是哈希表 ;而 map实现使用的是红黑树 //2.统计出现次数 for (auto num : nums) cnt[num]++; //3.遍历 只有检查到某个数时,这个数未被消耗完,且既不能和前面组成连续子序列,也不能和后面组成连续子序列时,无法分割 for (auto num : nums) { if (cnt[num] == 0) continue; else if (cnt[num] > 0 && tail[num - 1] > 0) //tail[num-1]>0表示前面的连续子序列的尾部到num-1 ;如果此时 num 至少有一个 ,则可以延申该子序列 { cnt[num]--;//num出现次数减一 tail[num - 1]--;//以num-1结尾的连续子序列个数减一 tail[num]++;//以num结尾的连续子序列个数加一 } else if (cnt[num] > 0 && cnt[num + 1] > 0 && cnt[num + 2] > 0) //存在连续子序列 { cnt[num]--; cnt[num + 1]--; cnt[num + 2]--; tail[num + 2]++; } else return false; } return true; } int main() { int n,tmp; cin >> n; vector<int>nums; for (int i = 0; i < n; i++) { cin >> tmp; nums.push_back(tmp); } bool res = isPossible(nums); //true返回值为1 false 返回值为0 res == 1 ? (cout << "true") : (cout << "false"); return 0; }
标签:26,--,cnt,力扣,tail,num,数组,序列,include 来源: https://www.cnblogs.com/juillard/p/16484786.html