LeetCode 659 Split Array into Consecutive Subsequences (hash 思维 推荐)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Tc_To_Top/article/details/88938832

You are given an integer array sorted in ascending order (may contain duplicates), you need to split them into several subsequences, where each subsequences consist of at least 3 consecutive integers. Return whether you can make such a split.

Example 1:

Input: [1,2,3,3,4,5]
Output: True
Explanation:
You can split them into two consecutive subsequences : 
1, 2, 3
3, 4, 5

Example 2:

Input: [1,2,3,3,4,4,5,5]
Output: True
Explanation:
You can split them into two consecutive subsequences : 
1, 2, 3, 4, 5
3, 4, 5

Example 3:

Input: [1,2,3,4,4,5]
Output: False

Note:

  1. The length of the input is in range of [1, 10000]

题目链接:https://leetcode.com/problems/split-array-into-consecutive-subsequences/

题目分析:用两个hashmap,freq[x]表示数字x出现的次数,lastCnt[x]表示以x结尾的consecutive subsequence的个数,对于数字nums[i]来说,若其频数等于0则跳过,否则存在两种情况,a)nums[i]可以接到某个已存在的consecutive subsequence之后,b)nums[i]组成一个新的consecutive subsequence,但前提是nums[i]+1和nums[i]+2的频数均不为0,若不满足这两种情况,则无解,两种情况下必须优先接已存在的序列(e.g. [1,2,3,4,5,5,6,7])

32ms,时间击败77.5%

class Solution {
    public boolean isPossible(int[] nums) {
        HashMap<Integer, Integer> freq = new HashMap<>();
        HashMap<Integer, Integer> lastCnt = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            add(freq, nums[i], 1);
        }
        for (int i = 0; i < nums.length; i++) {
            if (!has(freq, nums[i])) {
                continue;
            }
            if (has(lastCnt, nums[i] - 1)) {
                add(lastCnt, nums[i] - 1, -1);
                add(lastCnt, nums[i], 1);
            } else if (has(freq, nums[i] + 1) && has(freq, nums[i] + 2)) {
                add(freq, nums[i] + 1, -1);
                add(freq, nums[i] + 2, -1);
                add(lastCnt, nums[i] + 2, 1);
            } else {
                return false;
            }
            add(freq, nums[i], -1);
        }
        return true;
    }
    
    public void add(HashMap<Integer, Integer> mp, int key, int value) {
        mp.put(key, mp.getOrDefault(key, 0) + value);
    }
    
    public boolean has(HashMap<Integer, Integer> mp, int value) {
        return mp.containsKey(value) && mp.get(value) > 0;
    }
}

改成数组,4ms,时间击败99.47%,最优做法是三个变量滚动

class Solution {
    public boolean isPossible(int[] nums) {
        int mi = nums[0];
        int ma = nums[nums.length - 1];
        int[] freq = new int[2 * ma - mi + 3];
        int[] lastCnt = new int[2 * ma - mi + 3];
        for (int i = 0; i < nums.length; i++) {
            freq[ma - mi + nums[i]]++;
        }
        for (int i = 0; i < nums.length; i++) {
            if (freq[ma - mi + nums[i]] == 0) {
                continue;
            }
            if (lastCnt[ma - mi + nums[i] - 1] > 0) {
                lastCnt[ma - mi + nums[i] - 1]--;
                lastCnt[ma - mi + nums[i]]++;
            } else if (freq[ma - mi + nums[i] + 1] > 0 && freq[ma - mi + nums[i] + 2] > 0) {
                freq[ma - mi + nums[i] + 1]--;
                freq[ma - mi + nums[i] + 2]--;
                lastCnt[ma - mi + nums[i] + 2]++;
            } else {
                return false;
            }
            freq[ma - mi + nums[i]]--;
        }
        return true;
    }
}

猜你喜欢

转载自blog.csdn.net/Tc_To_Top/article/details/88938832