|
| 1 | +/** |
| 2 | + * [128] Longest Consecutive Sequence |
| 3 | + * |
| 4 | + * Given an unsorted array of integers, find the length of the longest consecutive elements sequence. |
| 5 | + * |
| 6 | + * Your algorithm should run in O(n) complexity. |
| 7 | + * |
| 8 | + * Example: |
| 9 | + * |
| 10 | + * |
| 11 | + * Input: [100, 4, 200, 1, 3, 2] |
| 12 | + * Output: 4 |
| 13 | + * Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4. |
| 14 | + * |
| 15 | + * |
| 16 | + */ |
| 17 | +pub struct Solution {} |
| 18 | + |
| 19 | +// submission codes start here |
| 20 | + |
| 21 | +/* |
| 22 | + 要找到连续子串, 基本策略就是对每个 num, 判断 num+1, num+2, num+3... 是否在数组中, 直到不再连续 |
| 23 | +
|
| 24 | + 工程里写的话用排序是最清晰可维护的(需求变了很好改), 排序之后查找 num+1 是否存在就只需要 O(1) 的复杂度了: |
| 25 | + 看下一个元素是不是 num+1 即可 |
| 26 | +
|
| 27 | + 但题目一定要求 O(N) 的解法, 只能想些奇怪的办法了, HashSet 也能达到 O(1) 的查找效率. 但假如对每个元素 |
| 28 | + 都做一遍, 最差就是 O(N^2) 了, 可以发现对于一个连续序列 1,2,3,4,5,6 我们从 1 开始查就能找到这个序列, |
| 29 | + 从 2,3,4,5,6 开始查都是在做重复计算, 因此对于一个 num, 假如 num-1 存在于 HashSet 中, 我们就不需要考虑 |
| 30 | + 它了, 因为它是一次重复的计算. |
| 31 | + */ |
| 32 | +use std::collections::HashSet; |
| 33 | +impl Solution { |
| 34 | + pub fn longest_consecutive(nums: Vec<i32>) -> i32 { |
| 35 | + let mut max = 0; |
| 36 | + let nums = nums.into_iter().collect::<Vec<_>>(); |
| 37 | + for &num in nums.iter() { |
| 38 | + if !nums.contains(&(num-1)) { |
| 39 | + let mut curr = num; |
| 40 | + let mut curr_max = 1; |
| 41 | + while nums.contains(&(curr+1)) { |
| 42 | + curr += 1; curr_max += 1; |
| 43 | + } |
| 44 | + max = i32::max(curr_max, max); |
| 45 | + } |
| 46 | + } |
| 47 | + max |
| 48 | + } |
| 49 | +} |
| 50 | + |
| 51 | +// submission codes end |
| 52 | + |
| 53 | +#[cfg(test)] |
| 54 | +mod tests { |
| 55 | + use super::*; |
| 56 | + |
| 57 | + #[test] |
| 58 | + fn test_128() { |
| 59 | + assert_eq!(Solution::longest_consecutive(vec![100,4,200,1,3,2]), 4) |
| 60 | + } |
| 61 | +} |
0 commit comments