How to implement K stacks in an array, with best storage usage (stacks should be dynamic)?
如何在阵列中实现K堆栈,具有最佳存储使用率(堆栈应该是动态的)?
3 个解决方案
#1
0
Well, if you're only worried about space usage, and don't care that stack operations can take O(N)
, you can use the array's first few cells to manage the stacks:
好吧,如果你只是担心空间使用,并且不关心堆栈操作可以采用O(N),你可以使用数组的前几个单元来管理堆栈:
Array[0]
- the end of stack 0
数组[0] - 堆栈0的结尾
Array[1]
- the end of stack 1
数组[1] - 堆栈1的结尾
...
...
Array[K-1]
= the end of stack K
数组[K-1] =堆栈K的结束
Stack n
starts at Array[n-1]
and ends at Array[n]
(exclusive - [Array[n-1], Array[n]) )
. If Array[n-1]==Array[n]
the stack is empty. The first stack starts at K, so at first Array[0]..Array[K-1] = K
堆栈n从Array [n-1]开始,到Array [n]结束(exclusive - [Array [n-1],Array [n]))。如果Array [n-1] == Array [n],则堆栈为空。第一个堆栈从K开始,因此首先是Array [0] .. Array [K-1] = K.
When you push into a stack, just move all the elements in the stacks below it, and adjust the pointers respectively.
当你进入堆栈时,只需移动它下面的堆栈中的所有元素,并分别调整指针。
It'll get you the memory constraint you need.
它会让你获得所需的内存约束。
#2
0
Answer 1: store the K stack pointers at the start. now mark the first address after that as address 0 (makes life simpler) an even K stack (stack_0, stack_2, ...) should grow upward; an odd K stack (stack_1, ..) should grow downward when initializing segment the array into K/2 parts (assuming K is even for simplicity). stack0 starts at address 0 stack1 starts at (arraySize / (k/2)) and grows downward stack3 starts at (arraySize / (k/2)) and grows upward
答案1:在开始时存储K堆栈指针。现在标记之后的第一个地址为地址0(使生活更简单)一个偶数K堆栈(stack_0,stack_2,...)应该向上增长;当将阵列初始化为K / 2个部分时,奇数K堆栈(stack_1,..)应该向下增长(假设为简单起见,K为偶数)。 stack0从地址0开始stack1从(arraySize /(k / 2))开始向下增长stack3从(arraySize /(k / 2))开始并向上增长
when pushing data into a certain stack we should make sure that it is not overflowing to the adjacent stack, otherwise throw an exception.
当将数据推入某个堆栈时,我们应该确保它没有溢出到相邻堆栈,否则抛出异常。
the array should look like this: [[stack pointers][stack_0][stack_1]...[stack_k]] where stack[0] and stack[1] both share the same region so they can make an optimal use of the space available to them.
数组应如下所示:[[stack pointers] [stack_0] [stack_1] ... [stack_k]]其中stack [0]和stack [1]共享相同的区域,以便它们可以最佳地利用空间可供他们使用。
there could be further optimizations done by pairing each large stack with a small stack (this could be done by checking the behavior of the stacks over time). Also, grouping together rapidly changing arrays with slow changing arrays may help.
通过将每个大堆栈与一个小堆栈配对可以进行进一步的优化(这可以通过检查堆栈随时间的行为来完成)。此外,将快速变化的阵列与缓慢变化的阵列组合在一起可能有所帮助
Answer 2: thinking some more on this, I saw that my 1st solution only guarantees using array_size/(k/2) (since if we only have one array of size array_size/(k/2), we will get a stack overflow). the following (completely impractical) solution can satisfy the requirements: we allocate the start of the array for our k stack pointers, and ignore this region from now on. In the rest of the array we look at each cell as a struct [data, previous, next].
答案2:在这方面考虑更多,我看到我的第一个解决方案只保证使用array_size /(k / 2)(因为如果我们只有一个大小为array_size /(k / 2)的数组,我们将得到堆栈溢出) 。以下(完全不切实际)的解决方案可以满足要求:我们为k堆栈指针分配数组的开始,并从现在开始忽略该区域。在数组的其余部分,我们将每个单元格视为struct [data,previous,next]。
push(stack_i, data) -> get sp_i from the stack pointers area. then go to that address, fill in the "next" pointer to point to the next empty cell in the array (we could have all the empty spaces linked together in another stack so this is o(1)). in the "next" cell store our data, and fill in the "prev" pointer. update sp_i
push(stack_i,data) - >从堆栈指针区域获取sp_i。然后转到该地址,填入“next”指针指向数组中的下一个空单元格(我们可以将所有空白空间链接在另一个堆栈中,这样就是o(1))。在“下一个”单元格中存储我们的数据,并填写“prev”指针。更新sp_i
pop(stack_i) -> get sp_i. get the "data" from that cell. "prev" from that cell is our new sp_i. push the old (now empty) cell to the empty list.
pop(stack_i) - >获取sp_i。从该单元格中获取“数据”。来自该单元格的“prev”是我们的新sp_i。将旧(现在为空)单元格推送到空列表。
#3
0
Oooh, ooh, if K is dynamic, too, you just make the K element array dynamic. Making it larger simply means push down all the stacks. So if you don't mind O(N) push and pop operations, K shouldn't be a constant.
噢,哦,如果K也是动态的,你只需要使K元素数组动态化。使其变大只是意味着压下所有堆栈。因此,如果您不介意O(N)推送和弹出操作,K不应该是常数。
I wonder if I got the job.
我想知道我是否得到了这份工作。
#1
0
Well, if you're only worried about space usage, and don't care that stack operations can take O(N)
, you can use the array's first few cells to manage the stacks:
好吧,如果你只是担心空间使用,并且不关心堆栈操作可以采用O(N),你可以使用数组的前几个单元来管理堆栈:
Array[0]
- the end of stack 0
数组[0] - 堆栈0的结尾
Array[1]
- the end of stack 1
数组[1] - 堆栈1的结尾
...
...
Array[K-1]
= the end of stack K
数组[K-1] =堆栈K的结束
Stack n
starts at Array[n-1]
and ends at Array[n]
(exclusive - [Array[n-1], Array[n]) )
. If Array[n-1]==Array[n]
the stack is empty. The first stack starts at K, so at first Array[0]..Array[K-1] = K
堆栈n从Array [n-1]开始,到Array [n]结束(exclusive - [Array [n-1],Array [n]))。如果Array [n-1] == Array [n],则堆栈为空。第一个堆栈从K开始,因此首先是Array [0] .. Array [K-1] = K.
When you push into a stack, just move all the elements in the stacks below it, and adjust the pointers respectively.
当你进入堆栈时,只需移动它下面的堆栈中的所有元素,并分别调整指针。
It'll get you the memory constraint you need.
它会让你获得所需的内存约束。
#2
0
Answer 1: store the K stack pointers at the start. now mark the first address after that as address 0 (makes life simpler) an even K stack (stack_0, stack_2, ...) should grow upward; an odd K stack (stack_1, ..) should grow downward when initializing segment the array into K/2 parts (assuming K is even for simplicity). stack0 starts at address 0 stack1 starts at (arraySize / (k/2)) and grows downward stack3 starts at (arraySize / (k/2)) and grows upward
答案1:在开始时存储K堆栈指针。现在标记之后的第一个地址为地址0(使生活更简单)一个偶数K堆栈(stack_0,stack_2,...)应该向上增长;当将阵列初始化为K / 2个部分时,奇数K堆栈(stack_1,..)应该向下增长(假设为简单起见,K为偶数)。 stack0从地址0开始stack1从(arraySize /(k / 2))开始向下增长stack3从(arraySize /(k / 2))开始并向上增长
when pushing data into a certain stack we should make sure that it is not overflowing to the adjacent stack, otherwise throw an exception.
当将数据推入某个堆栈时,我们应该确保它没有溢出到相邻堆栈,否则抛出异常。
the array should look like this: [[stack pointers][stack_0][stack_1]...[stack_k]] where stack[0] and stack[1] both share the same region so they can make an optimal use of the space available to them.
数组应如下所示:[[stack pointers] [stack_0] [stack_1] ... [stack_k]]其中stack [0]和stack [1]共享相同的区域,以便它们可以最佳地利用空间可供他们使用。
there could be further optimizations done by pairing each large stack with a small stack (this could be done by checking the behavior of the stacks over time). Also, grouping together rapidly changing arrays with slow changing arrays may help.
通过将每个大堆栈与一个小堆栈配对可以进行进一步的优化(这可以通过检查堆栈随时间的行为来完成)。此外,将快速变化的阵列与缓慢变化的阵列组合在一起可能有所帮助
Answer 2: thinking some more on this, I saw that my 1st solution only guarantees using array_size/(k/2) (since if we only have one array of size array_size/(k/2), we will get a stack overflow). the following (completely impractical) solution can satisfy the requirements: we allocate the start of the array for our k stack pointers, and ignore this region from now on. In the rest of the array we look at each cell as a struct [data, previous, next].
答案2:在这方面考虑更多,我看到我的第一个解决方案只保证使用array_size /(k / 2)(因为如果我们只有一个大小为array_size /(k / 2)的数组,我们将得到堆栈溢出) 。以下(完全不切实际)的解决方案可以满足要求:我们为k堆栈指针分配数组的开始,并从现在开始忽略该区域。在数组的其余部分,我们将每个单元格视为struct [data,previous,next]。
push(stack_i, data) -> get sp_i from the stack pointers area. then go to that address, fill in the "next" pointer to point to the next empty cell in the array (we could have all the empty spaces linked together in another stack so this is o(1)). in the "next" cell store our data, and fill in the "prev" pointer. update sp_i
push(stack_i,data) - >从堆栈指针区域获取sp_i。然后转到该地址,填入“next”指针指向数组中的下一个空单元格(我们可以将所有空白空间链接在另一个堆栈中,这样就是o(1))。在“下一个”单元格中存储我们的数据,并填写“prev”指针。更新sp_i
pop(stack_i) -> get sp_i. get the "data" from that cell. "prev" from that cell is our new sp_i. push the old (now empty) cell to the empty list.
pop(stack_i) - >获取sp_i。从该单元格中获取“数据”。来自该单元格的“prev”是我们的新sp_i。将旧(现在为空)单元格推送到空列表。
#3
0
Oooh, ooh, if K is dynamic, too, you just make the K element array dynamic. Making it larger simply means push down all the stacks. So if you don't mind O(N) push and pop operations, K shouldn't be a constant.
噢,哦,如果K也是动态的,你只需要使K元素数组动态化。使其变大只是意味着压下所有堆栈。因此,如果您不介意O(N)推送和弹出操作,K不应该是常数。
I wonder if I got the job.
我想知道我是否得到了这份工作。