594. 最長(zhǎng)和諧子序列
和諧數(shù)組是指一個(gè)數(shù)組里元素的最大值和最小值之間的差別 正好是 1
。
現(xiàn)在,給你一個(gè)整數(shù)數(shù)組 nums
,請(qǐng)你在所有可能的子序列中找到最長(zhǎng)的和諧子序列的長(zhǎng)度。
數(shù)組的子序列是一個(gè)由數(shù)組派生出來的序列,它可以通過刪除一些元素或不刪除元素、且不改變其余元素的順序而得到。
示例 1:
輸入:nums = [1,3,2,2,5,2,3,7]
輸出:5
解釋:最長(zhǎng)的和諧子序列是 [3,2,2,2,3]
示例 2:
輸入:nums = [1,2,3,4]
輸出:2
示例 3:
輸入:nums = [1,1,1,1]
輸出:0
方法二:哈希映射
在方法一中,我們枚舉了 x 后,遍歷數(shù)組找出所有的 x 和 x + 1。我們也可以用一個(gè)哈希映射(HashMap)來存儲(chǔ)每個(gè)數(shù)出現(xiàn)的次數(shù),這樣就能在 O(1)O(1) 的時(shí)間內(nèi)得到 x 和 x + 1 出現(xiàn)的次數(shù)。
我們首先遍歷一遍數(shù)組,得到哈希映射。隨后遍歷哈希映射,設(shè)當(dāng)前遍歷到的鍵值對(duì)為 (x, value),那么我們就查詢 x + 1 在哈希映射中對(duì)應(yīng)的值,就得到了 x 和 x + 1 出現(xiàn)的次數(shù)。
方法三:哈希映射 + 單次掃描
在方法二中,我們需要對(duì)數(shù)組進(jìn)行一次掃描,再對(duì)哈希映射進(jìn)行一次掃描。事實(shí)上,我們也可以設(shè)計(jì)出只進(jìn)行一次掃描的算法。
我們掃描一次數(shù)組,當(dāng)掃描到元素 x 時(shí),我們首先將 x 加入哈希映射,隨后獲取哈希映射中 x - 1, x, x + 1 三者出現(xiàn)的次數(shù) u, v, w,那么 u + v 即為 x - 1, x 組成的和諧子序列的長(zhǎng)度,v + w 即為 x, x + 1 組成的和諧子序列的長(zhǎng)度。假設(shè)數(shù)組中最長(zhǎng)的和諧子序列的最后一個(gè)元素在數(shù)組中的位置為 i,那么在掃描到 nums[i] 時(shí),u + v 和 v + w 中一定有一個(gè)就是答案。因此這種方法可以找到最長(zhǎng)的和諧子序列的長(zhǎng)度。
class Solution {
public:
int findLHS(vector<int>& nums) {
unordered_map<int, int> map;
int ans = 0;
for (int i : nums) {
map[i]++;
if(map.count(i - 1))
ans = max(ans, map[i] + map[i - 1]);
if(map.count(i + 1))
ans = max(ans, map[i] + map[i + 1]);
}
return ans;
}
};