Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 39b47ca

Browse files
Optimize solution of InfectionDistribution task
1 parent 39a8668 commit 39b47ca

File tree

3 files changed

+34
-176
lines changed

3 files changed

+34
-176
lines changed

‎README.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ notes about interview preparation and useful links.
161161
| Удаление элемента заданной величины из массива (leetcode) | [Youtube](https://youtu.be/ECdosiz1ZPM) | [Code](src/main/java/by/andd3dfx/common/RemoveElement.java) |
162162
| ДВЕ задачи про ДВЕри | [Youtube](https://youtu.be/ix81AbCNiBE) | [Code](src/main/java/by/andd3dfx/common/DoorNBox.java) [Code2](src/main/java/by/andd3dfx/common/DoorsNKeys.java) |
163163
| Добавление многопоточности при параллельных запросах в разные системы | [Youtube](https://youtu.be/3IGsZy0uTSk) | [Code](src/main/java/by/andd3dfx/multithreading/AddMultithreading.java) |
164-
| Распространение чумы между городами (2 решения) | [Youtube](https://youtu.be/Ei1uCCD_Iqg) | [Code](src/main/java/by/andd3dfx/common/InfectionDistribution.java) |
164+
| Распространение заражения между городами (2 решения) | [Youtube](https://youtu.be/Ei1uCCD_Iqg) | - |
165165
| Реверсирование порядка цифр в числе (2 решения) | [Youtube](https://youtu.be/w3C4L7GxD7M) | [Code](src/main/java/by/andd3dfx/numeric/ReverseDigitsOrder.java) |
166166
| Поиск среди пар чисел значения, встречающегося однажды: магия XOR (2 решения) (leetcode) | [Youtube](https://youtu.be/dNB8tOvx5Gk) | [Code](src/main/java/by/andd3dfx/numeric/FindNumberWhichAppearsOnce.java) |
167167
| Удаление дубликатов в сортированном связном списке ч.I, II (leetcode) | [Youtube](https://youtu.be/ryE_Q_AtAg8) | [Code](src/main/java/by/andd3dfx/collections/RemoveDuplicatesFromSortedLinkedList.java) [Code2](src/main/java/by/andd3dfx/collections/RemoveDuplicatesFromSortedLinkedList_II.java) |
@@ -265,3 +265,4 @@ notes about interview preparation and useful links.
265265
| 7 классических задач (музыкальный выпуск) | [Youtube](https://youtu.be/KlD0hWZLFbg) | - |
266266
| Решение дифф. уравнений в ЧП на Java численно | [Youtube](https://youtu.be/AmPgu9vksTU) | [Repo](https://github.com/andrei-punko/pde-solvers) |
267267
| 5 сортировок (музыкальный выпуск) | [Youtube](https://youtu.be/tOu0W-hkFCE) | - |
268+
| Распространение заражения между городами 2: матрица смежности | [Youtube](https://youtu.be/d9v9DS1YVtk) | [Code](src/main/java/by/andd3dfx/common/InfectionDistribution.java) |
Lines changed: 19 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
package by.andd3dfx.common;
22

3-
import lombok.Data;
4-
53
import java.util.Arrays;
6-
import java.util.HashMap;
74
import java.util.HashSet;
8-
import java.util.Map;
95
import java.util.Set;
106
import java.util.stream.Collectors;
117

@@ -29,118 +25,41 @@
2925
*/
3026
public class InfectionDistribution {
3127

32-
/**
33-
* Initial solution
34-
*/
35-
public static int weeksToInfectAllCities_usingIterationByRoads(int citiesAmount, int[][] roads, int[] infected) {
36-
int weeksCount = 0;
37-
var infectedCitiesSet = Arrays.stream(infected).boxed()
38-
.collect(Collectors.toSet());
39-
var roadsSet = buildRoadsSet(roads);
40-
41-
while (!isAllInfected(citiesAmount, infectedCitiesSet)) {
42-
var infectedOnThisIteration = processOneWeek(roadsSet, infectedCitiesSet);
43-
44-
if (infectedOnThisIteration == 0) {
45-
throw new IllegalArgumentException("Could not infect all cities!");
46-
}
47-
weeksCount++;
48-
}
49-
50-
return weeksCount;
51-
}
52-
53-
private static boolean isAllInfected(int citiesAmount, Set<Integer> infectedCitiesSet) {
54-
return infectedCitiesSet.size() == citiesAmount;
55-
}
56-
57-
private static Set<Road> buildRoadsSet(int[][] roads) {
58-
return Arrays.stream(roads)
59-
.map(Road::new)
60-
.collect(Collectors.toSet());
61-
}
62-
63-
private static int processOneWeek(Set<Road> roads, Set<Integer> infectedCitiesSet) {
64-
var initialCitiesSet = new HashSet<>(infectedCitiesSet);
65-
66-
var it = roads.iterator();
67-
while (it.hasNext()) {
68-
var road = it.next();
69-
70-
if (initialCitiesSet.contains(road.start)) {
71-
infectedCitiesSet.add(road.end);
72-
it.remove();
73-
continue;
74-
}
75-
76-
if (initialCitiesSet.contains(road.end)) {
77-
infectedCitiesSet.add(road.start);
78-
it.remove();
79-
}
80-
}
81-
82-
return infectedCitiesSet.size() - initialCitiesSet.size();
83-
}
84-
85-
@Data
86-
private static class Road {
87-
private int start;
88-
private int end;
89-
90-
public Road(int[] road) {
91-
this.start = road[0];
92-
this.end = road[1];
93-
}
94-
}
95-
96-
/**
97-
* Enhanced solution
98-
*/
99-
public static int weeksToInfectAllCities_usingIterationByInfectedCities(int citiesAmount, int[][] roads, int[] infected) {
100-
var routesMap = new HashMap<Integer, Set<Integer>>();
28+
public static int weeksToInfectAllCities(int citiesAmount, int[][] roads, int[] infected) {
29+
var adjMatrix = new boolean[citiesAmount][citiesAmount]; // adjacency matrix
10130
Arrays.stream(roads).forEach(road -> {
102-
populate(routesMap, road, 0, 1);
103-
populate(routesMap, road, 1, 0);
31+
adjMatrix[road[0]][road[1]] = true;
32+
adjMatrix[road[1]][road[0]] = true;
10433
});
10534

10635
var weeksAmount = 0;
10736
var infectedCities = Arrays.stream(infected).boxed().collect(Collectors.toSet());
108-
var sourceCities = new HashSet<>(infectedCities);
10937

110-
while (!isAllInfected(citiesAmount, infectedCities)) {
111-
if (sourceCities.isEmpty()) {
112-
throw new IllegalArgumentException("Could not infect all cities!");
38+
while (infectedCities.size() < citiesAmount) {
39+
var newCities = determineNewInfectedCities(infectedCities, adjMatrix);
40+
if (newCities.isEmpty()) {
41+
return -1;
11342
}
11443

115-
var newInfectedCities = determineNewInfectedCities(routesMap, infectedCities, sourceCities);
116-
infectedCities.addAll(newInfectedCities);
117-
sourceCities = newInfectedCities;
44+
infectedCities.addAll(newCities);
45+
11846
weeksAmount++;
11947
}
12048

12149
return weeksAmount;
12250
}
12351

124-
private static HashSet<Integer> determineNewInfectedCities(
125-
Map<Integer, Set<Integer>> routesMap, Set<Integer> infectedCities, Set<Integer> sourceCities) {
126-
var newInfectedCities = new HashSet<Integer>();
127-
for (var city : sourceCities) {
128-
if (!routesMap.containsKey(city)) {
129-
continue;
52+
private static Set<Integer> determineNewInfectedCities(Set<Integer> infectedCities, boolean[][] adjMatrix) {
53+
var n = adjMatrix.length;
54+
var newCities = new HashSet<Integer>();
55+
for (var city : infectedCities) {
56+
for (int i = 0; i < n; i++) {
57+
if (adjMatrix[city][i] && !infectedCities.contains(i)) {
58+
newCities.add(i);
59+
}
13060
}
131-
132-
var citiesToInfect = new HashSet<>(routesMap.get(city));
133-
citiesToInfect.removeAll(infectedCities);
134-
135-
newInfectedCities.addAll(citiesToInfect);
13661
}
137-
return newInfectedCities;
138-
}
13962

140-
private static void populate(Map<Integer, Set<Integer>> routesMap, int[] road, int i, int j) {
141-
if (!routesMap.containsKey(road[i])) {
142-
routesMap.put(road[i], new HashSet<>());
143-
}
144-
routesMap.get(road[i]).add(road[j]);
63+
return newCities;
14564
}
14665
}

‎src/test/java/by/andd3dfx/common/InfectionDistributionTest.java‎

Lines changed: 13 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,26 @@
22

33
import org.junit.Test;
44

5-
import static by.andd3dfx.common.InfectionDistribution.weeksToInfectAllCities_usingIterationByInfectedCities;
6-
import static by.andd3dfx.common.InfectionDistribution.weeksToInfectAllCities_usingIterationByRoads;
5+
import static by.andd3dfx.common.InfectionDistribution.weeksToInfectAllCities;
76
import static org.assertj.core.api.Assertions.assertThat;
8-
import static org.junit.Assert.assertThrows;
97

108
public class InfectionDistributionTest {
119

1210
@Test
13-
public void weeksToInfectAllCitiesPositive_usingIterationByRoads() {
14-
assertThat(weeksToInfectAllCities_usingIterationByRoads(
11+
public void weeksToInfectAllCitiesPositive() {
12+
assertThat(weeksToInfectAllCities(
1513
1,
1614
new int[][]{},
1715
new int[]{0}
1816
)).isEqualTo(0);
1917

20-
assertThat(weeksToInfectAllCities_usingIterationByRoads(
18+
assertThat(weeksToInfectAllCities(
2119
2,
2220
new int[][]{new int[]{0, 1}},
2321
new int[]{0}
2422
)).isEqualTo(1);
2523

26-
assertThat(weeksToInfectAllCities_usingIterationByRoads(
24+
assertThat(weeksToInfectAllCities(
2725
5,
2826
new int[][]{
2927
new int[]{0, 2},
@@ -33,7 +31,7 @@ public void weeksToInfectAllCitiesPositive_usingIterationByRoads() {
3331
new int[]{0, 3}
3432
)).isEqualTo(2);
3533

36-
assertThat(weeksToInfectAllCities_usingIterationByRoads(
34+
assertThat(weeksToInfectAllCities(
3735
7,
3836
new int[][]{
3937
new int[]{0, 2},
@@ -48,80 +46,20 @@ public void weeksToInfectAllCitiesPositive_usingIterationByRoads() {
4846
}
4947

5048
@Test
51-
public void weeksToInfectAllCitiesNegative_usingIterationByRoads() {
52-
assertThrows("Could not infect all cities!", IllegalArgumentException.class,
53-
() -> weeksToInfectAllCities_usingIterationByRoads(
54-
1,
55-
new int[][]{},
56-
new int[]{}
57-
));
58-
59-
assertThrows("Could not infect all cities!", IllegalArgumentException.class,
60-
() -> weeksToInfectAllCities_usingIterationByRoads(
61-
5,
62-
new int[][]{
63-
new int[]{0, 2},
64-
new int[]{1, 4},
65-
},
66-
new int[]{0, 3}
67-
));
68-
}
69-
70-
@Test
71-
public void weeksToInfectAllCitiesPositive_usingIterationByCities() {
72-
assertThat(weeksToInfectAllCities_usingIterationByInfectedCities(
49+
public void weeksToInfectAllCitiesNegative() {
50+
assertThat(weeksToInfectAllCities(
7351
1,
7452
new int[][]{},
75-
new int[]{0}
76-
)).isEqualTo(0);
53+
new int[]{}
54+
)).isEqualTo(-1);
7755

78-
assertThat(weeksToInfectAllCities_usingIterationByInfectedCities(
79-
2,
80-
new int[][]{new int[]{0, 1}},
81-
new int[]{0}
82-
)).isEqualTo(1);
83-
84-
assertThat(weeksToInfectAllCities_usingIterationByInfectedCities(
56+
assertThat(weeksToInfectAllCities(
8557
5,
8658
new int[][]{
8759
new int[]{0, 2},
88-
new int[]{1, 2},
89-
new int[]{3, 4},
60+
new int[]{1, 4},
9061
},
9162
new int[]{0, 3}
92-
)).isEqualTo(2);
93-
94-
assertThat(weeksToInfectAllCities_usingIterationByInfectedCities(
95-
7,
96-
new int[][]{
97-
new int[]{0, 2},
98-
new int[]{1, 2},
99-
new int[]{3, 4},
100-
new int[]{6, 4},
101-
new int[]{6, 5},
102-
new int[]{1, 5},
103-
},
104-
new int[]{0}
105-
)).isEqualTo(6);
106-
}
107-
108-
@Test
109-
public void weeksToInfectAllCitiesNegative_usingIterationByCities() {
110-
assertThrows("Could not infect all cities!", IllegalArgumentException.class,
111-
() -> weeksToInfectAllCities_usingIterationByInfectedCities(
112-
1,
113-
new int[][]{},
114-
new int[]{}
115-
));
116-
117-
assertThrows("Could not infect all cities!", IllegalArgumentException.class,
118-
() -> weeksToInfectAllCities_usingIterationByInfectedCities(
119-
5,
120-
new int[][]{
121-
new int[]{0, 2},
122-
new int[]{1, 4},
123-
},
124-
new int[]{0, 3}
125-
));
63+
)).isEqualTo(-1);
12664
}
12765
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /