版权声明:本文为博主原创文章,未经博主允许不得转载。 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:
- 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;
}
}