zoukankan      html  css  js  c++  java
  • Leetcode 659 分割数组为连续子序列 (贪心)

    题目描述:

      输入一个按升序排序的整数数组(可能包含重复数字),你需要将它们分割成几个子序列,其中每个子序列至少包含三个连续整数。要求判断你能够完成上述要求的划分。

    题解:

      我们需要两个map,一个用来记录$key$出现的次数,记为mp;一个用来记录以$key$为结尾的合法序列的个数,记为$tail$。为了尽可能的使划分成立,我们期望新加入的数字尽可能多的加入到已经合法的序列中,因为只有重新建立一个新的序列才会导致不符合情况的划分出现。那么我们对于顺序遍历的数有如下操作

      1)通过$tail$尽可能多的把数加入已经合法的序列中。

      2)新建一个合法序列,这里只新建长度为3的初始序列,如果无法新建则return false

    AC代码:

      

    class Solution {
    public:
        // 贪心的一个处理方式
        bool isPossible(vector<int>& nums) {
            map<int,int> mp;
            unordered_map<int,int> tail;
            // int len = nums.size();
            int ans = 0;
            for(auto & num:nums) mp[num]++;
            for(auto& [key,value]:mp)
            {
                if(tail.find(key-1) != tail.end())
                {
                    int tmp = min(value,tail[key-1]);
                    tail[key-1] -= tmp;
                    tail[key] += tmp;
                    value -= tmp;
                }
                // 如果每法通过之前的序列处理 新建一个
                if(value > 0)
                {
                    if(mp.find(key+1) == mp.end() || mp[key+1] == 0) return false;
                    if(mp.find(key+2) == mp.end() || mp[key+2] == 0) return false;
                    int tmp = min(mp[key+1],mp[key+2]);
                    if(tmp < value) return false;
                    value = 0;
                    mp[key+1] -= tmp;
                    mp[key+2] -= tmp;
                    tail[key+2] += tmp;
                    // tmp = min(tmp,value);
    
                }
            }
            return true;
        }
    };
  • 相关阅读:
    java根据汉字获取全拼和首字母
    SQL 增加或删除一列
    C#实现WinForm传值实例解析
    C# 静态类与非静态类、静态成员的区别分析
    c# 面相对象1-概括
    c# 面相对象2-之封装性
    c# 面相对象3-之继承性
    面向对象基础知识(含义、修饰符、三大特性)
    c# 面相对象4-多态性
    用集合求平均分
  • 原文地址:https://www.cnblogs.com/z1141000271/p/12874498.html
Copyright © 2011-2022 走看看