Skip to content

Commit e48dded

Browse files
committed
feat: add solutions to lc problem: No.0368
No.0368.Largest Divisible Subset
1 parent f81e8d4 commit e48dded

File tree

6 files changed

+314
-108
lines changed

6 files changed

+314
-108
lines changed

solution/0300-0399/0368.Largest Divisible Subset/README.md

Lines changed: 116 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,18 @@
4646

4747
<!-- 这里可写通用的实现逻辑 -->
4848

49+
**方法一:排序 + 动态规划**
50+
51+
我们先对数组进行排序,这样可以保证对于任意的 $i \lt j$,如果 $nums[i]$ 可以整除 $nums[j]$,那么 $nums[i]$ 一定在 $nums[j]$ 的左边。
52+
53+
接下来,我们定义 $f[i]$ 表示以 $nums[i]$ 为最大元素的最大整除子集的大小,初始时 $f[i]=1$。
54+
55+
对于每一个 $i$,我们从左往右枚举 $j$,如果 $nums[i]$ 可以被 $nums[j]$ 整除,那么 $f[i]$ 可以从 $f[j]$ 转移而来,我们更新 $f[i]=max(f[i], f[j]+1)$。过程中,我们记录 $f[i]$ 的最大值的下标 $k$ 以及对应的子集大小 $m$。
56+
57+
最后,我们从 $k$ 开始倒序遍历,如果 $nums[k]$ 可以被 $nums[i]$ 整除,且 $f[i]=m$,那么 $nums[i]$ 就是一个整除子集的元素,我们将 $nums[i]$ 加入答案,并将 $m$ 减 $1$,同时更新 $k=i$。继续倒序遍历,直到 $m=0$。
58+
59+
时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 是数组的长度。
60+
4961
<!-- tabs:start -->
5062

5163
### **Python3**
@@ -57,25 +69,23 @@ class Solution:
5769
def largestDivisibleSubset(self, nums: List[int]) -> List[int]:
5870
nums.sort()
5971
n = len(nums)
60-
f, p = [0] * n, [0] * n
72+
f = [1] * n
73+
k = 0
6174
for i in range(n):
62-
l, pre = 1, i
63-
for j in range(n):
64-
if nums[i] % nums[j] == 0 and f[j] + 1 > l:
65-
l = f[j] + 1
66-
pre = j
67-
f[i] = l
68-
p[i] = pre
69-
max_len, max_index = 0, 0
70-
for i, v in enumerate(f):
71-
if max_len < v:
72-
max_len = v
73-
max_index = i
75+
for j in range(i):
76+
if nums[i] % nums[j] == 0:
77+
f[i] = max(f[i], f[j] + 1)
78+
if f[k] < f[i]:
79+
k = i
80+
m = f[k]
81+
i = k
7482
ans = []
75-
while len(ans) < max_len:
76-
ans.append(nums[max_index])
77-
max_index = p[max_index]
78-
return ans[::-1]
83+
while m:
84+
if nums[k] % nums[i] == 0 and f[i] == m:
85+
ans.append(nums[i])
86+
k, m = i, m - 1
87+
i -= 1
88+
return ans
7989
```
8090

8191
### **Java**
@@ -87,36 +97,106 @@ class Solution {
8797
public List<Integer> largestDivisibleSubset(int[] nums) {
8898
Arrays.sort(nums);
8999
int n = nums.length;
90-
int[] f = new int[n], p = new int[n];
91-
for (int i = 0; i < n; i++) {
92-
int l = 1, pre = i;
93-
for (int j = 0; j < i; j++) {
94-
if (nums[i] % nums[j] == 0 && f[j] + 1 > l) {
95-
l = f[j] + 1;
96-
pre = j;
100+
int[] f = new int[n];
101+
Arrays.fill(f, 1);
102+
int k = 0;
103+
for (int i = 0; i < n; ++i) {
104+
for (int j = 0; j < i; ++j) {
105+
if (nums[i] % nums[j] == 0) {
106+
f[i] = Math.max(f[i], f[j] + 1);
97107
}
98108
}
99-
f[i] = l;
100-
p[i] = pre;
101-
}
102-
int maxLen = 0, maxIndex = 0;
103-
for (int i = 0; i < n; i++) {
104-
if (f[i] > maxLen) {
105-
maxLen = f[i];
106-
maxIndex = i;
109+
if (f[k] < f[i]) {
110+
k = i;
107111
}
108112
}
113+
int m = f[k];
109114
List<Integer> ans = new ArrayList<>();
110-
while (ans.size() < maxLen) {
111-
ans.add(nums[maxIndex]);
112-
maxIndex = p[maxIndex];
115+
for (int i = k; m > 0; --i) {
116+
if (nums[k] % nums[i] == 0 && f[i] == m) {
117+
ans.add(nums[i]);
118+
k = i;
119+
--m;
120+
}
113121
}
114-
Collections.reverse(ans);
115122
return ans;
116123
}
117124
}
118125
```
119126

127+
### **C++**
128+
129+
```cpp
130+
class Solution {
131+
public:
132+
vector<int> largestDivisibleSubset(vector<int>& nums) {
133+
sort(nums.begin(), nums.end());
134+
int n = nums.size();
135+
int f[n];
136+
int k = 0;
137+
for (int i = 0; i < n; ++i) {
138+
f[i] = 1;
139+
for (int j = 0; j < i; ++j) {
140+
if (nums[i] % nums[j] == 0) {
141+
f[i] = max(f[i], f[j] + 1);
142+
}
143+
}
144+
if (f[k] < f[i]) {
145+
k = i;
146+
}
147+
}
148+
int m = f[k];
149+
vector<int> ans;
150+
for (int i = k; m > 0; --i) {
151+
if (nums[k] % nums[i] == 0 && f[i] == m) {
152+
ans.push_back(nums[i]);
153+
k = i;
154+
--m;
155+
}
156+
}
157+
return ans;
158+
}
159+
};
160+
```
161+
162+
### **Go**
163+
164+
```go
165+
func largestDivisibleSubset(nums []int) (ans []int) {
166+
sort.Ints(nums)
167+
n := len(nums)
168+
f := make([]int, n)
169+
k := 0
170+
for i := 0; i < n; i++ {
171+
f[i] = 1
172+
for j := 0; j < i; j++ {
173+
if nums[i]%nums[j] == 0 {
174+
f[i] = max(f[i], f[j]+1)
175+
}
176+
}
177+
if f[k] < f[i] {
178+
k = i
179+
}
180+
}
181+
m := f[k]
182+
for i := k; m > 0; i-- {
183+
if nums[k]%nums[i] == 0 && f[i] == m {
184+
ans = append(ans, nums[i])
185+
k = i
186+
m--
187+
}
188+
}
189+
return
190+
}
191+
192+
func max(a, b int) int {
193+
if a > b {
194+
return a
195+
}
196+
return b
197+
}
198+
```
199+
120200
### **...**
121201

122202
```

solution/0300-0399/0368.Largest Divisible Subset/README_EN.md

Lines changed: 104 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -49,25 +49,23 @@ class Solution:
4949
def largestDivisibleSubset(self, nums: List[int]) -> List[int]:
5050
nums.sort()
5151
n = len(nums)
52-
f, p = [0] * n, [0] * n
52+
f = [1] * n
53+
k = 0
5354
for i in range(n):
54-
l, pre = 1, i
55-
for j in range(n):
56-
if nums[i] % nums[j] == 0 and f[j] + 1 > l:
57-
l = f[j] + 1
58-
pre = j
59-
f[i] = l
60-
p[i] = pre
61-
max_len, max_index = 0, 0
62-
for i, v in enumerate(f):
63-
if max_len < v:
64-
max_len = v
65-
max_index = i
55+
for j in range(i):
56+
if nums[i] % nums[j] == 0:
57+
f[i] = max(f[i], f[j] + 1)
58+
if f[k] < f[i]:
59+
k = i
60+
m = f[k]
61+
i = k
6662
ans = []
67-
while len(ans) < max_len:
68-
ans.append(nums[max_index])
69-
max_index = p[max_index]
70-
return ans[::-1]
63+
while m:
64+
if nums[k] % nums[i] == 0 and f[i] == m:
65+
ans.append(nums[i])
66+
k, m = i, m - 1
67+
i -= 1
68+
return ans
7169
```
7270

7371
### **Java**
@@ -77,36 +75,106 @@ class Solution {
7775
public List<Integer> largestDivisibleSubset(int[] nums) {
7876
Arrays.sort(nums);
7977
int n = nums.length;
80-
int[] f = new int[n], p = new int[n];
81-
for (int i = 0; i < n; i++) {
82-
int l = 1, pre = i;
83-
for (int j = 0; j < i; j++) {
84-
if (nums[i] % nums[j] == 0 && f[j] + 1 > l) {
85-
l = f[j] + 1;
86-
pre = j;
78+
int[] f = new int[n];
79+
Arrays.fill(f, 1);
80+
int k = 0;
81+
for (int i = 0; i < n; ++i) {
82+
for (int j = 0; j < i; ++j) {
83+
if (nums[i] % nums[j] == 0) {
84+
f[i] = Math.max(f[i], f[j] + 1);
8785
}
8886
}
89-
f[i] = l;
90-
p[i] = pre;
91-
}
92-
int maxLen = 0, maxIndex = 0;
93-
for (int i = 0; i < n; i++) {
94-
if (f[i] > maxLen) {
95-
maxLen = f[i];
96-
maxIndex = i;
87+
if (f[k] < f[i]) {
88+
k = i;
9789
}
9890
}
91+
int m = f[k];
9992
List<Integer> ans = new ArrayList<>();
100-
while (ans.size() < maxLen) {
101-
ans.add(nums[maxIndex]);
102-
maxIndex = p[maxIndex];
93+
for (int i = k; m > 0; --i) {
94+
if (nums[k] % nums[i] == 0 && f[i] == m) {
95+
ans.add(nums[i]);
96+
k = i;
97+
--m;
98+
}
10399
}
104-
Collections.reverse(ans);
105100
return ans;
106101
}
107102
}
108103
```
109104

105+
### **C++**
106+
107+
```cpp
108+
class Solution {
109+
public:
110+
vector<int> largestDivisibleSubset(vector<int>& nums) {
111+
sort(nums.begin(), nums.end());
112+
int n = nums.size();
113+
int f[n];
114+
int k = 0;
115+
for (int i = 0; i < n; ++i) {
116+
f[i] = 1;
117+
for (int j = 0; j < i; ++j) {
118+
if (nums[i] % nums[j] == 0) {
119+
f[i] = max(f[i], f[j] + 1);
120+
}
121+
}
122+
if (f[k] < f[i]) {
123+
k = i;
124+
}
125+
}
126+
int m = f[k];
127+
vector<int> ans;
128+
for (int i = k; m > 0; --i) {
129+
if (nums[k] % nums[i] == 0 && f[i] == m) {
130+
ans.push_back(nums[i]);
131+
k = i;
132+
--m;
133+
}
134+
}
135+
return ans;
136+
}
137+
};
138+
```
139+
140+
### **Go**
141+
142+
```go
143+
func largestDivisibleSubset(nums []int) (ans []int) {
144+
sort.Ints(nums)
145+
n := len(nums)
146+
f := make([]int, n)
147+
k := 0
148+
for i := 0; i < n; i++ {
149+
f[i] = 1
150+
for j := 0; j < i; j++ {
151+
if nums[i]%nums[j] == 0 {
152+
f[i] = max(f[i], f[j]+1)
153+
}
154+
}
155+
if f[k] < f[i] {
156+
k = i
157+
}
158+
}
159+
m := f[k]
160+
for i := k; m > 0; i-- {
161+
if nums[k]%nums[i] == 0 && f[i] == m {
162+
ans = append(ans, nums[i])
163+
k = i
164+
m--
165+
}
166+
}
167+
return
168+
}
169+
170+
func max(a, b int) int {
171+
if a > b {
172+
return a
173+
}
174+
return b
175+
}
176+
```
177+
110178
### **...**
111179

112180
```
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
class Solution {
2+
public:
3+
vector<int> largestDivisibleSubset(vector<int>& nums) {
4+
sort(nums.begin(), nums.end());
5+
int n = nums.size();
6+
int f[n];
7+
int k = 0;
8+
for (int i = 0; i < n; ++i) {
9+
f[i] = 1;
10+
for (int j = 0; j < i; ++j) {
11+
if (nums[i] % nums[j] == 0) {
12+
f[i] = max(f[i], f[j] + 1);
13+
}
14+
}
15+
if (f[k] < f[i]) {
16+
k = i;
17+
}
18+
}
19+
int m = f[k];
20+
vector<int> ans;
21+
for (int i = k; m > 0; --i) {
22+
if (nums[k] % nums[i] == 0 && f[i] == m) {
23+
ans.push_back(nums[i]);
24+
k = i;
25+
--m;
26+
}
27+
}
28+
return ans;
29+
}
30+
};

0 commit comments

Comments
 (0)