其他分享
首页 > 其他分享> > 力扣练习——26 分割数组为连续子序列

力扣练习——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