- Practice
- Data Structures
- Stacks
- Largest Rectangle
- Discussions

# Largest Rectangle

# Largest Rectangle

JimB6800 + 8 comments To Moderator: Most of the other problems in the data structures area are regarding fundamental use of the data structure. I believe that this problem would be more appropriately located in the Algorithms section as it assumes development of an algorithm based on a stack. From the problem description, and from a number of the discussion comments, it's not clear to many how a stack would be used to solve this problem.

I suggest either 1) move to algorithms section, or 2) describe the algorithm in enough detail such that this becomes a stack development/usage problem.

- SW
SidWagz + 1 comment I agree because my solution was a simple divinde and conquer with recursion and I could not think In anyway I would use stacks.

brynn_mahsman + 4 comments If you're doing recursion you're using a stack, specifically the call stack.

mkhan31995 + 1 comment Will you please explain ? Thank You

- MF
mfilandro + 1 comment I belive what Brynn is saying is that the process of recursion creates a stack whether or not you are using a stack data structure to store data.

Basically, each time you recurse, you're putting the current call of the function on hold and making a new call to the function. Then, once you hit the base case, you start going down the list of functions in a Last In, First Out manner, because the VM has created a stack of your function calls to process later while you were recursing.

mkhan31995 + 0 comments Thanks. It's clear to me now.

3r4b6wgzr0650 + 0 comments According to this logic all problems should be listed under "Stack" section, because stack is implicitly used every time you call a function.

- RM
mahawarrahul51 + 0 comments well said!!!

mahipalsaran + 0 comments then all recursion problem should be in stack section,am i right?

- UU
ubbnz + 1 comment I used stack to keep track of heights which are cumulatively increasing. You can have look on my github https://github.com/ubbn/HackerRank/blob/master/datastructure/stacks/largestrectangle/Solution.java

- TA
tranc2606 + 3 comments Heights are not cumulatively increasing, that would make the problem so much easier, and yes, a stack could be used in that case. I took a look at test#2 and this is the input:

10 6320 6020 6098 1332 7263 672 9472 28338 3401 9494

output:18060 (from adding the first three numbers)

I also looked at another test, and the rectangle can be in the middle, it doesn't neccessarily have to be on the extremes.

- MI
ZenoMachine + 0 comments Why is it not 28338? 28338 > 18060

- T
thebick + 1 comment The correct answer is 28838. If you have 18060, your algorithm is buggy. (I just passed the challenge, then put your example in and got 28838)

On the other hand, your example helped me find the last bug that was stopping me.

- MS
msahu6174 + 0 comments Do you mean 28338 as answer. Simple stare at the sequence reveals that answer should be 28338. The larest one.

- AH
abinashhota95 + 0 comments 2838 not 28338

- TA
tranc2606 + 2 comments I totally agree. The only solution I have been able to see so far using a stack is very hairy. A hint would be appreciated.

- GS
harsimransingh31 + 0 comments # include

using namespace std;

class hell { int n,*a; long long int ar=0; public: void get() { cin>>n; a=new int(n); for(int i=0;i>a[i]; } for(int i=0;iar) ar=temp; } } cout<

int main() { hell q; q.get(); return 0; }

bennattj + 4 comments Look at the picture below which pretty much shows the cases you need to consider.

Basically, we're going to start with

**building 1**, then compute all of the areas of each rectangle and choose the maximum from that. Notice that when we start with**building 1**, we have no idea when the end of it's rectangle will be (represented by a dashed arrow going to the right). The next thing you should notice is that if the next building goes up (higher than the previous), all active areas will remain active (i.e. we still haven't found the end of the area).When

**building 5**is added, it definitely ends the previous building's area (or whatever area it was part of) and, in this case, that's it. Also notice that we need to extend**building 5***back*through**building 4**. How do you know to stop at**building 4**? Easy, the next active area (coming from**building 3**) has a height*lower*than**building 5**'s, so that area is still active (in other words it will go through**building 5**).Hopefully you're starting to see how a stack can be used here: when the next building is taller than the previous, add it to the stack (to be processsed later). When the next building is shorter: pop off stack until you find a starting area with a smaller height (than the current building) or you empty the stack (meaning it goes all the way back through the first building). Now push this building's height along with it's left position onto the stack.

When you pop off the stack, this means you've found the right side of an area, so compute its area and see if it's the maximum.

*Also*when you find the "left wall" for the current building (meaning you found a smaller building in the stack or went all the way back to the first building), you need to remember that position*in addition to*the height of the current building so that when the current building is eventually popped off of the stack, you can properly compute it's area. Notice how**building 6**extends both backwards and forwards, such that when I get to**building 8**, I have to know that**building 6**'s height extended all the way back through**building 2**.m_kaleia + 0 comments Thanks a lot for clarifying the problem, your example should be considered the main test case instead of the original one

Cheers

- AD
codeeater + 0 comments thanks

devinludwig + 0 comments Here's a ruby implementation:

def largestRectangle(h) max, stack = 0, [[h[0],0]] for i in 1...h.size if h[i]>h[i-1] stack.push [h[i],i] else l2=nil while stack.any? and stack[-1][0]>h[i] l = stack.pop l2 = l[1] max = [max, l[0]*(i-l[1])].max end stack.push [h[i], l2 ? l2 : i] end end stack.each{|b| max = [max, b[0]*(h.size-b[1])].max} max end

- VV
vipulvikram3499 + 0 comments Nice explanation.

- SC
shubhamchandra + 0 comments [deleted] choito + 5 comments I also agree. It seems this problem is more like an algorithm problem instead of the data structure problem using the stack. I used the dynamic programming to find the maximum possible largest rectangle. For each height, I found the width to the right and left where each rectangle can extend at most. And then, I simply multiplied each height and width and updated the largest rectangle from the first to the last rectangle.

- PS
pratyaksh_nidhi + 0 comments How did you divide the problem into 2 or more smaller problems

jain_lalit90 + 1 comment works like a charm! just one question... why is there a need for DP?

shashank9226 + 0 comments The DP approach smiplifies the code to a large extent, if you get the approach. For eg. here the approach is: 1. Get the rectangle for a building (sub-problem) 2. Do it for all the the buildings (recursion or looping) 3. Return the maximum of the lot.

- S
ShubhamV06 + 2 comments I dont get it. This makes the algorithm of O(n^2) right? Correct me if i am wrong. I also did using the same method and can u explain why the stack method would be better than this?

- MK
CliffyMk + 0 comments n log n probably

- VV
vipulvikram3499 + 0 comments By using stack u can solve it in O(n) time. Here there is concept similar to find the smallest window in a string to find a pattern containg fixed count of some characters. here max iteration time is O(2*n)=O(n).

- NS
nishanthsanjeevi + 1 comment i dont find any requirement to use a stack moreover using a stack is a complication to this problem

shashank9226 + 0 comments You are correct. DP with Recursion. Simple.

- SY
19998sachinyadav + 0 comments This i O(n^2) aproach. How can we improve this

- MK
_miran_ + 0 comments Actually, if you use stack instead of divide and conquer approach, you get solution with better time complexity - O(n).

blairnangle + 0 comments Completely agree. The

*optimal*solution requires using stacks (in the data structure sense) but it is by no means clear from the description of the problem that stacks should be used in the solution.- SI
NaruSh + 0 comments Totally agreed. This section should contain problems dealing with Stack manipulation. The Linkedlist section is very well maintained, all the problems revolve around Linkedlist manipulations.

de4thst4lk3r + 1 comment That sample test case isn't so great to help you understand the problem.

- AT
AbhishekThecoder + 1 comment Yes, Exactly!! The sample test case is not sufficient enough to understand the problem. I actually understood the problem while reading the discussion.

- RL
tgunix + 6 comments italwaysdepends + 1 comment This video was really helpful. Thanks!

- JK
juli6 + 0 comments Thanx for the video

- MG
Mani4723 + 0 comments thanks

tagaew + 2 comments Thank you for the video! This is the key to the solution. However, it is still not clear to me the formula that is using in the calculation. The guy is explaining the formula, however I can't catch it.

mkhan31995 + 3 comments I faced the same problem my friend. I couldn't get the formula. SO i did a research on it and found a better video which explained me the core of this question. Have a look at it : https://www.youtube.com/watch?v=VNbkzsnllsU

Hope that helped you friend.

- JT
Jlookup + 0 comments good video, thanks!

- BP
bert5porter + 0 comments Yes, this is a MUCH better video. He explains the algorithm, why it works.

pareksha + 0 comments Hey, thanks !

phillm6 + 0 comments [deleted]

phillm6 + 0 comments *edited I think I found a problem with Tushar Roy's algorithm.

I think this is a telling case: If you have this list (no delimiter) 24534513

list: 24534513 stack:012 i = 3 (push till a decreasing value found)

list: 24534513 stack:012 i=3 (i-p)*list[p] -> (3-2)5 -> (3-1)4 So we update max to 5 then 8, but 2<3 (list[0]

list: 24534513 stack:0 345 i=6 (push until decreasing again)

list: 24534513 stack:0 345 i=6 -> (1)5 -> (2)4 -> (3)3 -> (6)2

So max is 12... but wait, 3 forms the min height of a rectangle starting at 1 and ending at 5 for a total size of 15!

My suggestion is that you check if your previous index (j) skips (has a greater than one difference with the current) and if list[j] is less than our current value (if not, the regular algorithm will take care of it).

- SS
sakets594 + 0 comments [deleted] - SS
sakets594 + 0 comments [deleted]

akrox58 + 2 comments http://www.informatik.uni-ulm.de/acm/Locals/2003/html/histogram.html

Check this for full description of problem! :)

- PS
prashanth_sunder + 0 comments Thanks a lot!

- J
jacob_sthilaire + 0 comments [deleted]

thienlongtpct + 0 comments Test 1 has wrong answer. It shoud be 18.

himanhsu54 + 2 comments Test case 1 1 3 5 9 11 Expected output 81 is this right or i am missing something?

kumarprajwal26 + 0 comments I am getting 18 as answer

- AP
aviral_petwal + 1 comment I am getting 18 as a answer. Idon't think 81 is correct.

himanhsu54 + 1 comment but sample test case 2 gives output 81. should i report it. can someone confirm?

- AP
aviral_petwal + 1 comment Yep output should be 18. But it is giving 81 as expected output.

himanhsu54 + 0 comments I reported this in Suggest Edit. Thanks.

rajkumar9606 + 1 comment i did'nt use stack.but any how all testcases passed.

#include <cmath> #include <cstdio> #include <vector> #include <iostream> #include <algorithm> using namespace std; int main() { /* Enter your code here. Read input from STDIN. Print output to STDOUT */ long long n,arr[100001],i,j,max,temp=-1,k,count=1,val; cin>>n; for(i=0;i<n;i++){ cin>>arr[i]; } for(i=0;i<n;i++){ val=arr[i]; int cl1=1,cl=1; for(j=i-1,k=i+1;j>=0 || k<n;j--,k++){ if(j>=0 && arr[j]>=val && cl1==1){ count++; }else cl1=0; if(k<n && arr[k]>=val && cl==1){ count++; }else cl=0; if(cl==0 && cl1==0) break; } max=val*count; if(max>temp){ temp=max; } count=1; } cout<<temp; return 0; }

CrapBag0301 + 0 comments [deleted]

- LK
landonkoo0207 + 2 comments You don't really need any stack to tackle this problem. Just one array holding the heights would be enought. Then you can work out the maximum rectangle as you go through the building heights. My python3 solution with the comments is below:

n = int(input()) h = [int(x) for x in input().split(" ")] # For each element(height) of an array, # 1. Search the continuous buildings to the left # - if continous building is at the same height or taller, increment the count # 2. Seach the continuous buildings to the right # - if continous building is at the same height or taller, increment the count # 3. Calculate the current rectangle area: # - height of the current building * current count # 4. Check if the current area is larger than the current maximum area # When the search finishes print the maximum area acquired. max_area = 0 for i in range(len(h)): cnt = 0 for j in range(i, -1, -1): if h[j] >= h[i]: cnt += 1 else: break for k in range(i+1, len(h)): if h[k] >= h[i]: cnt += 1 else: break area = h[i] * cnt if area > max_area: max_area = area print (max_area)

- SD
SuyogD + 0 comments Superb explanation !! I was working in similar way . Good to see I was working in correct direction. @landonkoo0207

- FF
ufabianx + 0 comments While elegant, the worst case complexity is still O(N^2).

e.g.

n = 1e5-1 h[i] = 1, i = range(n)

will make your program timeout.

And in the case you would check for that special case, I would use:

h[0] = h[n-1] = rand()

mgkanani + 3 comments try for this input:- 2 3 2 5 1 4 4 1 4 4

Output should be 10. If we use stack based solution, it will give 8.

- LJ
udhy15 + 0 comments [deleted] - LJ
udhy15 + 1 comment Implement the code properly , the solution to the problem is not solemnly based in stack.

mgkanani + 2 comments Refer to this http://www.geeksforgeeks.org/largest-rectangle-under-histogram/. It will work in all the testcases. When the stack is empty, it is considering length as i(current_index) and finding the area.

sattujaiswal + 1 comment `no it will give 10 .. try this import java.util.*; // @author satyendra public class areaHistogram { static int area(int[] a) { int i,area=0; int maxArea=0; Stack<Integer> st=new Stack<>(); for(i=0;i<a.length;) { if(st.isEmpty()||a[st.peek()]<=a[i]) { st.push(i++); } else { int x=st.pop(); if(st.isEmpty()) { area=a[x]*i; } else { area=a[x]*(i-st.peek()-1); } if(area>maxArea) maxArea=area; } } while(!st.isEmpty()) { int x=st.pop(); if(st.isEmpty()) { area=a[x]*i; } else { area=a[x]*(i-st.peek()-1); } if(area>maxArea) maxArea=area; } return maxArea; } public static void main(String[] args) { Scanner sc=new Scanner(System.in); int n; n=sc.nextInt(); int[] a=new int[n]; for(int i=0;i<n;i++) a[i]=sc.nextInt(); System.out.println("max area="+area(a)); }`

}

- E
elephantscabin + 0 comments will this work if i initially sort the heights of the building in ascending order and then find the third largest height and multiply it by 3 ?

plaanupam + 5 comments My solution complexity is o(n^2). It passes 7 test cases. For further tst cases, it shows timeout. What is the optimal complexity for this solution?

- LK
Lucky_son123 + 0 comments Same problem

dgrant + 0 comments My complexity is O(n^2) but passes all tests just fine in under 1 second each (using python 3).

chandanm2 + 0 comments O(n) is the optimal complexity of the solution and my solution passes all the test cases :)

- ZY
angeloyz + 0 comments If you are using dynamic programming, you have excceeds the memory limits.

Sort 206 Discussions, By:

Please Login in order to post a comment