Skip to content

Commit 87494f1

Browse files
pa-kh039cclausspre-commit-ci[bot]
authored
largest divisible subset (#9825)
* largest divisible subset * minor tweaks * adding more test cases Co-authored-by: Christian Clauss <cclauss@me.com> * improving code for better readability Co-authored-by: Christian Clauss <cclauss@me.com> * update Co-authored-by: Christian Clauss <cclauss@me.com> * update Co-authored-by: Christian Clauss <cclauss@me.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * suggested changes done, and further modfications * final update * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update largest_divisible_subset.py * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update largest_divisible_subset.py --------- Co-authored-by: Christian Clauss <cclauss@me.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent deb0480 commit 87494f1

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
from __future__ import annotations
2+
3+
4+
def largest_divisible_subset(items: list[int]) -> list[int]:
5+
"""
6+
Algorithm to find the biggest subset in the given array such that for any 2 elements
7+
x and y in the subset, either x divides y or y divides x.
8+
>>> largest_divisible_subset([1, 16, 7, 8, 4])
9+
[16, 8, 4, 1]
10+
>>> largest_divisible_subset([1, 2, 3])
11+
[2, 1]
12+
>>> largest_divisible_subset([-1, -2, -3])
13+
[-3]
14+
>>> largest_divisible_subset([1, 2, 4, 8])
15+
[8, 4, 2, 1]
16+
>>> largest_divisible_subset((1, 2, 4, 8))
17+
[8, 4, 2, 1]
18+
>>> largest_divisible_subset([1, 1, 1])
19+
[1, 1, 1]
20+
>>> largest_divisible_subset([0, 0, 0])
21+
[0, 0, 0]
22+
>>> largest_divisible_subset([-1, -1, -1])
23+
[-1, -1, -1]
24+
>>> largest_divisible_subset([])
25+
[]
26+
"""
27+
# Sort the array in ascending order as the sequence does not matter we only have to
28+
# pick up a subset.
29+
items = sorted(items)
30+
31+
number_of_items = len(items)
32+
33+
# Initialize memo with 1s and hash with increasing numbers
34+
memo = [1] * number_of_items
35+
hash_array = list(range(number_of_items))
36+
37+
# Iterate through the array
38+
for i, item in enumerate(items):
39+
for prev_index in range(i):
40+
if ((items[prev_index] != 0 and item % items[prev_index]) == 0) and (
41+
(1 + memo[prev_index]) > memo[i]
42+
):
43+
memo[i] = 1 + memo[prev_index]
44+
hash_array[i] = prev_index
45+
46+
ans = -1
47+
last_index = -1
48+
49+
# Find the maximum length and its corresponding index
50+
for i, memo_item in enumerate(memo):
51+
if memo_item > ans:
52+
ans = memo_item
53+
last_index = i
54+
55+
# Reconstruct the divisible subset
56+
if last_index == -1:
57+
return []
58+
result = [items[last_index]]
59+
while hash_array[last_index] != last_index:
60+
last_index = hash_array[last_index]
61+
result.append(items[last_index])
62+
63+
return result
64+
65+
66+
if __name__ == "__main__":
67+
from doctest import testmod
68+
69+
testmod()
70+
71+
items = [1, 16, 7, 8, 4]
72+
print(
73+
f"The longest divisible subset of {items} is {largest_divisible_subset(items)}."
74+
)

0 commit comments

Comments
 (0)