Leetcode659。配列を連続したサブシーケンスに分割します

Leetcode659。配列を連続したサブシーケンスに分割します

質問の語幹

昇順でソートされた整数num(繰り返し数を含む場合があります)の配列を指定します。各サブシーケンスが連続する整数で構成され、長さが3以上の1つ以上のサブシーケンスに分割してください。
上記のセグメンテーションを完了できる場合はtrueを返し、そうでない場合はfalseを返します。

例1:
入力:[1,2,3,3,4,5]
出力:True
説明:
2つの連続するサブシーケンスをセグメント化できます:
1、2、3
3、4、5

実施例2:
入力:[1,2,3,3,4,4,5,5]
出力:真の
説明:
ことはできセグメント二つの連続するサブ:
1、2、3、4、5
3、4、5

例3:
入力:[1,2,3,4,4,5]
出力:False

ヒント:
入力配列の長さは[1、10000]です。

回答

直観的には理解できたものの、合格できなかった初版は、高さの始点を更新する際に適切に処理されませんでした。
写真を見てください。

class Solution {
    
    
public:
    bool isPossible(vector<int>& nums) {
    
    
        int n = nums.size();
        if(n <= 2){
    
    
            return false;
        }
        vector<int> pileHeight(n);
        int prePileValue = 1,currentPileValue = 0;
        int samePileCount = 1;
        int pileCount = 0;
        pileHeight[1] = 0;
        for(int i = 1 ; i < n ; ++i){
    
    
            if(nums[i] != nums[i-1]){
    
    
                pileHeight[1] = i;
            }
            //出现了前一个数不同的数
            if(nums[i] != nums[i-1]){
    
    
                //结算上一个堆的大小,堆数+1
                pileCount++;
                //高度上升,记录起点
                if(currentPileValue > prePileValue){
    
    
                    for(int j = prePileValue ; j <= currentPileValue ; ++j){
    
    
                        pileHeight[currentPileValue] = pileCount;
                    }
                }else if(currentPileValue < prePileValue){
    
    
                    //高度下降,获得等高宽度
                    //处理峰顶的情况
                    if(samePileCount < 3){
    
    
                        return false;
                    }
                    if(pileCount - pileHeight[currentPileValue] + 1 < 3){
    
    
                        return false;
                    }
                    currentPileValue = 1;
                }else{
    
    
                    //高度相等
                    samePileCount++;
                    currentPileValue = 1;
                }
            }else{
    
    
                currentPileValue++;
            }
        }
        //处理弹出循环的情况,即最后一个堆没有结算的情况。此时又有
        if(currentPileValue > prePileValue){
    
    
            return false;
        }else{
    
    
            if(n - pileHeight[currentPileValue] < 3){
    
    
                return false;
            }else{
    
    
                return true;
            }
        }
    }
};
/*
    猜测算法:
        一个连续子序列在重复数字第一次减少时终止,比如:
            1 2 3 3 4 4 5 6
            即分为1 2 3 4 和 4 5 6

            1 2 3 3 3 4 4 4 5 5 6 6 7
            分为 1 2 3 4、3 4 5 6、3 4 5 6 7
            (第一个1234分出来后34的重复次数减小为2了,所以跟67相同)

            1 2 3 3 4 5

            1 1 2 2 3 3 4
        归纳出更为简单的规律:记某个数字重复出现的次数为X,则对于每个数字,有数列Xn。对于Xn,对于任意连续的若干项,若相同值的项数存在<3的情况则无法分割。

        记某个数字重复出现的次数为X,则对于每个数字有数列Xn,将数列图像化为直方图,高度代表每个数出现的次数。从图像上理解,分割出的连续子序列,相当于
        在直方图上某一高度截取的几个值的宽度大于等于3的一段,而且这几个值同高度的部分一定是连续的。

        所以开辟数组,当高度上升时,存放某个高度的起点,高度下降时,比较相同高度的起点,若宽度<3则不可分割
*/

問題の公式ソリューションを参照し、ハッシュテーブルの機能を使用してキーを介して直接アクセスし、ハッシュテーブルを使用し
て各番号の出現回数を格納します。番号の前の番号で終わるサブシーケンスがある場合は、これ末尾に数字が追加されます。
存在しない場合は、この番号の最後の2つの番号を確認し、未使用の最後の2つの番号がある場合は、長さ3の新しいサブシーケンスを作成します。
ハッシュテーブルの特性上、境界条件を気にする必要はありません。

class Solution {
    
    
public:
    bool isPossible(vector<int>& nums) {
    
    
        int n = nums.size();
        unordered_map<int,int> num;
        unordered_map<int,int> end;
        if(n <= 2){
    
    
            return false;
        }
        for(auto i : nums){
    
    
            num[i]++;
        }
        for(auto i : nums){
    
    
            //i没被用完
            if(num[i] > 0){
    
    
                //存在以i-1为结尾的子序列
                if(end[i-1] > 0){
    
    
                    end[i-1]--;
                    end[i]++;
                    num[i]--;
                }else{
    
    
                    //不存在以i-1为结尾的子序列,只能新开辟一个子序列。查询i+1 i+2是否被用尽
                    if(num[i+1] > 0 && num[i+2] > 0){
    
    
                        num[i]--;
                        num[i+1]--;
                        num[i+2]--;
                        end[i+2]++;
                    }else{
    
    
                        return false;
                    }
                }
            }
        
        }
        return true;
    }
};

おすすめ

転載: blog.csdn.net/weixin_43662405/article/details/110671608