classSolution { publicintfindLHS(int[] nums) { Arrays.sort(nums); intbegin=0; intres=0; for (intend=0; end < nums.length; end++) { while (nums[end] - nums[begin] > 1) { begin++; } if (nums[end] - nums[begin] == 1) { res = Math.max(res, end - begin + 1); } } return res; } }
[sol1-C++]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
classSolution { public: intfindLHS(vector<int>& nums){ sort(nums.begin(),nums.end()); int begin = 0; int res = 0; for (int end = 0; end < nums.size(); end++) { while (nums[end] - nums[begin] > 1) { begin++; } if (nums[end] - nums[begin] == 1) { res = max(res, end - begin + 1); } } return res; } };
[sol1-C#]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
publicclassSolution { publicintFindLHS(int[] nums) { Array.Sort(nums); int begin = 0; int res = 0; for (int end = 0; end < nums.Length; end++) { while (nums[end] - nums[begin] > 1) { begin++; } if (nums[end] - nums[begin] == 1) { res = Math.Max(res, end - begin + 1); } } return res; } }
[sol1-Python3]
1 2 3 4 5 6 7 8 9 10
classSolution: deffindLHS(self, nums: List[int]) -> int: nums.sort() res, begin = 0, 0 for end inrange(len(nums)): while nums[end] - nums[begin] > 1: begin += 1 if nums[end] - nums[begin] == 1: res = max(res, end - begin + 1) return res
[sol1-JavaScript]
1 2 3 4 5 6 7 8 9 10 11 12 13 14
var findLHS = function(nums) { nums.sort((a, b) => a - b); let begin = 0; let res = 0; for (let end = 0; end < nums.length; end++) { while (nums[end] - nums[begin] > 1) { begin++; } if (nums[end] - nums[begin] === 1) { res = Math.max(res, end - begin + 1); } } return res; };
[sol1-Golang]
1 2 3 4 5 6 7 8 9 10 11 12 13
funcfindLHS(nums []int) (ans int) { sort.Ints(nums) begin := 0 for end, num := range nums { for num-nums[begin] > 1 { begin++ } if num-nums[begin] == 1 && end-begin+1 > ans { ans = end - begin + 1 } } return }
在方法一中,我们枚举了 x 后,遍历数组找出所有的 x 和 x + 1的出现的次数。我们也可以用一个哈希映射来存储每个数出现的次数,这样就能在 O(1) 的时间内得到 x 和 x + 1 出现的次数。
我们首先遍历一遍数组,得到哈希映射。随后遍历哈希映射,设当前遍历到的键值对为 (x, \textit{value}),那么我们就查询 x + 1 在哈希映射中对应的统计次数,就得到了 x 和 x + 1 出现的次数,和谐子序列的长度等于 x 和 x + 1 出现的次数之和。
代码
[sol2-Java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
classSolution { publicintfindLHS(int[] nums) { HashMap <Integer, Integer> cnt = newHashMap <>(); intres=0; for (int num : nums) { cnt.put(num, cnt.getOrDefault(num, 0) + 1); } for (int key : cnt.keySet()) { if (cnt.containsKey(key + 1)) { res = Math.max(res, cnt.get(key) + cnt.get(key + 1)); } } return res; } }
[sol2-C++]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
classSolution { public: intfindLHS(vector<int>& nums){ unordered_map<int, int> cnt; int res = 0; for (int num : nums) { cnt[num]++; } for (auto [key, val] : cnt) { if (cnt.count(key + 1)) { res = max(res, val + cnt[key + 1]); } } return res; } };
[sol2-C#]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
publicclassSolution { publicintFindLHS(int[] nums) { Dictionary<int, int> dictionary = new Dictionary<int, int>(); int res = 0; foreach (int num in nums) { if (dictionary.ContainsKey(num)) { dictionary[num]++; } else { dictionary.Add(num, 1); } } foreach (int key in dictionary.Keys) { if (dictionary.ContainsKey(key + 1)) { res = Math.Max(res, dictionary[key] + dictionary[key + 1]); } } return res; } }
[sol2-Python3]
1 2 3 4
classSolution: deffindLHS(self, nums: List[int]) -> int: cnt = Counter(nums) returnmax((val + cnt[key + 1] for key, val in cnt.items() if key + 1in cnt), default=0)
[sol2-JavaScript]
1 2 3 4 5 6 7 8 9 10 11 12 13
var findLHS = function(nums) { const cnt = newMap(); let res = 0; for (const num of nums) { cnt.set(num, (cnt.get(num) || 0) + 1); } for (const key of cnt.keys()) { if (cnt.has(key + 1)) { res = Math.max(res, cnt.get(key) + cnt.get(key + 1)); } } return res; };
[sol2-Golang]
1 2 3 4 5 6 7 8 9 10 11 12
funcfindLHS(nums []int) (ans int) { cnt := map[int]int{} for _, num := range nums { cnt[num]++ } for num, c := range cnt { if c1 := cnt[num+1]; c1 > 0 && c+c1 > ans { ans = c + c1 } } return }
复杂度分析
时间复杂度:O(N),其中 N 为数组的长度。
空间复杂度:O(N),其中 N 为数组的长度。数组中最多有 N 个不同元素,因此哈希表最多存储 N 个数据。