getOrDefault使用方法
Method Returns
The getOrDefault() method returns the value to which the specified key is mapped, or defaultValue if this map contains no mapping for the key.
当HashMap集合中有这个key时,如果存在则return it,如果没有就使用默认值defaultValue
贪心算法
时间复杂度:O(n)
空间复杂度:O(n)
使用两个哈希表,第一个哈希表存储数组中的每个数字的剩余次数,第二个哈希表存储数组中的每个数字作为结尾的子序列的数量。
初始时,每个数字的剩余次数即为每个数字在数组中出现的次数,因此遍历数组,初始化第一个哈希表。
在初始化第一个哈希表之后,遍历数组,更新两个哈希表。只有当一个数字的剩余次数大于 00 时,才需要考虑这个数字是否属于某个子序列。假设当前元素是 xx,进行如下操作。
首先判断是否存在以 x-1x−1 结尾的子序列,即根据第二个哈希表判断 x-1x−1 作为结尾的子序列的数量是否大于 00,如果大于 00,则将元素 xx 加入该子序列中。由于 xx 被使用了一次,因此需要在第一个哈希表中将 xx 的剩余次数减 11。又由于该子序列的最后一个数字从 x-1x−1 变成了 xx,因此需要在第二个哈希表中将 x-1x−1 作为结尾的子序列的数量减 11,以及将 xx 作为结尾的子序列的数量加 11。
否则,xx 为一个子序列的第一个数,为了得到长度至少为 33 的子序列,x+1x+1 和 x+2x+2 必须在子序列中,因此需要判断在第一个哈希表中 x+1x+1 和 x+2x+2 的剩余次数是否都大于 00。
当 x+1x+1 和 x+2x+2 的剩余次数都大于 00 时,可以新建一个长度为 33 的子序列 [x,x+1,x+2][x,x+1,x+2]。由于这三个数都被使用了一次,因此需要在第一个哈希表中将这三个数的剩余次数分别减 11。又由于该子序列的最后一个数字是 x+2x+2,因此需要在第二个哈希表中将 x+2x+2 作为结尾的子序列的数量加 11。
否则,无法得到长度为 33 的子序列 [x,x+1,x+2][x,x+1,x+2],因此无法完成分割,返回 false。
如果整个数组遍历结束时,没有遇到无法完成分割的情况,则可以完成分割,返回true。
class Solution {
public boolean isPossible(int[] nums) {
Map<Integer, Integer> countMap = new HashMap<Integer, Integer>();
Map<Integer, Integer> endMap = new HashMap<Integer, Integer>();
for (int x : nums) {
int count = countMap.getOrDefault(x, 0) + 1;
countMap.put(x, count);
}
for (int x : nums) {
int count = countMap.getOrDefault(x, 0);
if (count > 0) {
int prevEndCount = endMap.getOrDefault(x - 1, 0);
if (prevEndCount > 0) {
countMap.put(x, count - 1);
endMap.put(x - 1, prevEndCount - 1);
endMap.put(x, endMap.getOrDefault(x, 0) + 1);
} else {
int count1 = countMap.getOrDefault(x + 1, 0);
int count2 = countMap.getOrDefault(x + 2, 0);
if (count1 > 0 && count2 > 0) {
countMap.put(x, count - 1);
countMap.put(x + 1, count1 - 1);
countMap.put(x + 2, count2 - 1);
endMap.put(x + 2, endMap.getOrDefault(x + 2, 0) + 1);
} else {
return false;
}
}
}
}
return true;
}
}