📑 题目:128. 最长连续序列

🚀 本题 LeetCode 传送门

题目大意

给定一个未排序的整数数组,找出最长连续序列的长度。要求算法的时间复杂度为 O(n)。

解题思路

  • 给出一个数组,要求找出最长连续序列,输出这个最长的长度。要求时间复杂度为 O(n)
  • 这一题可以先用暴力解决解决,代码见解法三。思路是把每个数都存在 map 中,先删去 map 中没有前一个数 nums[i]-1 也没有后一个数 nums[i]+1 的数 nums[i],这种数前后都不连续。然后在 map 中找到前一个数 nums[i]-1 不存在,但是后一个数 nums[i]+1 存在的数,这种数是连续序列的起点,那么不断的往后搜,直到序列“断”了。最后输出最长序列的长度。
  • 这一题最优的解法是解法一,针对每一个 map 中不存在的数 n,插入进去都做 2 件事情。第一件事,先查看 n - 1n + 1 是否都存在于 map 中,如果都存在,代表存在连续的序列,那么就更新 leftright 边界。那么 n 对应的这个小的子连续序列长度为 sum = left + right + 1。第二件事就是更新 leftright 左右边界对应的 length = sum
  • 这一题还可以用并查集解决,见解法二。利用每个数在 nums 中的下标,把下标和下标进行 union(),具体做法是看前一个数 nums[i]-1 和后一个数 nums[i]+1map 中是否存在,如果存在就 union(),最终输出整个并查集中包含最多元素的那个集合的元素总数。

代码

  1. package leetcode
  2. import (
  3. ""github.com/halfrost/LeetCode-Go/template""
  4. )
  5. // 解法一 map,时间复杂度 O(n)
  6. func longestConsecutive(nums []int) int {
  7. res, numMap := 0, map[int]int{}
  8. for _, num := range nums {
  9. if numMap[num] == 0 {
  10. left, right, sum := 0, 0, 0
  11. if numMap[num-1] > 0 {
  12. left = numMap[num-1]
  13. } else {
  14. left = 0
  15. }
  16. if numMap[num+1] > 0 {
  17. right = numMap[num+1]
  18. } else {
  19. right = 0
  20. }
  21. // sum: length of the sequence n is in
  22. sum = left + right + 1
  23. numMap[num] = sum
  24. // keep track of the max length
  25. res = max(res, sum)
  26. // extend the length to the boundary(s) of the sequence
  27. // will do nothing if n has no neighbors
  28. numMap[num-left] = sum
  29. numMap[num+right] = sum
  30. } else {
  31. continue
  32. }
  33. }
  34. return res
  35. }
  36. // 解法二 并查集
  37. func longestConsecutive1(nums []int) int {
  38. if len(nums) == 0 {
  39. return 0
  40. }
  41. numMap, countMap, lcs, uf := map[int]int{}, map[int]int{}, 0, template.UnionFind{}
  42. uf.Init(len(nums))
  43. for i := 0; i < len(nums); i++ {
  44. countMap[i] = 1
  45. }
  46. for i := 0; i < len(nums); i++ {
  47. if _, ok := numMap[nums[i]]; ok {
  48. continue
  49. }
  50. numMap[nums[i]] = i
  51. if _, ok := numMap[nums[i]+1]; ok {
  52. uf.Union(i, numMap[nums[i]+1])
  53. }
  54. if _, ok := numMap[nums[i]-1]; ok {
  55. uf.Union(i, numMap[nums[i]-1])
  56. }
  57. }
  58. for key := range countMap {
  59. parent := uf.Find(key)
  60. if parent != key {
  61. countMap[parent]++
  62. }
  63. if countMap[parent] > lcs {
  64. lcs = countMap[parent]
  65. }
  66. }
  67. return lcs
  68. }
  69. // 解法三 暴力解法,时间复杂度 O(n^2)
  70. func longestConsecutive2(nums []int) int {
  71. if len(nums) == 0 {
  72. return 0
  73. }
  74. numMap, length, tmp, lcs := map[int]bool{}, 0, 0, 0
  75. for i := 0; i < len(nums); i++ {
  76. numMap[nums[i]] = true
  77. }
  78. for key := range numMap {
  79. if !numMap[key-1] && !numMap[key+1] {
  80. delete(numMap, key)
  81. }
  82. }
  83. if len(numMap) == 0 {
  84. return 1
  85. }
  86. for key := range numMap {
  87. if !numMap[key-1] && numMap[key+1] {
  88. length, tmp = 1, key+1
  89. for numMap[tmp] {
  90. length++
  91. tmp++
  92. }
  93. lcs = max(lcs, length)
  94. }
  95. }
  96. return max(lcs, length)
  97. }

**