7
7
8
8
#include < iostream>
9
9
#include < map>
10
+ #include < set>
11
+ #include < unordered_map>
10
12
#include < vector>
11
13
12
14
using namespace std ;
13
15
14
- void merge (vector<int > & arr, int i, int k, int j) {
15
-
16
- int n1 = k - i + 1 ;
17
- int n2 = j - k;
18
- int * arr1 = new int [n1 + 1 ];
19
- int * arr2 = new int [n2 + 1 ];
20
- int arr_index = i;
21
- for (int arr1_index = 0 ; arr1_index < n1; ++arr1_index) {
22
- arr1[arr1_index] = arr[arr_index];
23
- arr_index++;
24
- }
25
-
26
- for (int arr2_index = 0 ; arr2_index < n2; ++arr2_index) {
27
- arr2[arr2_index] = arr[arr_index];
28
- arr_index++;
29
- }
30
-
31
- arr1[n1] = INT_MAX;
32
- arr2[n2] = INT_MAX;
33
-
34
- int arr1_index = 0 ;
35
- int arr2_index = 0 ;
36
- for (int arr_index = i; arr_index <= j; ++arr_index) {
37
- if (arr1[arr1_index] >= arr2[arr2_index]) {
38
- arr[arr_index] = arr2[arr2_index];
39
- arr2_index++;
40
- }
41
- else {
42
- arr[arr_index] = arr1[arr1_index];
43
- arr1_index++;
44
- }
45
- }
46
-
47
- // Free data
48
- delete [] arr1;
49
- delete [] arr2;
50
- }
51
-
52
- void merge_sort (vector<int > & arr, int i, int j) {
53
-
54
- if (j - i > 0 ) {
55
- int k = (i + j) / 2 ;
56
- merge_sort (arr, i, k);
57
- merge_sort (arr, k + 1 , j);
58
- merge (arr, i, k, j);
59
- }
60
- }
61
-
62
- void merge_sort_wrap (vector<int > & input_arr) {
63
-
64
- int n = (int ) input_arr.size ();
65
-
66
- // Perform sort
67
- merge_sort (input_arr, 0 , n - 1 );
68
- }
69
-
70
- void gen_numbers (long t, vector<int > & uglies, int n, long cap, map<long , long > & dp) {
16
+ void gen_numbers (long t, set<int > & uglies, long cap, unordered_map<long , long > & dp) {
71
17
18
+ // If uglies derived from t have been computed do not proceed with computation
72
19
if (dp[t] != 0 ) {
73
20
return ;
74
21
}
75
22
23
+ // Compute all uglies less than cap
76
24
if (t < cap) {
77
25
long val1 = t * 2 ;
78
26
long val2 = t * 3 ;
79
27
long val3 = t * 5 ;
80
28
81
29
if (val1 < cap) {
82
- uglies.push_back ((int ) val1);
83
- gen_numbers (val1, uglies, n, cap, dp);
30
+ uglies.insert ((int ) val1);
31
+ gen_numbers (val1, uglies, cap, dp);
84
32
}
85
33
if (val2 < cap) {
86
- uglies.push_back ((int ) val2);
87
- gen_numbers (val2, uglies, n, cap, dp);
34
+ uglies.insert ((int ) val2);
35
+ gen_numbers (val2, uglies, cap, dp);
88
36
}
89
37
if (val3 < cap) {
90
- uglies.push_back ((int ) val3);
91
- gen_numbers (val3, uglies, n, cap, dp);
38
+ uglies.insert ((int ) val3);
39
+ gen_numbers (val3, uglies, cap, dp);
92
40
}
93
41
}
94
42
43
+ // Set flag signaling uglies derived from t have been computed
95
44
dp[t] = 1 ;
96
45
}
97
46
@@ -100,38 +49,22 @@ int ugly_number_api(int n) {
100
49
// Results are integers, and so ugly numbers are <= INT_MAX
101
50
long cap = INT_MAX;
102
51
103
- // Reduce cap for moderate numbers of n. Maximum value of n = 1690
104
- if (1000 < n && n <= 1250 ) {
105
- cap = cap / 9 ;
106
- }
107
- if (n <= 1000 ) {
108
- cap = cap / 40 ;
109
- }
110
-
111
52
// Storage for ugly numbers
112
- vector <int > uglies ;
113
- uglies. push_back (1 );
53
+ set <int > uglies_set ;
54
+ uglies_set. insert (1 );
114
55
115
56
// Memo table
116
- map <long , long > dp;
57
+ unordered_map <long , long > dp;
117
58
118
59
// Generate ugly numbers
119
- gen_numbers (1 , uglies, n , cap, dp);
60
+ gen_numbers (1 , uglies_set , cap, dp);
120
61
121
- // Sort array of ugly numbers
122
- merge_sort_wrap (uglies);
62
+ // Get nth element in ugly number set
63
+ set<int >::iterator it = uglies_set.begin ();
64
+ advance (it, n - 1 );
65
+ int x = *it;
123
66
124
- // Remove duplicate ugly numbers
125
- vector<int > set_arr;
126
- int size_uglies = (int ) uglies.size ();
127
-
128
- for (int i = 0 ; i < size_uglies - 1 ; ++i) {
129
- if (uglies[i + 1 ] != uglies[i]) {
130
- set_arr.push_back (uglies[i]);
131
- }
132
- }
133
-
134
- return set_arr[n - 1 ];
67
+ return x;
135
68
}
136
69
137
70
int main (int argc, const char * argv[]) {
@@ -146,4 +79,4 @@ int main(int argc, const char * argv[]) {
146
79
cout << " nth ugly number: " << ugly_num << endl;
147
80
148
81
return 0 ;
149
- }
82
+ }
0 commit comments