https://leetcode-cn.com/problems/longest-consecutive-sequence/

    优化思路:

    1. 暴力法最容易想到,然后对暴力法优化。
    2. 发现【1】的“contains()”函数时间复杂度高,根据“查询勤用Hash表的思路”和题目自身的特点,使用HashSet即可。
    3. 针对【2】的循环中,如【1,2,3,4,5】的特点,其实遍历了一遍之后,以“2”开头的遍历思路其实与“1”开头的一样,只不过数值加一,因此,提出当前Set中包含当前遍历数字的前驱时,即放弃遍历。
    1. class Solution {
    2. public int longestConsecutive(int[] nums) {
    3. // 进一步优化:既然存在大量重复辨别,使用 前驱 来帮助跳过重复
    4. // 遍历到当前数字时,只要 HsehSet 中的 "当前数字 - 1" 存在,就跳过
    5. int maxLen = 0;
    6. // 定义一个 HashSet,保存所有出现的数值
    7. HashSet<Object> hashSet = new HashSet<>();
    8. // 遍历一遍所有元素
    9. for (int num : nums) {
    10. hashSet.add(num);
    11. }
    12. // 遍历数组,以每个元素作为起始点,寻找连续序列
    13. for (int i = 0; i < nums.length; i++) {
    14. // 当前元素作为起始点
    15. int curNum = nums[i];
    16. // 保存当前连续子序列长度
    17. int curLen = 1;
    18. // 只有在当前元素的前驱不存在的情况下,才去进行寻找连续序列的操作
    19. if (!hashSet.contains(curNum - 1)) {
    20. // 寻找后续数字
    21. while (hashSet.contains(curNum + 1)) {
    22. curLen++;
    23. curNum++;
    24. }
    25. maxLen = curLen > maxLen ? curLen : maxLen;
    26. }
    27. }
    28. return maxLen;
    29. }
    30. }
    1. public int longestConsecutiveAdvanced(int[] nums) {
    2. // 暴力法优化:contains 函数的功能交给 HashSet 来执行,降低时间复杂度
    3. // 思路几乎一样,不过先使用一次遍历来一劳永逸地将数据存入 HashSet,便于后面使用
    4. int maxLen = 0;
    5. // 定义一个 HashSet,保存所有出现的数值
    6. HashSet<Object> hashSet = new HashSet<>();
    7. // 遍历一遍所有元素
    8. for (int num : nums) {
    9. hashSet.add(num);
    10. }
    11. // 遍历数组,以每个元素作为起始点,寻找连续序列
    12. for (int i = 0; i < nums.length; i++) {
    13. // 当前元素作为起始点
    14. int curNum = nums[i];
    15. // 保存当前连续子序列长度
    16. int curLen = 1;
    17. // 寻找后续数字
    18. while (hashSet.contains(curNum + 1)) {
    19. curLen++;
    20. curNum++;
    21. }
    22. maxLen = curLen > maxLen ? curLen : maxLen;
    23. }
    24. return maxLen;
    25. }
    1. public int longestConsecutive(int[] nums) {
    2. // 暴力法:时间复杂度过高
    3. // 定义一个长度,保持当前最长连续序列的长度
    4. int maxLen = 0;
    5. // 遍历数组,以每个元素作为起始点,寻找连续序列
    6. for (int i = 0; i < nums.length; i++) {
    7. // 当前元素作为起始点
    8. int curNum = nums[i];
    9. // 保存当前连续子序列长度
    10. int curLen = 1;
    11. // 寻找后续数字,只有当前 nums 继续包含 [ 当前数 + 1 ],就继续,同时长度++
    12. while (contains(nums, curNum + 1)) {
    13. curLen++;
    14. curNum++;
    15. }
    16. maxLen = curLen > maxLen ? curLen : maxLen;
    17. }
    18. return maxLen;
    19. }
    20. public boolean contains(int[] nums, int x) {
    21. // 定义一个方法,用于在数组中寻找某个元素
    22. for (int num : nums) {
    23. if (num == x) {
    24. return true;
    25. }
    26. }
    27. return false;
    28. }