Skip to content

Commit 2fdeff3

Browse files
committed
Improved task 3470
1 parent 1bf553a commit 2fdeff3

File tree

1 file changed

+83
-110
lines changed

1 file changed

+83
-110
lines changed
Lines changed: 83 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,147 +1,120 @@
11
package g3401_3500.s3470_permutations_iv;
22

3-
// #Hard #2025_03_02_Time_12_ms_(100.00%)_Space_45.94_MB_(100.00%)
3+
// #Hard #2025_03_02_Time_12_ms_(100.00%)_Space_44.78_MB_(100.00%)
44

55
import java.util.ArrayList;
6-
import java.util.Arrays;
76
import java.util.List;
87

9-
public class Solution {
10-
// Define a large constant value to cap calculations and prevent overflow
11-
private static final long CAP = 1000000000000001L;
12-
// 3D DP array to store precomputed results for dynamic programming
13-
private static final long[][][] DP = new long[105][105][3];
8+
class Solution {
9+
private static final long INF = 1_000_000_000_000_000_000L;
1410

15-
// Initialize DP array with -1 (indicating uncomputed states)
16-
static {
17-
for (long[][] longs : DP) {
18-
for (long[] aLong : longs) {
19-
Arrays.fill(aLong, -1);
11+
private long helper(int a, int b) {
12+
long res = 1;
13+
for (int i = 0; i < b; i++) {
14+
res *= (a - i);
15+
if (res > INF) {
16+
return INF;
2017
}
2118
}
19+
return res;
2220
}
2321

24-
// Recursive function to count alternating permutations
25-
private long rec(int o, int e, int req) {
26-
if (o == 0 && e == 0) {
22+
private long solve(int odd, int even, int r, int req) {
23+
if (r == 0) {
2724
return 1;
2825
}
29-
if (DP[o][e][req] != -1) {
30-
return DP[o][e][req];
31-
}
32-
long count = 0;
33-
if (req == 2) {
34-
if (o > 0) {
35-
count = addCapped(count, multiplyCapped(o, rec(o - 1, e, 1)));
36-
}
37-
if (e > 0) {
38-
count = addCapped(count, multiplyCapped(e, rec(o, e - 1, 0)));
39-
}
40-
} else if (req == 0) {
41-
if (o > 0) {
42-
count = multiplyCapped(o, rec(o - 1, e, 1));
43-
}
26+
int nodd;
27+
int neven;
28+
if (req == 1) {
29+
nodd = (r + 1) / 2;
30+
neven = r / 2;
4431
} else {
45-
if (e > 0) {
46-
count = multiplyCapped(e, rec(o, e - 1, 0));
47-
}
32+
neven = (r + 1) / 2;
33+
nodd = r / 2;
4834
}
49-
DP[o][e][req] = count;
50-
return count;
51-
}
52-
53-
// Helper function to prevent overflow when multiplying
54-
private long multiplyCapped(long a, long b) {
55-
if (b == 0) {
35+
if (odd < nodd || even < neven) {
5636
return 0;
5737
}
58-
if (a >= CAP || b >= CAP || a > CAP / b) {
59-
return CAP;
38+
long oddways = helper(odd, nodd);
39+
long evenways = helper(even, neven);
40+
long total = oddways;
41+
if (evenways == 0 || total > INF / evenways) {
42+
total = INF;
43+
} else {
44+
total *= evenways;
6045
}
61-
return a * b;
62-
}
63-
64-
// Helper function to prevent overflow when adding
65-
private long addCapped(long a, long b) {
66-
long res = a + b;
67-
return Math.min(res, CAP);
46+
return total;
6847
}
6948

7049
public int[] permute(int n, long k) {
71-
// Separate odd and even numbers from 1 to n
72-
List<Integer> odds = new ArrayList<>();
73-
List<Integer> evens = new ArrayList<>();
74-
for (int x = 1; x <= n; x++) {
75-
if ((x & 1) == 1) {
76-
odds.add(x);
50+
List<Integer> ans = new ArrayList<>();
51+
boolean first = false;
52+
boolean[] used = new boolean[n + 1];
53+
int odd = (n + 1) / 2;
54+
int even = n / 2;
55+
int last = -1;
56+
for (int i = 1; i <= n; i++) {
57+
if (used[i]) {
58+
continue;
59+
}
60+
int odd2 = odd;
61+
int even2 = even;
62+
int cp = i & 1;
63+
int next = (cp == 1 ? 0 : 1);
64+
if (cp == 1) {
65+
odd2--;
66+
} else {
67+
even2--;
68+
}
69+
int r = n - 1;
70+
long cnt = solve(odd2, even2, r, next);
71+
if (k > cnt) {
72+
k -= cnt;
7773
} else {
78-
evens.add(x);
74+
ans.add(i);
75+
used[i] = true;
76+
odd = odd2;
77+
even = even2;
78+
last = cp;
79+
first = true;
80+
break;
7981
}
8082
}
81-
// Count the number of odd and even elements
82-
int oCount = odds.size();
83-
int eCount = evens.size();
84-
long ansTotal = rec(oCount, eCount, 2);
85-
if (k > ansTotal) {
83+
if (!first) {
8684
return new int[0];
8785
}
88-
List<Integer> result = new ArrayList<>();
89-
int req = 2;
90-
while (oCount + eCount > 0) {
91-
List<Integer> candidates = new ArrayList<>();
92-
if (req == 2) {
93-
int i = 0;
94-
int j = 0;
95-
while (i < odds.size() || j < evens.size()) {
96-
if (j >= evens.size() || (i < odds.size() && odds.get(i) < evens.get(j))) {
97-
candidates.add(odds.get(i++));
86+
for (int z = 1; z < n; z++) {
87+
boolean taken = false;
88+
for (int j = 1; j <= n; j++) {
89+
if (!used[j] && ((j & 1) != last)) {
90+
int odd2 = odd;
91+
int even2 = even;
92+
int cp = j & 1;
93+
if (cp == 1) {
94+
odd2--;
9895
} else {
99-
candidates.add(evens.get(j++));
96+
even2--;
10097
}
101-
}
102-
} else if (req == 0) {
103-
candidates.addAll(odds);
104-
} else {
105-
candidates.addAll(evens);
106-
}
107-
boolean found = false;
108-
for (int num : candidates) {
109-
int candidateParity = (num % 2 == 1) ? 0 : 1;
110-
if (req != 2 && candidateParity != req) {
111-
continue;
112-
}
113-
long ways;
114-
if (candidateParity == 0) {
115-
ways = rec(oCount - 1, eCount, 1);
116-
} else {
117-
ways = rec(oCount, eCount - 1, 0);
118-
}
119-
if (ways >= k) {
120-
result.add(num);
121-
if (candidateParity == 0) {
122-
odds.remove(Integer.valueOf(num));
123-
oCount--;
124-
req = 1;
98+
int r = n - (z + 1);
99+
int next = (cp == 1 ? 0 : 1);
100+
long cnt2 = solve(odd2, even2, r, next);
101+
if (k > cnt2) {
102+
k -= cnt2;
125103
} else {
126-
evens.remove(Integer.valueOf(num));
127-
eCount--;
128-
req = 0;
104+
ans.add(j);
105+
used[j] = true;
106+
odd = odd2;
107+
even = even2;
108+
last = cp;
109+
taken = true;
110+
break;
129111
}
130-
found = true;
131-
break;
132-
} else {
133-
k -= ways;
134112
}
135113
}
136-
if (!found) {
114+
if (!taken) {
137115
return new int[0];
138116
}
139117
}
140-
// Convert result list to array and return
141-
int[] ans = new int[result.size()];
142-
for (int i = 0; i < result.size(); i++) {
143-
ans[i] = result.get(i);
144-
}
145-
return ans;
118+
return ans.stream().mapToInt(i -> i).toArray();
146119
}
147120
}

0 commit comments

Comments
 (0)