You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Passing tests
Current implementation clones the parameter arr array to store NGEs, then later traverses that array left to right to construct a stringbuilder object which is finally converted to string
Getting ready to refactor to prepend to stringbuilder object as we go while determining NGEs (so don't have to traverse an array of NGEs to build the string afterwards)
Also to tell stringbuilder at creation time how big to be (since this is easily calculated) to avoid possible future perf hit
// Will refer to result of last comparison to determine if arr[i + 1] is determined to be a new local maximum
165
+
varlastResult=CompResult.NoNotLessThan;
166
+
// NoNotLessThan is correct for the "comparison" between arr[^1] and the non-element to its right, since arr[^1] will be a local max if arr[i] < arr[i + 1]
167
+
// Default is reserved to essentially mean uninitialized
143
168
144
-
if(leaders.Count==0)
145
-
thrownewArgumentException("Queue<int> leaders parameter is empty.");
169
+
varthisResult=CompResult.Default;
146
170
147
-
if(leaders.Count==1)
148
-
return$"leader is {leaders.Dequeue()}";
171
+
// walk array from right to left
172
+
// i starts at next-to-last index
173
+
// compare the elements in pairs
174
+
for(vari=arr.Length-2;i>=0;--i)
175
+
{
176
+
if(arr[i]<arr[i+1])
177
+
// Immediately adjacent element is NGE
178
+
{
179
+
thisResult=CompResult.YesLessThan;
180
+
arrNGE[i]=arr[i+1];
149
181
182
+
if(lastResult==CompResult.NoNotLessThan)
183
+
{
184
+
localMaxes.Push(arr[i+1]);
185
+
}
186
+
}
187
+
else// arr[i] >= arr[i + 1]
188
+
// Immediately adjacent element is not NGE
189
+
{
190
+
thisResult=CompResult.NoNotLessThan;
150
191
151
-
// Build from the right of the string to the left
152
-
varbuilder=newStringBuilder($" and {leaders.Dequeue()}");
192
+
// (Destructive) check of previous local maxes for NGE
193
+
boolfoundNGE=false;
194
+
while(!foundNGE&&localMaxes.Count>0)
195
+
{
196
+
if(arr[i]<localMaxes.Peek())
197
+
{
198
+
arrNGE[i]=localMaxes.Peek();
199
+
// Leave the NGE that we just used where we found it in localMaxes, it is still a candidate to be an NGE again in the future
200
+
foundNGE=true;
201
+
}
202
+
else
203
+
{
204
+
// WAS BUG: Must check of stack has elements before Pop
205
+
localMaxes.Pop();
206
+
}
207
+
}
153
208
154
-
// Insert at 0, or prepend, whatever the method is for that
155
-
builder.Insert(0,leaders.Dequeue());
209
+
if(localMaxes.Count==0)
210
+
// No candidate NGEs exist, or arr[i] was greater than each candidate NGE
211
+
{
212
+
arrNGE[i]=DEFAULT_NGE;
213
+
}
156
214
157
-
// When you Insert into a StringBuilder (probably onto the front of it,
158
-
// as a prepend), the index (probably zero) is the first param, while
159
-
// the string or thing-to-be-stringified is the second param
215
+
// Not pushing onto localMaxes here, since we won't know until next iteration whether the current arr[i] is a local max
216
+
}
160
217
218
+
// Advance state of tracking for next loop iteration
219
+
lastResult=thisResult;
220
+
thisResult=CompResult.Default;
221
+
}
161
222
162
-
while(leaders.Count>0)
163
-
{
164
-
builder.Insert(0,$"{leaders.Dequeue()}, ");
165
-
}
223
+
// Now construct the string left to right (or print it out as you go...but not since we're doing fixup at the end of the string building...and we're headed back to build the string as we go in the next version anyway)
// TODO: Tell the builder how big it needs to be to avoid later reallocation
228
+
// (Since we already know)
229
+
varbuilder=newStringBuilder("{ ");
171
230
172
231
173
-
// made for video
174
-
publicstaticvoidPrintLeaders(int[]arr)
175
-
{
176
-
if(arr==null)
177
-
thrownewArgumentNullException("The int[] arr parameter is null.");
232
+
// BUG: it's either k < arr.Length OR k <= arr.Length-1
233
+
for(vark=0;k<arr.Length;++k)
234
+
{
235
+
// It's Append, not Add, for StringBuilder, right?
236
+
builder.Append($"{{{arr[k]}, {arrNGE[k]}}}, ");
237
+
// BUG: array index var for this loop is k, not i
238
+
// But this loop is going away in the next version anyway
239
+
}
178
240
179
-
if(arr.Length==0)
180
-
thrownewArgumentException("The parameter int[] arr is empty.");
241
+
// Drop the last comma
242
+
// param1: remove starting from what index
243
+
// param2: how many to remove
244
+
// that is: builder.Remove(where, howmany);
245
+
builder.Remove(builder.Length-2,1);
246
+
247
+
// Add the final curly brace
248
+
builder.Append('}');
181
249
182
-
varlargestLeader=arr[arr.Length-1];
183
250
184
-
varleaders=newQueue<int>();
185
-
leaders.Enqueue(largestLeader);
186
-
187
-
// Walk through arr right to left,
188
-
// starting at the the element to the left of the default leader
189
-
for(vari=arr.Length-2;i>=0;--i)
190
-
{
191
-
// Compare to the largestLeader
192
-
if(arr[i]>largestLeader)
193
-
{
194
-
largestLeader=arr[i];
195
-
leaders.Enqueue(largestLeader);
196
-
}
197
-
}
251
+
returnbuilder.ToString();
252
+
253
+
254
+
// Go ahead and finish writing this, test that this solution works, then tomorrow adapt it to build the string right to left during initial traversal of the array (instead of cloning the array)
255
+
256
+
// That would actually make the StringBuilder approach kind of good, even if simply printing the result at the end
257
+
258
+
// Would reduce space complexity by O(n), since would not need the clone array
259
+
// Would reduce time complexity by O(n), since would not need to traverse the array again to build the string at the end...the string would be built as you go
0 commit comments