From e831ed2be5152da3dcc413903e426268d9535a38 Mon Sep 17 00:00:00 2001
From: yanglbme <szuyanglb@outlook.com>
Date: Fri, 27 Dec 2024 09:19:58 +0800
Subject: [PATCH] feat: add solutions to lc problem: No.0128

No.0128.Longest Consecutive Sequence
---
 solution/0000-0099/0001.Two Sum/README.md     |   3 +-
 solution/0000-0099/0001.Two Sum/README_EN.md  |   3 +-
 solution/0000-0099/0001.Two Sum/Solution.py   |   3 +-
 .../README.md                                 | 238 +++++++++---------
 .../README_EN.md                              | 238 +++++++++---------
 .../Solution.cpp                              |  25 +-
 .../Solution.go                               |  31 ++-
 .../Solution.java                             |  26 +-
 .../Solution.js                               |  24 +-
 .../Solution.py                               |  23 +-
 .../Solution.rs                               |  34 +--
 .../Solution.ts                               |  24 +-
 .../Solution2.cpp                             |   8 +-
 .../Solution2.go                              |   4 +-
 .../Solution2.java                            |   4 +-
 .../Solution2.py                              |   2 +-
 .../Solution2.rs                              |  18 ++
 .../Solution2.ts                              |   2 +-
 18 files changed, 332 insertions(+), 378 deletions(-)
 create mode 100644 solution/0100-0199/0128.Longest Consecutive Sequence/Solution2.rs

diff --git a/solution/0000-0099/0001.Two Sum/README.md b/solution/0000-0099/0001.Two Sum/README.md
index 74e45489db964..f9a38ce75e350 100644
--- a/solution/0000-0099/0001.Two Sum/README.md	
+++ b/solution/0000-0099/0001.Two Sum/README.md	
@@ -85,8 +85,7 @@ class Solution:
     def twoSum(self, nums: List[int], target: int) -> List[int]:
         d = {}
         for i, x in enumerate(nums):
-            y = target - x
-            if y in d:
+            if (y := target - x) in d:
                 return [d[y], i]
             d[x] = i
 ```
diff --git a/solution/0000-0099/0001.Two Sum/README_EN.md b/solution/0000-0099/0001.Two Sum/README_EN.md
index 2e2b638512a97..25b360b51dbb7 100644
--- a/solution/0000-0099/0001.Two Sum/README_EN.md	
+++ b/solution/0000-0099/0001.Two Sum/README_EN.md	
@@ -82,8 +82,7 @@ class Solution:
     def twoSum(self, nums: List[int], target: int) -> List[int]:
         d = {}
         for i, x in enumerate(nums):
-            y = target - x
-            if y in d:
+            if (y := target - x) in d:
                 return [d[y], i]
             d[x] = i
 ```
diff --git a/solution/0000-0099/0001.Two Sum/Solution.py b/solution/0000-0099/0001.Two Sum/Solution.py
index 35a41d01ac455..5764f5daafd0e 100644
--- a/solution/0000-0099/0001.Two Sum/Solution.py	
+++ b/solution/0000-0099/0001.Two Sum/Solution.py	
@@ -2,7 +2,6 @@ class Solution:
     def twoSum(self, nums: List[int], target: int) -> List[int]:
         d = {}
         for i, x in enumerate(nums):
-            y = target - x
-            if y in d:
+            if (y := target - x) in d:
                 return [d[y], i]
             d[x] = i
diff --git a/solution/0100-0199/0128.Longest Consecutive Sequence/README.md b/solution/0100-0199/0128.Longest Consecutive Sequence/README.md
index c760e4fe2d4fc..a70eb4d730473 100644
--- a/solution/0100-0199/0128.Longest Consecutive Sequence/README.md	
+++ b/solution/0100-0199/0128.Longest Consecutive Sequence/README.md	
@@ -53,19 +53,15 @@ tags:
 
 <!-- solution:start -->
 
-### 方法一:排序
+### 方法一:哈希表
 
-我们先将数组排序,然后用一个变量 $t$ 记录当前连续序列的长度,用一个变量 $ans$ 记录最长连续序列的长度。
+我们可以用一个哈希表 $\textit{s}$ 存储数组中所有的元素,用一个变量 $\textit{ans}$ 记录最长连续序列的长度,用一个哈希表 $\textit{d}$ 记录每个元素 $x$ 所在的连续序列的长度。
 
-接下来,我们从下标 $i=1$ 开始遍历数组,对于当前遍历到的元素 $nums[i]$:
+接下来,我们遍历数组中每个元素 $x$,用一个临时变量 $y$ 记录当前连续序列的最大值,初始时 $y = x$。然后,我们不断尝试匹配 $y+1, y+2, y+3, \dots$,直到匹配不到为止,过程中将匹配到的元素从哈希表 $\textit{s}$ 中移除。那么,当前元素 $x$ 所在的连续序列的长度即为 $d[x] = d[y] + y - x$,然后更新答案 $\textit{ans} = \max(\textit{ans}, d[x])$。
 
--   如果 $nums[i]=nums[i-1]$,则说明当前元素重复,无需考虑;
--   如果 $nums[i]=nums[i-1]+1$,则说明当前元素可以接在上一个连续序列后面以形成更长的连续序列,我们更新 $t = t + 1$,然后更新答案 $ans = \max(ans, t)$;
--   否则,说明当前元素无法接在上一个连续序列后面,我们将 $t$ 重新置为 $1$。
+遍历结束后,返回答案 $\textit{ans}$ 即可。
 
-最终,我们返回答案 $ans$ 即可。
-
-时间复杂度 $O(n \times \log n)$,空间复杂度 $O(\log n)$。其中 $n$ 是数组的长度。
+时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $\textit{nums}$ 的长度。
 
 <!-- tabs:start -->
 
@@ -74,19 +70,16 @@ tags:
 ```python
 class Solution:
     def longestConsecutive(self, nums: List[int]) -> int:
-        n = len(nums)
-        if n < 2:
-            return n
-        nums.sort()
-        ans = t = 1
-        for a, b in pairwise(nums):
-            if a == b:
-                continue
-            if a + 1 == b:
-                t += 1
-                ans = max(ans, t)
-            else:
-                t = 1
+        s = set(nums)
+        ans = 0
+        d = defaultdict(int)
+        for x in nums:
+            y = x
+            while y in s:
+                s.remove(y)
+                y += 1
+            d[x] = d[y] + y - x
+            ans = max(ans, d[x])
         return ans
 ```
 
@@ -95,21 +88,19 @@ class Solution:
 ```java
 class Solution {
     public int longestConsecutive(int[] nums) {
-        int n = nums.length;
-        if (n < 2) {
-            return n;
+        Set<Integer> s = new HashSet<>();
+        for (int x : nums) {
+            s.add(x);
         }
-        Arrays.sort(nums);
-        int ans = 1, t = 1;
-        for (int i = 1; i < n; ++i) {
-            if (nums[i] == nums[i - 1]) {
-                continue;
-            }
-            if (nums[i] == nums[i - 1] + 1) {
-                ans = Math.max(ans, ++t);
-            } else {
-                t = 1;
+        int ans = 0;
+        Map<Integer, Integer> d = new HashMap<>();
+        for (int x : nums) {
+            int y = x;
+            while (s.contains(y)) {
+                s.remove(y++);
             }
+            d.put(x, d.getOrDefault(y, 0) + y - x);
+            ans = Math.max(ans, d.get(x));
         }
         return ans;
     }
@@ -122,21 +113,16 @@ class Solution {
 class Solution {
 public:
     int longestConsecutive(vector<int>& nums) {
-        int n = nums.size();
-        if (n < 2) {
-            return n;
-        }
-        sort(nums.begin(), nums.end());
-        int ans = 1, t = 1;
-        for (int i = 1; i < n; ++i) {
-            if (nums[i] == nums[i - 1]) {
-                continue;
-            }
-            if (nums[i] == nums[i - 1] + 1) {
-                ans = max(ans, ++t);
-            } else {
-                t = 1;
+        unordered_set<int> s(nums.begin(), nums.end());
+        int ans = 0;
+        unordered_map<int, int> d;
+        for (int x : nums) {
+            int y = x;
+            while (s.contains(y)) {
+                s.erase(y++);
             }
+            d[x] = (d.contains(y) ? d[y] : 0) + y - x;
+            ans = max(ans, d[x]);
         }
         return ans;
     }
@@ -146,25 +132,22 @@ public:
 #### Go
 
 ```go
-func longestConsecutive(nums []int) int {
-	n := len(nums)
-	if n < 2 {
-		return n
+func longestConsecutive(nums []int) (ans int) {
+	s := map[int]bool{}
+	for _, x := range nums {
+		s[x] = true
 	}
-	sort.Ints(nums)
-	ans, t := 1, 1
-	for i, x := range nums[1:] {
-		if x == nums[i] {
-			continue
-		}
-		if x == nums[i]+1 {
-			t++
-			ans = max(ans, t)
-		} else {
-			t = 1
+	d := map[int]int{}
+	for _, x := range nums {
+		y := x
+		for s[y] {
+			delete(s, y)
+			y++
 		}
+		d[x] = d[y] + y - x
+		ans = max(ans, d[x])
 	}
-	return ans
+	return
 }
 ```
 
@@ -172,22 +155,16 @@ func longestConsecutive(nums []int) int {
 
 ```ts
 function longestConsecutive(nums: number[]): number {
-    const n = nums.length;
-    if (n < 2) {
-        return n;
-    }
-    let ans = 1;
-    let t = 1;
-    nums.sort((a, b) => a - b);
-    for (let i = 1; i < n; ++i) {
-        if (nums[i] === nums[i - 1]) {
-            continue;
-        }
-        if (nums[i] === nums[i - 1] + 1) {
-            ans = Math.max(ans, ++t);
-        } else {
-            t = 1;
+    const s = new Set(nums);
+    let ans = 0;
+    const d = new Map<number, number>();
+    for (const x of nums) {
+        let y = x;
+        while (s.has(y)) {
+            s.delete(y++);
         }
+        d.set(x, (d.get(y) || 0) + (y - x));
+        ans = Math.max(ans, d.get(x)!);
     }
     return ans;
 }
@@ -196,32 +173,24 @@ function longestConsecutive(nums: number[]): number {
 #### Rust
 
 ```rust
-use std::collections::HashSet;
+use std::collections::{HashMap, HashSet};
 
 impl Solution {
-    #[allow(dead_code)]
     pub fn longest_consecutive(nums: Vec<i32>) -> i32 {
-        let mut s = HashSet::new();
-        let mut ret = 0;
-
-        // Initialize the set
-        for num in &nums {
-            s.insert(*num);
-        }
-
-        for num in &nums {
-            if s.contains(&(*num - 1)) {
-                continue;
+        let mut s: HashSet<i32> = nums.iter().cloned().collect();
+        let mut ans = 0;
+        let mut d: HashMap<i32, i32> = HashMap::new();
+        for &x in &nums {
+            let mut y = x;
+            while s.contains(&y) {
+                s.remove(&y);
+                y += 1;
             }
-            let mut cur_num = num.clone();
-            while s.contains(&cur_num) {
-                cur_num += 1;
-            }
-            // Update the answer
-            ret = std::cmp::max(ret, cur_num - num);
+            let length = d.get(&(y)).unwrap_or(&0) + y - x;
+            d.insert(x, length);
+            ans = ans.max(length);
         }
-
-        ret
+        ans
     }
 }
 ```
@@ -234,22 +203,16 @@ impl Solution {
  * @return {number}
  */
 var longestConsecutive = function (nums) {
-    const n = nums.length;
-    if (n < 2) {
-        return n;
-    }
-    nums.sort((a, b) => a - b);
-    let ans = 1;
-    let t = 1;
-    for (let i = 1; i < n; ++i) {
-        if (nums[i] === nums[i - 1]) {
-            continue;
-        }
-        if (nums[i] === nums[i - 1] + 1) {
-            ans = Math.max(ans, ++t);
-        } else {
-            t = 1;
+    const s = new Set(nums);
+    let ans = 0;
+    const d = new Map();
+    for (const x of nums) {
+        let y = x;
+        while (s.has(y)) {
+            s.delete(y++);
         }
+        d.set(x, (d.get(y) || 0) + (y - x));
+        ans = Math.max(ans, d.get(x));
     }
     return ans;
 };
@@ -261,11 +224,11 @@ var longestConsecutive = function (nums) {
 
 <!-- solution:start -->
 
-### 方法二:哈希表
+### 方法二:哈希表(优化)
 
-我们用哈希表存储数组中的所有元素,然后遍历数组中的每个元素 $x$,如果当前元素的前驱 $x-1$ 不在哈希表中,那么我们以当前元素为起点,不断尝试匹配 $x+1, x+2, x+3, \dots$,直到匹配不到为止,此时的匹配长度即为以 $x$ 为起点的最长连续序列长度,我们更新答案即可。
+与方法一类似,我们用一个哈希表 $\textit{s}$ 存储数组中所有的元素,用一个变量 $\textit{ans}$ 记录最长连续序列的长度。但是,我们不再使用哈希表 $\textit{d}$ 记录每个元素 $x$ 所在的连续序列的长度,在遍历的过程中,跳过那些 $x-1$ 也在哈希表 $\textit{s}$ 中的元素,如果 $x-1$ 在哈希表 $\textit{s}$ 中,那么 $x$ 一定不是连续序列的起点,因此我们可以直接跳过 $x$。
 
-时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组的长度。
+时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $\textit{nums}$ 的长度。
 
 <!-- tabs:start -->
 
@@ -276,7 +239,7 @@ class Solution:
     def longestConsecutive(self, nums: List[int]) -> int:
         s = set(nums)
         ans = 0
-        for x in nums:
+        for x in s:
             if x - 1 not in s:
                 y = x + 1
                 while y in s:
@@ -295,7 +258,7 @@ class Solution {
             s.add(x);
         }
         int ans = 0;
-        for (int x : nums) {
+        for (int x : s) {
             if (!s.contains(x - 1)) {
                 int y = x + 1;
                 while (s.contains(y)) {
@@ -317,10 +280,10 @@ public:
     int longestConsecutive(vector<int>& nums) {
         unordered_set<int> s(nums.begin(), nums.end());
         int ans = 0;
-        for (int x : nums) {
-            if (!s.count(x - 1)) {
+        for (int x : s) {
+            if (!s.contains(x - 1)) {
                 int y = x + 1;
-                while (s.count(y)) {
+                while (s.contains(y)) {
                     y++;
                 }
                 ans = max(ans, y - x);
@@ -339,7 +302,7 @@ func longestConsecutive(nums []int) (ans int) {
 	for _, x := range nums {
 		s[x] = true
 	}
-	for _, x := range nums {
+	for x, _ := range s {
 		if !s[x-1] {
 			y := x + 1
 			for s[y] {
@@ -356,7 +319,7 @@ func longestConsecutive(nums []int) (ans int) {
 
 ```ts
 function longestConsecutive(nums: number[]): number {
-    const s: Set<number> = new Set(nums);
+    const s = new Set<number>(nums);
     let ans = 0;
     for (const x of s) {
         if (!s.has(x - 1)) {
@@ -371,6 +334,29 @@ function longestConsecutive(nums: number[]): number {
 }
 ```
 
+#### Rust
+
+```rust
+use std::collections::HashSet;
+
+impl Solution {
+    pub fn longest_consecutive(nums: Vec<i32>) -> i32 {
+        let s: HashSet<i32> = nums.iter().cloned().collect();
+        let mut ans = 0;
+        for &x in &s {
+            if !s.contains(&(x - 1)) {
+                let mut y = x + 1;
+                while s.contains(&y) {
+                    y += 1;
+                }
+                ans = ans.max(y - x);
+            }
+        }
+        ans
+    }
+}
+```
+
 #### JavaScript
 
 ```js
diff --git a/solution/0100-0199/0128.Longest Consecutive Sequence/README_EN.md b/solution/0100-0199/0128.Longest Consecutive Sequence/README_EN.md
index 4666536ca47ba..e9cf2fe50f0aa 100644
--- a/solution/0100-0199/0128.Longest Consecutive Sequence/README_EN.md	
+++ b/solution/0100-0199/0128.Longest Consecutive Sequence/README_EN.md	
@@ -52,19 +52,15 @@ tags:
 
 <!-- solution:start -->
 
-### Solution 1: Sorting
+### Solution 1: Hash Table
 
-First, we sort the array, then use a variable $t$ to record the current length of the consecutive sequence, and a variable $ans$ to record the length of the longest consecutive sequence.
+We can use a hash table $\textit{s}$ to store all the elements in the array, a variable $\textit{ans}$ to record the length of the longest consecutive sequence, and a hash table $\textit{d}$ to record the length of the consecutive sequence each element $x$ belongs to.
 
-Next, we start traversing the array from index $i=1$. For the current element $nums[i]$:
+Next, we iterate through each element $x$ in the array, using a temporary variable $y$ to record the maximum value of the current consecutive sequence, initially $y = x$. Then, we continuously try to match $y+1, y+2, y+3, \dots$ until we can no longer match. During this process, we remove the matched elements from the hash table $\textit{s}$. The length of the consecutive sequence that the current element $x$ belongs to is $d[x] = d[y] + y - x$, and then we update the answer $\textit{ans} = \max(\textit{ans}, d[x])$.
 
--   If $nums[i] = nums[i-1]$, it means the current element is repeated and does not need to be considered.
--   If $nums[i] = nums[i-1] + 1$, it means the current element can be appended to the previous consecutive sequence to form a longer consecutive sequence. We update $t = t + 1$, and then update the answer $ans = \max(ans, t)$.
--   Otherwise, it means the current element cannot be appended to the previous consecutive sequence, and we reset $t$ to $1$.
+After the iteration, we return the answer $\textit{ans}$.
 
-Finally, we return the answer $ans$.
-
-The time complexity is $O(n \times \log n)$, and the space complexity is $O(\log n)$. Here, $n$ is the length of the array.
+The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array $\textit{nums}$.
 
 <!-- tabs:start -->
 
@@ -73,19 +69,16 @@ The time complexity is $O(n \times \log n)$, and the space complexity is $O(\log
 ```python
 class Solution:
     def longestConsecutive(self, nums: List[int]) -> int:
-        n = len(nums)
-        if n < 2:
-            return n
-        nums.sort()
-        ans = t = 1
-        for a, b in pairwise(nums):
-            if a == b:
-                continue
-            if a + 1 == b:
-                t += 1
-                ans = max(ans, t)
-            else:
-                t = 1
+        s = set(nums)
+        ans = 0
+        d = defaultdict(int)
+        for x in nums:
+            y = x
+            while y in s:
+                s.remove(y)
+                y += 1
+            d[x] = d[y] + y - x
+            ans = max(ans, d[x])
         return ans
 ```
 
@@ -94,21 +87,19 @@ class Solution:
 ```java
 class Solution {
     public int longestConsecutive(int[] nums) {
-        int n = nums.length;
-        if (n < 2) {
-            return n;
+        Set<Integer> s = new HashSet<>();
+        for (int x : nums) {
+            s.add(x);
         }
-        Arrays.sort(nums);
-        int ans = 1, t = 1;
-        for (int i = 1; i < n; ++i) {
-            if (nums[i] == nums[i - 1]) {
-                continue;
-            }
-            if (nums[i] == nums[i - 1] + 1) {
-                ans = Math.max(ans, ++t);
-            } else {
-                t = 1;
+        int ans = 0;
+        Map<Integer, Integer> d = new HashMap<>();
+        for (int x : nums) {
+            int y = x;
+            while (s.contains(y)) {
+                s.remove(y++);
             }
+            d.put(x, d.getOrDefault(y, 0) + y - x);
+            ans = Math.max(ans, d.get(x));
         }
         return ans;
     }
@@ -121,21 +112,16 @@ class Solution {
 class Solution {
 public:
     int longestConsecutive(vector<int>& nums) {
-        int n = nums.size();
-        if (n < 2) {
-            return n;
-        }
-        sort(nums.begin(), nums.end());
-        int ans = 1, t = 1;
-        for (int i = 1; i < n; ++i) {
-            if (nums[i] == nums[i - 1]) {
-                continue;
-            }
-            if (nums[i] == nums[i - 1] + 1) {
-                ans = max(ans, ++t);
-            } else {
-                t = 1;
+        unordered_set<int> s(nums.begin(), nums.end());
+        int ans = 0;
+        unordered_map<int, int> d;
+        for (int x : nums) {
+            int y = x;
+            while (s.contains(y)) {
+                s.erase(y++);
             }
+            d[x] = (d.contains(y) ? d[y] : 0) + y - x;
+            ans = max(ans, d[x]);
         }
         return ans;
     }
@@ -145,25 +131,22 @@ public:
 #### Go
 
 ```go
-func longestConsecutive(nums []int) int {
-	n := len(nums)
-	if n < 2 {
-		return n
+func longestConsecutive(nums []int) (ans int) {
+	s := map[int]bool{}
+	for _, x := range nums {
+		s[x] = true
 	}
-	sort.Ints(nums)
-	ans, t := 1, 1
-	for i, x := range nums[1:] {
-		if x == nums[i] {
-			continue
-		}
-		if x == nums[i]+1 {
-			t++
-			ans = max(ans, t)
-		} else {
-			t = 1
+	d := map[int]int{}
+	for _, x := range nums {
+		y := x
+		for s[y] {
+			delete(s, y)
+			y++
 		}
+		d[x] = d[y] + y - x
+		ans = max(ans, d[x])
 	}
-	return ans
+	return
 }
 ```
 
@@ -171,22 +154,16 @@ func longestConsecutive(nums []int) int {
 
 ```ts
 function longestConsecutive(nums: number[]): number {
-    const n = nums.length;
-    if (n < 2) {
-        return n;
-    }
-    let ans = 1;
-    let t = 1;
-    nums.sort((a, b) => a - b);
-    for (let i = 1; i < n; ++i) {
-        if (nums[i] === nums[i - 1]) {
-            continue;
-        }
-        if (nums[i] === nums[i - 1] + 1) {
-            ans = Math.max(ans, ++t);
-        } else {
-            t = 1;
+    const s = new Set(nums);
+    let ans = 0;
+    const d = new Map<number, number>();
+    for (const x of nums) {
+        let y = x;
+        while (s.has(y)) {
+            s.delete(y++);
         }
+        d.set(x, (d.get(y) || 0) + (y - x));
+        ans = Math.max(ans, d.get(x)!);
     }
     return ans;
 }
@@ -195,32 +172,24 @@ function longestConsecutive(nums: number[]): number {
 #### Rust
 
 ```rust
-use std::collections::HashSet;
+use std::collections::{HashMap, HashSet};
 
 impl Solution {
-    #[allow(dead_code)]
     pub fn longest_consecutive(nums: Vec<i32>) -> i32 {
-        let mut s = HashSet::new();
-        let mut ret = 0;
-
-        // Initialize the set
-        for num in &nums {
-            s.insert(*num);
-        }
-
-        for num in &nums {
-            if s.contains(&(*num - 1)) {
-                continue;
+        let mut s: HashSet<i32> = nums.iter().cloned().collect();
+        let mut ans = 0;
+        let mut d: HashMap<i32, i32> = HashMap::new();
+        for &x in &nums {
+            let mut y = x;
+            while s.contains(&y) {
+                s.remove(&y);
+                y += 1;
             }
-            let mut cur_num = num.clone();
-            while s.contains(&cur_num) {
-                cur_num += 1;
-            }
-            // Update the answer
-            ret = std::cmp::max(ret, cur_num - num);
+            let length = d.get(&(y)).unwrap_or(&0) + y - x;
+            d.insert(x, length);
+            ans = ans.max(length);
         }
-
-        ret
+        ans
     }
 }
 ```
@@ -233,22 +202,16 @@ impl Solution {
  * @return {number}
  */
 var longestConsecutive = function (nums) {
-    const n = nums.length;
-    if (n < 2) {
-        return n;
-    }
-    nums.sort((a, b) => a - b);
-    let ans = 1;
-    let t = 1;
-    for (let i = 1; i < n; ++i) {
-        if (nums[i] === nums[i - 1]) {
-            continue;
-        }
-        if (nums[i] === nums[i - 1] + 1) {
-            ans = Math.max(ans, ++t);
-        } else {
-            t = 1;
+    const s = new Set(nums);
+    let ans = 0;
+    const d = new Map();
+    for (const x of nums) {
+        let y = x;
+        while (s.has(y)) {
+            s.delete(y++);
         }
+        d.set(x, (d.get(y) || 0) + (y - x));
+        ans = Math.max(ans, d.get(x));
     }
     return ans;
 };
@@ -260,11 +223,11 @@ var longestConsecutive = function (nums) {
 
 <!-- solution:start -->
 
-### Solution 2: Hash Table
+### Solution 2: Hash Table (Optimization)
 
-We use a hash table to store all elements in the array, and then traverse each element $x$ in the array. If the predecessor $x-1$ of the current element is not in the hash table, then we start with the current element and continuously try to match $x+1, x+2, x+3, \dots$, until no match is found. The length of the match at this time is the longest consecutive sequence length starting with $x$, and we update the answer accordingly.
+Similar to Solution 1, we use a hash table $\textit{s}$ to store all the elements in the array and a variable $\textit{ans}$ to record the length of the longest consecutive sequence. However, we no longer use a hash table $\textit{d}$ to record the length of the consecutive sequence each element $x$ belongs to. During the iteration, we skip elements where $x-1$ is also in the hash table $\textit{s}$. If $x-1$ is in the hash table $\textit{s}$, then $x$ is definitely not the start of a consecutive sequence, so we can directly skip $x$.
 
-The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array.
+The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array $\textit{nums}$.
 
 <!-- tabs:start -->
 
@@ -275,7 +238,7 @@ class Solution:
     def longestConsecutive(self, nums: List[int]) -> int:
         s = set(nums)
         ans = 0
-        for x in nums:
+        for x in s:
             if x - 1 not in s:
                 y = x + 1
                 while y in s:
@@ -294,7 +257,7 @@ class Solution {
             s.add(x);
         }
         int ans = 0;
-        for (int x : nums) {
+        for (int x : s) {
             if (!s.contains(x - 1)) {
                 int y = x + 1;
                 while (s.contains(y)) {
@@ -316,10 +279,10 @@ public:
     int longestConsecutive(vector<int>& nums) {
         unordered_set<int> s(nums.begin(), nums.end());
         int ans = 0;
-        for (int x : nums) {
-            if (!s.count(x - 1)) {
+        for (int x : s) {
+            if (!s.contains(x - 1)) {
                 int y = x + 1;
-                while (s.count(y)) {
+                while (s.contains(y)) {
                     y++;
                 }
                 ans = max(ans, y - x);
@@ -338,7 +301,7 @@ func longestConsecutive(nums []int) (ans int) {
 	for _, x := range nums {
 		s[x] = true
 	}
-	for _, x := range nums {
+	for x, _ := range s {
 		if !s[x-1] {
 			y := x + 1
 			for s[y] {
@@ -355,7 +318,7 @@ func longestConsecutive(nums []int) (ans int) {
 
 ```ts
 function longestConsecutive(nums: number[]): number {
-    const s: Set<number> = new Set(nums);
+    const s = new Set<number>(nums);
     let ans = 0;
     for (const x of s) {
         if (!s.has(x - 1)) {
@@ -370,6 +333,29 @@ function longestConsecutive(nums: number[]): number {
 }
 ```
 
+#### Rust
+
+```rust
+use std::collections::HashSet;
+
+impl Solution {
+    pub fn longest_consecutive(nums: Vec<i32>) -> i32 {
+        let s: HashSet<i32> = nums.iter().cloned().collect();
+        let mut ans = 0;
+        for &x in &s {
+            if !s.contains(&(x - 1)) {
+                let mut y = x + 1;
+                while s.contains(&y) {
+                    y += 1;
+                }
+                ans = ans.max(y - x);
+            }
+        }
+        ans
+    }
+}
+```
+
 #### JavaScript
 
 ```js
diff --git a/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.cpp b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.cpp
index a3c9a84ec208c..c244bb46ba0e1 100644
--- a/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.cpp	
+++ b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.cpp	
@@ -1,22 +1,17 @@
 class Solution {
 public:
     int longestConsecutive(vector<int>& nums) {
-        int n = nums.size();
-        if (n < 2) {
-            return n;
-        }
-        sort(nums.begin(), nums.end());
-        int ans = 1, t = 1;
-        for (int i = 1; i < n; ++i) {
-            if (nums[i] == nums[i - 1]) {
-                continue;
-            }
-            if (nums[i] == nums[i - 1] + 1) {
-                ans = max(ans, ++t);
-            } else {
-                t = 1;
+        unordered_set<int> s(nums.begin(), nums.end());
+        int ans = 0;
+        unordered_map<int, int> d;
+        for (int x : nums) {
+            int y = x;
+            while (s.contains(y)) {
+                s.erase(y++);
             }
+            d[x] = (d.contains(y) ? d[y] : 0) + y - x;
+            ans = max(ans, d[x]);
         }
         return ans;
     }
-};
\ No newline at end of file
+};
diff --git a/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.go b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.go
index 272692b96d9ad..2db02e33eb2be 100644
--- a/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.go	
+++ b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.go	
@@ -1,20 +1,17 @@
-func longestConsecutive(nums []int) int {
-	n := len(nums)
-	if n < 2 {
-		return n
+func longestConsecutive(nums []int) (ans int) {
+	s := map[int]bool{}
+	for _, x := range nums {
+		s[x] = true
 	}
-	sort.Ints(nums)
-	ans, t := 1, 1
-	for i, x := range nums[1:] {
-		if x == nums[i] {
-			continue
-		}
-		if x == nums[i]+1 {
-			t++
-			ans = max(ans, t)
-		} else {
-			t = 1
+	d := map[int]int{}
+	for _, x := range nums {
+		y := x
+		for s[y] {
+			delete(s, y)
+			y++
 		}
+		d[x] = d[y] + y - x
+		ans = max(ans, d[x])
 	}
-	return ans
-}
\ No newline at end of file
+	return
+}
diff --git a/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.java b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.java
index 511b5cc8b24b0..5be8ee06a9301 100644
--- a/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.java	
+++ b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.java	
@@ -1,21 +1,19 @@
 class Solution {
     public int longestConsecutive(int[] nums) {
-        int n = nums.length;
-        if (n < 2) {
-            return n;
+        Set<Integer> s = new HashSet<>();
+        for (int x : nums) {
+            s.add(x);
         }
-        Arrays.sort(nums);
-        int ans = 1, t = 1;
-        for (int i = 1; i < n; ++i) {
-            if (nums[i] == nums[i - 1]) {
-                continue;
-            }
-            if (nums[i] == nums[i - 1] + 1) {
-                ans = Math.max(ans, ++t);
-            } else {
-                t = 1;
+        int ans = 0;
+        Map<Integer, Integer> d = new HashMap<>();
+        for (int x : nums) {
+            int y = x;
+            while (s.contains(y)) {
+                s.remove(y++);
             }
+            d.put(x, d.getOrDefault(y, 0) + y - x);
+            ans = Math.max(ans, d.get(x));
         }
         return ans;
     }
-}
\ No newline at end of file
+}
diff --git a/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.js b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.js
index 626571486477c..c517e3722f64c 100644
--- a/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.js	
+++ b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.js	
@@ -3,22 +3,16 @@
  * @return {number}
  */
 var longestConsecutive = function (nums) {
-    const n = nums.length;
-    if (n < 2) {
-        return n;
-    }
-    nums.sort((a, b) => a - b);
-    let ans = 1;
-    let t = 1;
-    for (let i = 1; i < n; ++i) {
-        if (nums[i] === nums[i - 1]) {
-            continue;
-        }
-        if (nums[i] === nums[i - 1] + 1) {
-            ans = Math.max(ans, ++t);
-        } else {
-            t = 1;
+    const s = new Set(nums);
+    let ans = 0;
+    const d = new Map();
+    for (const x of nums) {
+        let y = x;
+        while (s.has(y)) {
+            s.delete(y++);
         }
+        d.set(x, (d.get(y) || 0) + (y - x));
+        ans = Math.max(ans, d.get(x));
     }
     return ans;
 };
diff --git a/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.py b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.py
index 2f769cf2e22de..68e4d2445bc04 100644
--- a/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.py	
+++ b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.py	
@@ -1,16 +1,13 @@
 class Solution:
     def longestConsecutive(self, nums: List[int]) -> int:
-        n = len(nums)
-        if n < 2:
-            return n
-        nums.sort()
-        ans = t = 1
-        for a, b in pairwise(nums):
-            if a == b:
-                continue
-            if a + 1 == b:
-                t += 1
-                ans = max(ans, t)
-            else:
-                t = 1
+        s = set(nums)
+        ans = 0
+        d = defaultdict(int)
+        for x in nums:
+            y = x
+            while y in s:
+                s.remove(y)
+                y += 1
+            d[x] = d[y] + y - x
+            ans = max(ans, d[x])
         return ans
diff --git a/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.rs b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.rs
index 48b64c1980532..b46a0700e4d09 100644
--- a/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.rs	
+++ b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.rs	
@@ -1,28 +1,20 @@
-use std::collections::HashSet;
+use std::collections::{HashMap, HashSet};
 
 impl Solution {
-    #[allow(dead_code)]
     pub fn longest_consecutive(nums: Vec<i32>) -> i32 {
-        let mut s = HashSet::new();
-        let mut ret = 0;
-
-        // Initialize the set
-        for num in &nums {
-            s.insert(*num);
-        }
-
-        for num in &nums {
-            if s.contains(&(*num - 1)) {
-                continue;
+        let mut s: HashSet<i32> = nums.iter().cloned().collect();
+        let mut ans = 0;
+        let mut d: HashMap<i32, i32> = HashMap::new();
+        for &x in &nums {
+            let mut y = x;
+            while s.contains(&y) {
+                s.remove(&y);
+                y += 1;
             }
-            let mut cur_num = num.clone();
-            while s.contains(&cur_num) {
-                cur_num += 1;
-            }
-            // Update the answer
-            ret = std::cmp::max(ret, cur_num - num);
+            let length = d.get(&(y)).unwrap_or(&0) + y - x;
+            d.insert(x, length);
+            ans = ans.max(length);
         }
-
-        ret
+        ans
     }
 }
diff --git a/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.ts b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.ts
index fb0fc69cfc134..c7b256c914578 100644
--- a/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.ts	
+++ b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution.ts	
@@ -1,20 +1,14 @@
 function longestConsecutive(nums: number[]): number {
-    const n = nums.length;
-    if (n < 2) {
-        return n;
-    }
-    let ans = 1;
-    let t = 1;
-    nums.sort((a, b) => a - b);
-    for (let i = 1; i < n; ++i) {
-        if (nums[i] === nums[i - 1]) {
-            continue;
-        }
-        if (nums[i] === nums[i - 1] + 1) {
-            ans = Math.max(ans, ++t);
-        } else {
-            t = 1;
+    const s = new Set(nums);
+    let ans = 0;
+    const d = new Map<number, number>();
+    for (const x of nums) {
+        let y = x;
+        while (s.has(y)) {
+            s.delete(y++);
         }
+        d.set(x, (d.get(y) || 0) + (y - x));
+        ans = Math.max(ans, d.get(x)!);
     }
     return ans;
 }
diff --git a/solution/0100-0199/0128.Longest Consecutive Sequence/Solution2.cpp b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution2.cpp
index 63963f9f4512b..3741fcf9c7633 100644
--- a/solution/0100-0199/0128.Longest Consecutive Sequence/Solution2.cpp	
+++ b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution2.cpp	
@@ -3,10 +3,10 @@ class Solution {
     int longestConsecutive(vector<int>& nums) {
         unordered_set<int> s(nums.begin(), nums.end());
         int ans = 0;
-        for (int x : nums) {
-            if (!s.count(x - 1)) {
+        for (int x : s) {
+            if (!s.contains(x - 1)) {
                 int y = x + 1;
-                while (s.count(y)) {
+                while (s.contains(y)) {
                     y++;
                 }
                 ans = max(ans, y - x);
@@ -14,4 +14,4 @@ class Solution {
         }
         return ans;
     }
-};
\ No newline at end of file
+};
diff --git a/solution/0100-0199/0128.Longest Consecutive Sequence/Solution2.go b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution2.go
index 1a38e03b11467..cb5cbe08d6413 100644
--- a/solution/0100-0199/0128.Longest Consecutive Sequence/Solution2.go	
+++ b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution2.go	
@@ -3,7 +3,7 @@ func longestConsecutive(nums []int) (ans int) {
 	for _, x := range nums {
 		s[x] = true
 	}
-	for _, x := range nums {
+	for x, _ := range s {
 		if !s[x-1] {
 			y := x + 1
 			for s[y] {
@@ -13,4 +13,4 @@ func longestConsecutive(nums []int) (ans int) {
 		}
 	}
 	return
-}
\ No newline at end of file
+}
diff --git a/solution/0100-0199/0128.Longest Consecutive Sequence/Solution2.java b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution2.java
index 9fbf604320adb..d3a5d748d4acc 100644
--- a/solution/0100-0199/0128.Longest Consecutive Sequence/Solution2.java	
+++ b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution2.java	
@@ -5,7 +5,7 @@ public int longestConsecutive(int[] nums) {
             s.add(x);
         }
         int ans = 0;
-        for (int x : nums) {
+        for (int x : s) {
             if (!s.contains(x - 1)) {
                 int y = x + 1;
                 while (s.contains(y)) {
@@ -16,4 +16,4 @@ public int longestConsecutive(int[] nums) {
         }
         return ans;
     }
-}
\ No newline at end of file
+}
diff --git a/solution/0100-0199/0128.Longest Consecutive Sequence/Solution2.py b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution2.py
index cd60849601a20..e1758304fb18e 100644
--- a/solution/0100-0199/0128.Longest Consecutive Sequence/Solution2.py	
+++ b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution2.py	
@@ -2,7 +2,7 @@ class Solution:
     def longestConsecutive(self, nums: List[int]) -> int:
         s = set(nums)
         ans = 0
-        for x in nums:
+        for x in s:
             if x - 1 not in s:
                 y = x + 1
                 while y in s:
diff --git a/solution/0100-0199/0128.Longest Consecutive Sequence/Solution2.rs b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution2.rs
new file mode 100644
index 0000000000000..b01a7751346f1
--- /dev/null
+++ b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution2.rs	
@@ -0,0 +1,18 @@
+use std::collections::HashSet;
+
+impl Solution {
+    pub fn longest_consecutive(nums: Vec<i32>) -> i32 {
+        let s: HashSet<i32> = nums.iter().cloned().collect();
+        let mut ans = 0;
+        for &x in &s {
+            if !s.contains(&(x - 1)) {
+                let mut y = x + 1;
+                while s.contains(&y) {
+                    y += 1;
+                }
+                ans = ans.max(y - x);
+            }
+        }
+        ans
+    }
+}
diff --git a/solution/0100-0199/0128.Longest Consecutive Sequence/Solution2.ts b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution2.ts
index 7e593ca8830d1..cb9c453c19bd9 100644
--- a/solution/0100-0199/0128.Longest Consecutive Sequence/Solution2.ts	
+++ b/solution/0100-0199/0128.Longest Consecutive Sequence/Solution2.ts	
@@ -1,5 +1,5 @@
 function longestConsecutive(nums: number[]): number {
-    const s: Set<number> = new Set(nums);
+    const s = new Set<number>(nums);
     let ans = 0;
     for (const x of s) {
         if (!s.has(x - 1)) {