-
Notifications
You must be signed in to change notification settings - Fork 160
/
Delete k digits.cpp
152 lines (92 loc) · 2.41 KB
/
Delete k digits.cpp
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
Given a positive number and k, delete k digits of this number to get the smallest number.
For example:
Input: num = 42130, k =1
Output: 2139
*/
/*
solution1: change the int to string. Scan the string first k digits from left, get the minposition of the smallest digit.
Then, delete the first k digits and call the function again on the rest substring from minposition+1 to the end.
O(n*k) time, O(1) space
*/
/*
solution2: use deque, very similar to the sliding minimal Window problem.
O(n) time, O(k) space
*/
#include<iostream>
#include<cassert>
#include<string>
#include<queue>
using namespace std;
typedef pair<int, int> Pair;
string DeleteKDigits1Inner(string num, int start, int end, int k) {
if (end - start <= k || k <0) return "";
int minDigit = 10;
int minPosition = -1;
for (int i = start; i < start+k; ++i) {
int tmp = num[i] - '0';
if (tmp < minDigit) {
minDigit = tmp;
minPosition = i;
}
}
return num[minPosition] + DeleteKDigits1Inner(num, minPosition + 1, end, k - (minPosition-start) );
}
int DeleteKDigits1(int num, int k) {
assert(num > 0 && k >=0 );
char p[32];
itoa(num, p, 10);
string str = p;
string result = DeleteKDigits1Inner(str, 0, str.length(), k);
int finalnum = 0;
size_t iter = 0;
while (iter < result.length()) {
finalnum = 10 * finalnum + (result[iter]-'0');
iter++;
}
return finalnum;
}
string DeleteKDigits2Inner(string num, int k) {
deque<pair<int, char>> q;
if (num.length() <= k) return "";
for (int i = 0; i< k ; ++i) {
while (!q.empty() && q.back().second > (num[i] - '0')) {
q.pop_back();
}
q.push_back(Pair(i, num[i]));
}
string res = "";
for (int i = k; i < num.length(); ++i) {
res.push_back(q.front().second);
q.pop_front();
while (!q.empty() && q.back().second > (num[i] - '0')) {
q.pop_back();
}
while (!q.empty() && q.front().first < i - k) {
q.pop_front();
}
q.push_back(Pair(i, num[i]));
}
return res;
}
int DeleteKDigits2(int num, int k) {
assert(num > 0 && k >=0 );
char p[32];
itoa(num, p, 10);
string str = p;
string result = DeleteKDigits2Inner(str, k);
int finalnum = 0;
size_t iter = 0;
while (iter < result.length()) {
finalnum = 10 * finalnum + (result[iter]-'0');
iter++;
}
return finalnum;
}
int main() {
int num = 42139;
int k = 3;
cout<<DeleteKDigits1(num, k)<<endl;
cout<<DeleteKDigits2(num, k)<<endl;
return 0;
}