-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy path11. Sieve of Eratosthenes. CountNonDivisible.swift
87 lines (72 loc) · 2.57 KB
/
11. Sieve of Eratosthenes. CountNonDivisible.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import Foundation
import Glibc
// Solution @ Sergey Leschev, Belarusian State University
// 11. Sieve of Eratosthenes. CountNonDivisible.
// You are given an array A consisting of N integers.
// For each number A[i] such that 0 ≤ i < N, we want to count the number of elements of the array that are not the divisors of A[i]. We say that these elements are non-divisors.
// For example, consider integer N = 5 and array A such that:
// A[0] = 3
// A[1] = 1
// A[2] = 2
// A[3] = 3
// A[4] = 6
// For the following elements:
// A[0] = 3, the non-divisors are: 2, 6,
// A[1] = 1, the non-divisors are: 3, 2, 3, 6,
// A[2] = 2, the non-divisors are: 3, 3, 6,
// A[3] = 3, the non-divisors are: 2, 6,
// A[4] = 6, there aren't any non-divisors.
// Write a function:
// class Solution { public int[] solution(int[] A); }
// that, given an array A consisting of N integers, returns a sequence of integers representing the amount of non-divisors.
// Result array should be returned as an array of integers.
// For example, given:
// A[0] = 3
// A[1] = 1
// A[2] = 2
// A[3] = 3
// A[4] = 6
// the function should return [2, 4, 3, 2, 0], as explained above.
// Write an efficient algorithm for the following assumptions:
// N is an integer within the range [1..50,000];
// each element of array A is an integer within the range [1..2 * N].
public func solution(_ A: inout [Int]) -> [Int] {
let maxNumber = 2 * 50_000
let totalCount = A.count
var allNumbersDict = [Int: Int]()
var resultsDict = [Int: Int]()
var results = [Int]()
for i in 0..<totalCount {
let number = A[i]
if let count = allNumbersDict[number] {
allNumbersDict[number] = count + 1
} else {
allNumbersDict[number] = 1
}
}
for entry in allNumbersDict {
let number = entry.key
var k = number * 2
while k <= maxNumber {
if allNumbersDict[k] != nil {
let duplicates = allNumbersDict[number]!
if let count = resultsDict[k] {
resultsDict[k] = count + duplicates
} else {
resultsDict[k] = duplicates
}
}
k += number
}
}
for i in 0..<totalCount {
let number = A[i]
let duplicates = allNumbersDict[number]!
if let count = resultsDict[number] {
results.append(totalCount - count - duplicates)
} else {
results.append(totalCount - duplicates)
}
}
return results
}