Skip to content

Commit 9cc4c98

Browse files
committed
[hackerrank] "Fraudulent Activity notifications" O(Nd) 혹은 O(N)으로의 개선
1 parent 21c29ce commit 9cc4c98

File tree

2 files changed

+40
-34
lines changed

2 files changed

+40
-34
lines changed
Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,51 @@
11
package hackerrank.sorting
22

33
fun activityNotifications(expenditure: Array<Int>, d: Int): Int {
4-
var count = 0
4+
var notification = 0
5+
val counts = IntArray(200 + 1)
56

6-
(d until expenditure.size).forEach {
7-
if (isNotification(expenditure, it, d)) count++
7+
(0 until d).forEach {
8+
counts[expenditure[it]] += 1
89
}
910

10-
return count
11-
}
12-
13-
fun isNotification(
14-
expenditure: Array<Int>,
15-
index: Int,
16-
range: Int
17-
): Boolean {
18-
19-
val median = median(
20-
expenditure,
21-
index - range,
22-
index - 1
23-
)
11+
var startDay = 0
12+
(d until expenditure.size).forEach {
13+
val median = median(counts, d)
14+
if (expenditure[it] >= median * 2) {
15+
notification++
16+
}
17+
18+
counts[expenditure[startDay]] -= 1
19+
counts[expenditure[it]] += 1
20+
startDay++
21+
}
2422

25-
return expenditure[index].toFloat() >= (median * 2f)
23+
return notification
2624
}
2725

28-
private fun median(
29-
source: Array<Int>,
30-
from: Int,
31-
to: Int
32-
): Float {
33-
34-
val copy = source
35-
.copyOfRange(from, to + 1)
36-
.apply { sort() }
37-
38-
val mid = copy.size.div(2)
39-
40-
return if (copy.size.rem(2) == 0) {
41-
(copy[mid] + copy[mid + 1]).div(2f)
42-
} else {
43-
copy[mid].toFloat()
26+
fun median(counts: IntArray, days: Int): Float {
27+
val isOdd = days.rem(2) == 1
28+
var accum = 0
29+
var left = -1
30+
31+
counts.forEachIndexed { index, count ->
32+
accum += count
33+
if (isOdd) {
34+
if (accum - 1 >= days.div(2))
35+
return index.toFloat()
36+
} else {
37+
if (accum == days.div(2)) {
38+
left = index
39+
}
40+
if (accum > days.div(2)) {
41+
return if (left == -1) {
42+
index.toFloat()
43+
} else {
44+
(left + index).div(2f)
45+
}
46+
}
47+
}
4448
}
4549

50+
throw IllegalStateException("invalid fraudulent detection")
4651
}

src/test/kotlin/hackerrank/sorting/FraudulentActivityNotificationsKtTest.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ class FraudulentActivityNotificationsKtTest {
99
fun activityNotifications() {
1010
assertEquals(2, activityNotifications(arrayOf(2, 3, 4, 2, 3, 6, 8, 4, 5), 5))
1111
assertEquals(0, activityNotifications(arrayOf(1, 2, 3, 4, 4), 4))
12+
assertEquals(1, activityNotifications(arrayOf(4, 2, 3, 6, 5), 3))
1213
}
1314

1415
}

0 commit comments

Comments
 (0)