From 7a8e930a6548df9680214fde10ffff9fd0a9235b Mon Sep 17 00:00:00 2001
From: yanglbme <szuyanglb@outlook.com>
Date: Tue, 24 Sep 2024 09:11:36 +0800
Subject: [PATCH] feat: add solutions to lc problem: No.1239

No.1239.Maximum Length of a Concatenated String with Unique Characters
---
 .../README.md                                 | 178 +++++++++++-------
 .../README_EN.md                              | 178 +++++++++++-------
 .../Solution.cpp                              |  34 ++--
 .../Solution.go                               |  35 ++--
 .../Solution.java                             |  36 ++--
 .../Solution.py                               |  26 +--
 .../Solution.ts                               |  36 ++++
 7 files changed, 310 insertions(+), 213 deletions(-)
 create mode 100644 solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/Solution.ts

diff --git a/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/README.md b/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/README.md
index 5c8121c3866f2..dce090b353afa 100644
--- a/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/README.md	
+++ b/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/README.md	
@@ -75,11 +75,17 @@ tags:
 
 <!-- solution:start -->
 
-### 方法一:位运算 + 状态压缩
+### 方法一:状态压缩 + 位运算
 
-状态压缩,用一个 $32$ 位数记录字母的出现情况,`masks` 存储之前枚举的字符串。
+由于题目要求子序列的字符不能重复,字符都是小写字母,因此,我们可以用一个长度为 $26$ 的二进制整数来表示一个子序列,其中第 $i$ 位为 $1$ 表示子序列中含有滴 $i$ 个字符,为 $0$ 表示不含有第 $i$ 个字符。
 
-时间复杂度 $O(2^n + L)$,空间复杂度 $O(2^n)$。其中 $n$ 和 $L$ 分别是字符串数组的长度和字符串数组中字符串的长度之和。
+我们可以用一个数组 $s$ 来存储所有满足条件的子序列的状态,初始时 $s$ 中只有一个元素 $0$。
+
+然后我们遍历数组 $\textit{arr}$,对于每个字符串 $t$,我们用一个整数 $x$ 来表示 $t$ 的状态,然后我们遍历数组 $s$,对于每个状态 $y$,如果 $x$ 和 $y$ 之间没有相同的字符,那么我们将 $x$ 和 $y$ 的并集加入到 $s$ 中,并更新答案。
+
+最后我们返回答案即可。
+
+时间复杂度 $O(2^n + L)$,空间复杂度 $O(2^n)$,其中 $n$ 是字符串数组的长度,而 $L$ 是字符串数组中所有字符串的长度之和。
 
 <!-- tabs:start -->
 
@@ -88,23 +94,17 @@ tags:
 ```python
 class Solution:
     def maxLength(self, arr: List[str]) -> int:
-        ans = 0
-        masks = [0]
-        for s in arr:
-            mask = 0
-            for c in s:
-                i = ord(c) - ord('a')
-                if mask >> i & 1:
-                    mask = 0
+        s = [0]
+        for t in arr:
+            x = 0
+            for b in map(lambda c: ord(c) - 97, t):
+                if x >> b & 1:
+                    x = 0
                     break
-                mask |= 1 << i
-            if mask == 0:
-                continue
-            for m in masks:
-                if m & mask == 0:
-                    masks.append(m | mask)
-                    ans = max(ans, (m | mask).bit_count())
-        return ans
+                x |= 1 << b
+            if x:
+                s.extend((x | y) for y in s if (x & y) == 0)
+        return max(x.bit_count() for x in s)
 ```
 
 #### Java
@@ -112,28 +112,26 @@ class Solution:
 ```java
 class Solution {
     public int maxLength(List<String> arr) {
+        List<Integer> s = new ArrayList<>();
+        s.add(0);
         int ans = 0;
-        List<Integer> masks = new ArrayList<>();
-        masks.add(0);
-        for (var s : arr) {
-            int mask = 0;
-            for (int i = 0; i < s.length(); ++i) {
-                int j = s.charAt(i) - 'a';
-                if (((mask >> j) & 1) == 1) {
-                    mask = 0;
+        for (var t : arr) {
+            int x = 0;
+            for (char c : t.toCharArray()) {
+                int b = c - 'a';
+                if ((x >> b & 1) == 1) {
+                    x = 0;
                     break;
                 }
-                mask |= 1 << j;
+                x |= 1 << b;
             }
-            if (mask == 0) {
-                continue;
-            }
-            int n = masks.size();
-            for (int i = 0; i < n; ++i) {
-                int m = masks.get(i);
-                if ((m & mask) == 0) {
-                    masks.add(m | mask);
-                    ans = Math.max(ans, Integer.bitCount(m | mask));
+            if (x > 0) {
+                for (int i = s.size() - 1; i >= 0; --i) {
+                    int y = s.get(i);
+                    if ((x & y) == 0) {
+                        s.add(x | y);
+                        ans = Math.max(ans, Integer.bitCount(x | y));
+                    }
                 }
             }
         }
@@ -148,27 +146,25 @@ class Solution {
 class Solution {
 public:
     int maxLength(vector<string>& arr) {
+        vector<int> s = {0};
         int ans = 0;
-        vector<int> masks = {0};
-        for (auto& s : arr) {
-            int mask = 0;
-            for (auto& c : s) {
-                int i = c - 'a';
-                if (mask >> i & 1) {
-                    mask = 0;
+        for (const string& t : arr) {
+            int x = 0;
+            for (char c : t) {
+                int b = c - 'a';
+                if ((x >> b & 1) == 1) {
+                    x = 0;
                     break;
                 }
-                mask |= 1 << i;
-            }
-            if (mask == 0) {
-                continue;
+                x |= 1 << b;
             }
-            int n = masks.size();
-            for (int i = 0; i < n; ++i) {
-                int m = masks[i];
-                if ((m & mask) == 0) {
-                    masks.push_back(m | mask);
-                    ans = max(ans, __builtin_popcount(m | mask));
+            if (x > 0) {
+                for (int i = s.size() - 1; i >= 0; --i) {
+                    int y = s[i];
+                    if ((x & y) == 0) {
+                        s.push_back(x | y);
+                        ans = max(ans, __builtin_popcount(x | y));
+                    }
                 }
             }
         }
@@ -181,29 +177,69 @@ public:
 
 ```go
 func maxLength(arr []string) (ans int) {
-	masks := []int{0}
-	for _, s := range arr {
-		mask := 0
-		for _, c := range s {
-			i := int(c - 'a')
-			if mask>>i&1 == 1 {
-				mask = 0
+	s := []int{0}
+	for _, t := range arr {
+		x := 0
+		for _, c := range t {
+			b := int(c - 'a')
+			if (x>>b)&1 == 1 {
+				x = 0
 				break
 			}
-			mask |= 1 << i
+			x |= 1 << b
 		}
-		if mask == 0 {
-			continue
-		}
-		n := len(masks)
-		for _, m := range masks[:n] {
-			if m&mask == 0 {
-				masks = append(masks, m|mask)
-				ans = max(ans, bits.OnesCount(uint(m|mask)))
+		if x > 0 {
+			for i := len(s) - 1; i >= 0; i-- {
+				y := s[i]
+				if (x & y) == 0 {
+					s = append(s, x|y)
+					ans = max(ans, bits.OnesCount(uint(x|y)))
+				}
 			}
 		}
 	}
-	return
+	return ans
+}
+```
+
+#### TypeScript
+
+```ts
+function maxLength(arr: string[]): number {
+    const s: number[] = [0];
+    let ans = 0;
+    for (const t of arr) {
+        let x = 0;
+        for (const c of t) {
+            const b = c.charCodeAt(0) - 97;
+            if ((x >> b) & 1) {
+                x = 0;
+                break;
+            }
+            x |= 1 << b;
+        }
+
+        if (x > 0) {
+            for (let i = s.length - 1; ~i; --i) {
+                const y = s[i];
+                if ((x & y) === 0) {
+                    s.push(x | y);
+                    ans = Math.max(ans, bitCount(x | y));
+                }
+            }
+        }
+    }
+
+    return ans;
+}
+
+function bitCount(i: number): number {
+    i = i - ((i >>> 1) & 0x55555555);
+    i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
+    i = (i + (i >>> 4)) & 0x0f0f0f0f;
+    i = i + (i >>> 8);
+    i = i + (i >>> 16);
+    return i & 0x3f;
 }
 ```
 
diff --git a/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/README_EN.md b/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/README_EN.md
index dc8597040daba..260ee2b0ef79c 100644
--- a/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/README_EN.md	
+++ b/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/README_EN.md	
@@ -74,11 +74,17 @@ Maximum length is 4.
 
 <!-- solution:start -->
 
-### Solution 1: Bit Manipulation + State Compression
+### Solution 1: State Compression + Bit Manipulation
 
-State compression is used, with a 32-bit number recording the occurrence of letters, and `masks` storing the strings enumerated before.
+Since the problem requires that the characters in the subsequence must not be repeated and all characters are lowercase letters, we can use a binary integer of length $26$ to represent a subsequence. The $i$-th bit being $1$ indicates that the subsequence contains the $i$-th character, and $0$ indicates that it does not contain the $i$-th character.
 
-The time complexity is $O(2^n + L)$, and the space complexity is $O(2^n)$. Where $n$ and $L$ are the length of the string array and the sum of the lengths of the strings in the array, respectively.
+We can use an array $s$ to store the states of all subsequences that meet the conditions. Initially, $s$ contains only one element $0$.
+
+Then we traverse the array $\textit{arr}$. For each string $t$, we use an integer $x$ to represent the state of $t$. Then we traverse the array $s$. For each state $y$, if $x$ and $y$ have no common characters, we add the union of $x$ and $y$ to $s$ and update the answer.
+
+Finally, we return the answer.
+
+The time complexity is $O(2^n + L)$, and the space complexity is $O(2^n)$. Here, $n$ is the length of the string array, and $L$ is the sum of the lengths of all strings in the array.
 
 <!-- tabs:start -->
 
@@ -87,23 +93,17 @@ The time complexity is $O(2^n + L)$, and the space complexity is $O(2^n)$. Where
 ```python
 class Solution:
     def maxLength(self, arr: List[str]) -> int:
-        ans = 0
-        masks = [0]
-        for s in arr:
-            mask = 0
-            for c in s:
-                i = ord(c) - ord('a')
-                if mask >> i & 1:
-                    mask = 0
+        s = [0]
+        for t in arr:
+            x = 0
+            for b in map(lambda c: ord(c) - 97, t):
+                if x >> b & 1:
+                    x = 0
                     break
-                mask |= 1 << i
-            if mask == 0:
-                continue
-            for m in masks:
-                if m & mask == 0:
-                    masks.append(m | mask)
-                    ans = max(ans, (m | mask).bit_count())
-        return ans
+                x |= 1 << b
+            if x:
+                s.extend((x | y) for y in s if (x & y) == 0)
+        return max(x.bit_count() for x in s)
 ```
 
 #### Java
@@ -111,28 +111,26 @@ class Solution:
 ```java
 class Solution {
     public int maxLength(List<String> arr) {
+        List<Integer> s = new ArrayList<>();
+        s.add(0);
         int ans = 0;
-        List<Integer> masks = new ArrayList<>();
-        masks.add(0);
-        for (var s : arr) {
-            int mask = 0;
-            for (int i = 0; i < s.length(); ++i) {
-                int j = s.charAt(i) - 'a';
-                if (((mask >> j) & 1) == 1) {
-                    mask = 0;
+        for (var t : arr) {
+            int x = 0;
+            for (char c : t.toCharArray()) {
+                int b = c - 'a';
+                if ((x >> b & 1) == 1) {
+                    x = 0;
                     break;
                 }
-                mask |= 1 << j;
+                x |= 1 << b;
             }
-            if (mask == 0) {
-                continue;
-            }
-            int n = masks.size();
-            for (int i = 0; i < n; ++i) {
-                int m = masks.get(i);
-                if ((m & mask) == 0) {
-                    masks.add(m | mask);
-                    ans = Math.max(ans, Integer.bitCount(m | mask));
+            if (x > 0) {
+                for (int i = s.size() - 1; i >= 0; --i) {
+                    int y = s.get(i);
+                    if ((x & y) == 0) {
+                        s.add(x | y);
+                        ans = Math.max(ans, Integer.bitCount(x | y));
+                    }
                 }
             }
         }
@@ -147,27 +145,25 @@ class Solution {
 class Solution {
 public:
     int maxLength(vector<string>& arr) {
+        vector<int> s = {0};
         int ans = 0;
-        vector<int> masks = {0};
-        for (auto& s : arr) {
-            int mask = 0;
-            for (auto& c : s) {
-                int i = c - 'a';
-                if (mask >> i & 1) {
-                    mask = 0;
+        for (const string& t : arr) {
+            int x = 0;
+            for (char c : t) {
+                int b = c - 'a';
+                if ((x >> b & 1) == 1) {
+                    x = 0;
                     break;
                 }
-                mask |= 1 << i;
-            }
-            if (mask == 0) {
-                continue;
+                x |= 1 << b;
             }
-            int n = masks.size();
-            for (int i = 0; i < n; ++i) {
-                int m = masks[i];
-                if ((m & mask) == 0) {
-                    masks.push_back(m | mask);
-                    ans = max(ans, __builtin_popcount(m | mask));
+            if (x > 0) {
+                for (int i = s.size() - 1; i >= 0; --i) {
+                    int y = s[i];
+                    if ((x & y) == 0) {
+                        s.push_back(x | y);
+                        ans = max(ans, __builtin_popcount(x | y));
+                    }
                 }
             }
         }
@@ -180,29 +176,69 @@ public:
 
 ```go
 func maxLength(arr []string) (ans int) {
-	masks := []int{0}
-	for _, s := range arr {
-		mask := 0
-		for _, c := range s {
-			i := int(c - 'a')
-			if mask>>i&1 == 1 {
-				mask = 0
+	s := []int{0}
+	for _, t := range arr {
+		x := 0
+		for _, c := range t {
+			b := int(c - 'a')
+			if (x>>b)&1 == 1 {
+				x = 0
 				break
 			}
-			mask |= 1 << i
+			x |= 1 << b
 		}
-		if mask == 0 {
-			continue
-		}
-		n := len(masks)
-		for _, m := range masks[:n] {
-			if m&mask == 0 {
-				masks = append(masks, m|mask)
-				ans = max(ans, bits.OnesCount(uint(m|mask)))
+		if x > 0 {
+			for i := len(s) - 1; i >= 0; i-- {
+				y := s[i]
+				if (x & y) == 0 {
+					s = append(s, x|y)
+					ans = max(ans, bits.OnesCount(uint(x|y)))
+				}
 			}
 		}
 	}
-	return
+	return ans
+}
+```
+
+#### TypeScript
+
+```ts
+function maxLength(arr: string[]): number {
+    const s: number[] = [0];
+    let ans = 0;
+    for (const t of arr) {
+        let x = 0;
+        for (const c of t) {
+            const b = c.charCodeAt(0) - 97;
+            if ((x >> b) & 1) {
+                x = 0;
+                break;
+            }
+            x |= 1 << b;
+        }
+
+        if (x > 0) {
+            for (let i = s.length - 1; ~i; --i) {
+                const y = s[i];
+                if ((x & y) === 0) {
+                    s.push(x | y);
+                    ans = Math.max(ans, bitCount(x | y));
+                }
+            }
+        }
+    }
+
+    return ans;
+}
+
+function bitCount(i: number): number {
+    i = i - ((i >>> 1) & 0x55555555);
+    i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
+    i = (i + (i >>> 4)) & 0x0f0f0f0f;
+    i = i + (i >>> 8);
+    i = i + (i >>> 16);
+    return i & 0x3f;
 }
 ```
 
diff --git a/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/Solution.cpp b/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/Solution.cpp
index 71e2653dcd012..76f4c50b2ac58 100644
--- a/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/Solution.cpp	
+++ b/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/Solution.cpp	
@@ -1,30 +1,28 @@
 class Solution {
 public:
     int maxLength(vector<string>& arr) {
+        vector<int> s = {0};
         int ans = 0;
-        vector<int> masks = {0};
-        for (auto& s : arr) {
-            int mask = 0;
-            for (auto& c : s) {
-                int i = c - 'a';
-                if (mask >> i & 1) {
-                    mask = 0;
+        for (const string& t : arr) {
+            int x = 0;
+            for (char c : t) {
+                int b = c - 'a';
+                if ((x >> b & 1) == 1) {
+                    x = 0;
                     break;
                 }
-                mask |= 1 << i;
+                x |= 1 << b;
             }
-            if (mask == 0) {
-                continue;
-            }
-            int n = masks.size();
-            for (int i = 0; i < n; ++i) {
-                int m = masks[i];
-                if ((m & mask) == 0) {
-                    masks.push_back(m | mask);
-                    ans = max(ans, __builtin_popcount(m | mask));
+            if (x > 0) {
+                for (int i = s.size() - 1; i >= 0; --i) {
+                    int y = s[i];
+                    if ((x & y) == 0) {
+                        s.push_back(x | y);
+                        ans = max(ans, __builtin_popcount(x | y));
+                    }
                 }
             }
         }
         return ans;
     }
-};
\ No newline at end of file
+};
diff --git a/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/Solution.go b/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/Solution.go
index f1f2f02c47eb3..095f0d2809e73 100644
--- a/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/Solution.go	
+++ b/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/Solution.go	
@@ -1,25 +1,24 @@
 func maxLength(arr []string) (ans int) {
-	masks := []int{0}
-	for _, s := range arr {
-		mask := 0
-		for _, c := range s {
-			i := int(c - 'a')
-			if mask>>i&1 == 1 {
-				mask = 0
+	s := []int{0}
+	for _, t := range arr {
+		x := 0
+		for _, c := range t {
+			b := int(c - 'a')
+			if (x>>b)&1 == 1 {
+				x = 0
 				break
 			}
-			mask |= 1 << i
+			x |= 1 << b
 		}
-		if mask == 0 {
-			continue
-		}
-		n := len(masks)
-		for _, m := range masks[:n] {
-			if m&mask == 0 {
-				masks = append(masks, m|mask)
-				ans = max(ans, bits.OnesCount(uint(m|mask)))
+		if x > 0 {
+			for i := len(s) - 1; i >= 0; i-- {
+				y := s[i]
+				if (x & y) == 0 {
+					s = append(s, x|y)
+					ans = max(ans, bits.OnesCount(uint(x|y)))
+				}
 			}
 		}
 	}
-	return
-}
\ No newline at end of file
+	return ans
+}
diff --git a/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/Solution.java b/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/Solution.java
index 47e50759aea30..fee4b6904b825 100644
--- a/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/Solution.java	
+++ b/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/Solution.java	
@@ -1,30 +1,28 @@
 class Solution {
     public int maxLength(List<String> arr) {
+        List<Integer> s = new ArrayList<>();
+        s.add(0);
         int ans = 0;
-        List<Integer> masks = new ArrayList<>();
-        masks.add(0);
-        for (var s : arr) {
-            int mask = 0;
-            for (int i = 0; i < s.length(); ++i) {
-                int j = s.charAt(i) - 'a';
-                if (((mask >> j) & 1) == 1) {
-                    mask = 0;
+        for (var t : arr) {
+            int x = 0;
+            for (char c : t.toCharArray()) {
+                int b = c - 'a';
+                if ((x >> b & 1) == 1) {
+                    x = 0;
                     break;
                 }
-                mask |= 1 << j;
+                x |= 1 << b;
             }
-            if (mask == 0) {
-                continue;
-            }
-            int n = masks.size();
-            for (int i = 0; i < n; ++i) {
-                int m = masks.get(i);
-                if ((m & mask) == 0) {
-                    masks.add(m | mask);
-                    ans = Math.max(ans, Integer.bitCount(m | mask));
+            if (x > 0) {
+                for (int i = s.size() - 1; i >= 0; --i) {
+                    int y = s.get(i);
+                    if ((x & y) == 0) {
+                        s.add(x | y);
+                        ans = Math.max(ans, Integer.bitCount(x | y));
+                    }
                 }
             }
         }
         return ans;
     }
-}
\ No newline at end of file
+}
diff --git a/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/Solution.py b/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/Solution.py
index 1e63cce9be627..79fd149c270da 100644
--- a/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/Solution.py	
+++ b/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/Solution.py	
@@ -1,19 +1,13 @@
 class Solution:
     def maxLength(self, arr: List[str]) -> int:
-        ans = 0
-        masks = [0]
-        for s in arr:
-            mask = 0
-            for c in s:
-                i = ord(c) - ord('a')
-                if mask >> i & 1:
-                    mask = 0
+        s = [0]
+        for t in arr:
+            x = 0
+            for b in map(lambda c: ord(c) - 97, t):
+                if x >> b & 1:
+                    x = 0
                     break
-                mask |= 1 << i
-            if mask == 0:
-                continue
-            for m in masks:
-                if m & mask == 0:
-                    masks.append(m | mask)
-                    ans = max(ans, (m | mask).bit_count())
-        return ans
+                x |= 1 << b
+            if x:
+                s.extend((x | y) for y in s if (x & y) == 0)
+        return max(x.bit_count() for x in s)
diff --git a/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/Solution.ts b/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/Solution.ts
new file mode 100644
index 0000000000000..15e3c3a6e7269
--- /dev/null
+++ b/solution/1200-1299/1239.Maximum Length of a Concatenated String with Unique Characters/Solution.ts	
@@ -0,0 +1,36 @@
+function maxLength(arr: string[]): number {
+    const s: number[] = [0];
+    let ans = 0;
+    for (const t of arr) {
+        let x = 0;
+        for (const c of t) {
+            const b = c.charCodeAt(0) - 97;
+            if ((x >> b) & 1) {
+                x = 0;
+                break;
+            }
+            x |= 1 << b;
+        }
+
+        if (x > 0) {
+            for (let i = s.length - 1; ~i; --i) {
+                const y = s[i];
+                if ((x & y) === 0) {
+                    s.push(x | y);
+                    ans = Math.max(ans, bitCount(x | y));
+                }
+            }
+        }
+    }
+
+    return ans;
+}
+
+function bitCount(i: number): number {
+    i = i - ((i >>> 1) & 0x55555555);
+    i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
+    i = (i + (i >>> 4)) & 0x0f0f0f0f;
+    i = i + (i >>> 8);
+    i = i + (i >>> 16);
+    return i & 0x3f;
+}