Tìm hình chữ nhật lớn nhất chỉ chứa các số không trong ma trận nhị phân N × N


75

Cho một ma trận nhị phân NxN (chỉ chứa 0 hoặc 1), làm thế nào chúng ta có thể tìm hình chữ nhật lớn nhất chứa tất cả các 0?

Thí dụ:

      I
    0 0 0 0 1 0
    0 0 1 0 0 1
II->0 0 0 0 0 0
    1 0 0 0 0 0
    0 0 0 0 0 1 <--IV
    0 0 1 0 0 0
            IV 

Đối với ví dụ trên, nó là một ma trận nhị phân 6 × 6. giá trị trả về trong trường hợp này sẽ là Ô 1: (2, 1) và Ô 2: (4, 4). Ma trận con thu được có thể là hình vuông hoặc hình chữ nhật. Giá trị trả về cũng có thể là kích thước của ma trận con lớn nhất trong tất cả các số 0, trong ví dụ này là 3 × 4.


1
Vui lòng xem xét việc thay đổi câu trả lời được chấp nhận thành câu trả lời của JF Sebastian, câu trả lời hiện đúng và có độ phức tạp tối ưu.
j_random_hacker

1
Vui lòng kiểm tra các câu hỏi rất giống nhau (tôi muốn nói là trùng lặp): stackoverflow.com/questions/7770945/… , stackoverflow.com/a/7353193/684229 . Giải pháp là O(n).
TMS

Tôi đang cố gắng làm điều tương tự với một hình chữ nhật được định hướng theo bất kỳ hướng nào. xem câu hỏi: stackoverflow.com/questions/22604043/…
Chris Maes,

@TMS Thực ra thì ngược lại. Những câu hỏi này là bản sao của câu hỏi này.
tommy.carstensen

Câu trả lời:


45

Đây là giải pháp dựa trên vấn đề "Hình chữ nhật lớn nhất trong biểu đồ" do @j_random_hacker đề xuất trong phần nhận xét:

[Thuật toán] hoạt động bằng cách lặp lại qua các hàng từ trên xuống dưới, đối với mỗi hàng giải quyết vấn đề này , trong đó các "thanh" trong "biểu đồ" bao gồm tất cả các dấu không bị gián đoạn bắt đầu từ hàng hiện tại (cột có chiều cao 0 nếu nó có số 1 ở hàng hiện tại).

Ma trận đầu vào matcó thể là một tệp có thể lặp lại tùy ý, ví dụ, một tệp hoặc một luồng mạng. Mỗi lần chỉ cần một hàng.

#!/usr/bin/env python
from collections import namedtuple
from operator import mul

Info = namedtuple('Info', 'start height')

def max_size(mat, value=0):
    """Find height, width of the largest rectangle containing all `value`'s."""
    it = iter(mat)
    hist = [(el==value) for el in next(it, [])]
    max_size = max_rectangle_size(hist)
    for row in it:
        hist = [(1+h) if el == value else 0 for h, el in zip(hist, row)]
        max_size = max(max_size, max_rectangle_size(hist), key=area)
    return max_size

def max_rectangle_size(histogram):
    """Find height, width of the largest rectangle that fits entirely under
    the histogram.
    """
    stack = []
    top = lambda: stack[-1]
    max_size = (0, 0) # height, width of the largest rectangle
    pos = 0 # current position in the histogram
    for pos, height in enumerate(histogram):
        start = pos # position where rectangle starts
        while True:
            if not stack or height > top().height:
                stack.append(Info(start, height)) # push
            elif stack and height < top().height:
                max_size = max(max_size, (top().height, (pos - top().start)),
                               key=area)
                start, _ = stack.pop()
                continue
            break # height == top().height goes here

    pos += 1
    for start, height in stack:
        max_size = max(max_size, (height, (pos - start)), key=area)    
    return max_size

def area(size):
    return reduce(mul, size)

Giải pháp là O(N), đâu Nlà số phần tử trong ma trận. Nó yêu cầu O(ncols)bộ nhớ bổ sung, trong đó ncolslà số cột trong ma trận.

Phiên bản mới nhất có thử nghiệm tại https://gist.github.com/776423


2
Tốt thử, nhưng điều này không thành công max_size([[0,0,0,0,1,1,1], [0,0,0,0,0,0,0], [0,0,0,1,1,1,1], [0,0,1,1,1,1,1]] + [[1,0,1,1,1,1,1]] * 3), trả về (2, 4) khi có một hình vuông 3x3 ở trên cùng bên trái.
j_random_hacker

3
Vấn đề cơ bản là không phải lúc nào cũng đủ để theo dõi (một số) hình chữ nhật có diện tích lớn nhất của các điểm lân cận như bạn đang làm ở đây. Thuật toán O (N) duy nhất mà tôi biết là đúng hoạt động bằng cách lặp qua các hàng từ trên xuống dưới, đối với mỗi hàng giải quyết vấn đề này: stackoverflow.com/questions/4311694/… , trong đó "thanh" trong "biểu đồ" bao gồm tất cả các dấu không bị gián đoạn hướng lên bắt đầu ở hàng hiện tại (cột có chiều cao 0 nếu cột đó có 1 trong hàng hiện tại).
j_random_hacker

6
@j_random_hacker: Tôi đã cập nhật câu trả lời của mình để sử dụng thuật toán dựa trên "biểu đồ".
jfs

4
Điều này trông tuyệt vời, tuy nhiên, tôi đang cố gắng thực sự TÌM hình chữ nhật lớn nhất (như trong, trả về tọa độ). Thuật toán này sẽ trả về diện tích một cách đáng tin cậy, nhưng khi tôi biết điều đó, làm thế nào một người có thể phát hiện ra vị trí của hình chữ nhật 3 cột x 2 hàng, với góc trên bên trái của nó tại [3, 5] (ví dụ)?
JBWhitmore

1
người ta lấy thông tin cột bị trả lại ở đâu? (cột bên trái hay bên phải của hình chữ nhật?). Chúng tôi có thể lấy chiều rộng và chiều cao từ max_rectangle_sizevà hàng dưới cùng từ for row in it:lần lặp, nhưng tôi không thể tìm thấy thông tin cột giới hạn.
manatttta

30

Vui lòng xem xét Tối đa hóa diện tích hình chữ nhật trong Biểu đồ và sau đó tiếp tục đọc giải pháp bên dưới.

Traverse the matrix once and store the following;

For x=1 to N and y=1 to N    
F[x][y] = 1 + F[x][y-1] if A[x][y] is 0 , else 0

Then for each row for x=N to 1 
We have F[x] -> array with heights of the histograms with base at x.
Use O(N) algorithm to find the largest area of rectangle in this histogram = H[x]

From all areas computed, report the largest.

Độ phức tạp thời gian là O (N * N) = O (N²) (đối với ma trận nhị phân NxN)

Thí dụ:

Initial array    F[x][y] array
 0 0 0 0 1 0     1 1 1 1 0 1
 0 0 1 0 0 1     2 2 0 2 1 0
 0 0 0 0 0 0     3 3 1 3 2 1
 1 0 0 0 0 0     0 4 2 4 3 2
 0 0 0 0 0 1     1 5 3 5 4 0
 0 0 1 0 0 0     2 6 0 6 5 1

 For x = N to 1
 H[6] = 2 6 0 6 5 1 -> 10 (5*2)
 H[5] = 1 5 3 5 4 0 -> 12 (3*4)
 H[4] = 0 4 2 4 3 2 -> 10 (2*5)
 H[3] = 3 3 1 3 2 1 -> 6 (3*2)
 H[2] = 2 2 0 2 1 0 -> 4 (2*2)
 H[1] = 1 1 1 1 0 1 -> 4 (1*4)

 The largest area is thus H[5] = 12

lời giải thích tốt đẹp với ví dụ
Peter

1
bạn có chắc đây là O (N * N)? Có hai lần vượt qua toàn bộ ma trận, nhưng ấn tượng của tôi là đây là O (N).
Chris Maes

lời giải thích rất hay .. :) Tôi ước gì, bạn cũng sẽ giải thích "Tối đa hóa diện tích hình chữ nhật dưới Biểu đồ" ..: D
tumbudu

1
Để làm cho nó rõ ràng hơn. Giải pháp là O (N * N), trong đó N là số mục trong một hàng / cột vì câu hỏi cho biết đầu vào có kích thước NxN. Nếu N là tổng số các mặt hàng trong đầu vào, sau đó nó là O (N)
user2469515

12

Đây là một giải pháp Python3, trả về vị trí ngoài diện tích của hình chữ nhật lớn nhất:

#!/usr/bin/env python3

import numpy

s = '''0 0 0 0 1 0
0 0 1 0 0 1
0 0 0 0 0 0
1 0 0 0 0 0
0 0 0 0 0 1
0 0 1 0 0 0'''

nrows = 6
ncols = 6
skip = 1
area_max = (0, [])

a = numpy.fromstring(s, dtype=int, sep=' ').reshape(nrows, ncols)
w = numpy.zeros(dtype=int, shape=a.shape)
h = numpy.zeros(dtype=int, shape=a.shape)
for r in range(nrows):
    for c in range(ncols):
        if a[r][c] == skip:
            continue
        if r == 0:
            h[r][c] = 1
        else:
            h[r][c] = h[r-1][c]+1
        if c == 0:
            w[r][c] = 1
        else:
            w[r][c] = w[r][c-1]+1
        minw = w[r][c]
        for dh in range(h[r][c]):
            minw = min(minw, w[r-dh][c])
            area = (dh+1)*minw
            if area > area_max[0]:
                area_max = (area, [(r-dh, c-minw+1, r, c)])

print('area', area_max[0])
for t in area_max[1]:
    print('Cell 1:({}, {}) and Cell 2:({}, {})'.format(*t))

Đầu ra:

area 12
Cell 1:(2, 1) and Cell 2:(4, 4)

Hoạt động tuyệt vời! Tôi đã tạo một phiên bản Fortran từ cái này và biên dịch nó để sử dụng trong Python, vì việc duyệt một mảng lớn bằng Python như thế này rất chậm.
Jason

4

Đây là phương thức JF Sebastians được dịch sang C #:

private Vector2 MaxRectSize(int[] histogram) {
        Vector2 maxSize = Vector2.zero;
        int maxArea = 0;
        Stack<Vector2> stack = new Stack<Vector2>();

        int x = 0;
        for (x = 0; x < histogram.Length; x++) {
            int start = x;
            int height = histogram[x];
            while (true) {
                if (stack.Count == 0 || height > stack.Peek().y) {
                    stack.Push(new Vector2(start, height));

                } else if(height < stack.Peek().y) {
                    int tempArea = (int)(stack.Peek().y * (x - stack.Peek().x));
                    if(tempArea > maxArea) {
                        maxSize = new Vector2(stack.Peek().y, (x - stack.Peek().x));
                        maxArea = tempArea;
                    }

                    Vector2 popped = stack.Pop();
                    start = (int)popped.x;
                    continue;
                }

                break;
            }
        }

        foreach (Vector2 data in stack) {
            int tempArea = (int)(data.y * (x - data.x));
            if(tempArea > maxArea) {
                maxSize = new Vector2(data.y, (x - data.x));
                maxArea = tempArea;
            }
        }

        return maxSize;
    }

    public Vector2 GetMaximumFreeSpace() {
        // STEP 1:
        // build a seed histogram using the first row of grid points
        // example: [true, true, false, true] = [1,1,0,1]
        int[] hist = new int[gridSizeY];
        for (int y = 0; y < gridSizeY; y++) {
            if(!invalidPoints[0, y]) {
                hist[y] = 1;
            }
        }

        // STEP 2:
        // get a starting max area from the seed histogram we created above.
        // using the example from above, this value would be [1, 1], as the only valid area is a single point.
        // another example for [0,0,0,1,0,0] would be [1, 3], because the largest area of contiguous free space is 3.
        // Note that at this step, the heigh fo the found rectangle will always be 1 because we are operating on
        // a single row of data.
        Vector2 maxSize = MaxRectSize(hist);
        int maxArea = (int)(maxSize.x * maxSize.y);

        // STEP 3:
        // build histograms for each additional row, re-testing for new possible max rectangluar areas
        for (int x = 1; x < gridSizeX; x++) {
            // build a new histogram for this row. the values of this row are
            // 0 if the current grid point is occupied; otherwise, it is 1 + the value
            // of the previously found historgram value for the previous position. 
            // What this does is effectly keep track of the height of continous avilable spaces.
            // EXAMPLE:
            //      Given the following grid data (where 1 means occupied, and 0 means free; for clairty):
            //          INPUT:        OUTPUT:
            //      1.) [0,0,1,0]   = [1,1,0,1]
            //      2.) [0,0,1,0]   = [2,2,0,2]
            //      3.) [1,1,0,1]   = [0,0,1,0]
            //
            //  As such, you'll notice position 1,0 (row 1, column 0) is 2, because this is the height of contiguous
            //  free space.
            for (int y = 0; y < gridSizeY; y++) {                
                if(!invalidPoints[x, y]) {
                    hist[y] = 1 + hist[y];
                } else {
                    hist[y] = 0;
                }
            }

            // find the maximum size of the current histogram. If it happens to be larger
            // that the currently recorded max size, then it is the new max size.
            Vector2 maxSizeTemp = MaxRectSize(hist);
            int tempArea = (int)(maxSizeTemp.x * maxSizeTemp.y);
            if (tempArea > maxArea) {
                maxSize = maxSizeTemp;
                maxArea = tempArea;
            }
        }

        // at this point, we know the max size
        return maxSize;            
    }

Một số điều cần lưu ý về điều này:

  1. Phiên bản này được sử dụng với API Unity. Bạn có thể dễ dàng làm cho điều này chung chung hơn bằng cách thay thế các phiên bản của Vector2 bằng KeyValuePair. Vector2 chỉ được sử dụng để lưu trữ hai giá trị một cách thuận tiện.
  2. invalidPoints [] là một mảng bool, trong đó true có nghĩa là điểm lưới "đang được sử dụng" và false nghĩa là không.

3

Giải pháp có độ phức tạp không gian O (cột) [Có thể sửa đổi thành O (hàng)] và độ phức tạp thời gian O (hàng * cột)

public int maximalRectangle(char[][] matrix) {
    int m = matrix.length;
    if (m == 0)
        return 0;
    int n = matrix[0].length;
    int maxArea = 0;
    int[] aux = new int[n];
    for (int i = 0; i < n; i++) {
        aux[i] = 0;
    }
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            aux[j] = matrix[i][j] - '0' + aux[j];
            maxArea = Math.max(maxArea, maxAreaHist(aux));
        }
    }
    return maxArea;
}

public int maxAreaHist(int[] heights) {
    int n = heights.length;
    Stack<Integer> stack = new Stack<Integer>();
    stack.push(0);
    int maxRect = heights[0];
    int top = 0;
    int leftSideArea = 0;
    int rightSideArea = heights[0];
    for (int i = 1; i < n; i++) {
        if (stack.isEmpty() || heights[i] >= heights[stack.peek()]) {
            stack.push(i);
        } else {
            while (!stack.isEmpty() && heights[stack.peek()] > heights[i]) {
                top = stack.pop();
                rightSideArea = heights[top] * (i - top);
                leftSideArea = 0;
                if (!stack.isEmpty()) {
                    leftSideArea = heights[top] * (top - stack.peek() - 1);
                } else {
                    leftSideArea = heights[top] * top;
                }
                maxRect = Math.max(maxRect, leftSideArea + rightSideArea);
            }
            stack.push(i);
        }
    }
    while (!stack.isEmpty()) {
        top = stack.pop();
        rightSideArea = heights[top] * (n - top);
        leftSideArea = 0;
        if (!stack.isEmpty()) {
            leftSideArea = heights[top] * (top - stack.peek() - 1);
        } else {
            leftSideArea = heights[top] * top;
        }
        maxRect = Math.max(maxRect, leftSideArea + rightSideArea);
    }
    return maxRect;
}

Nhưng tôi nhận được thời gian vượt quá giới hạn thời gian khi tôi thử điều này trên LeetCode. Có giải pháp nào ít phức tạp hơn không?


Đơn giản và dễ hiểu .. Cảm ơn bạn!
Swadhikar

2

Tôi đề xuất một phương pháp O (nxn).

Đầu tiên, bạn có thể liệt kê tất cả các hình chữ nhật trống tối đa. Rỗng có nghĩa là nó chỉ bao gồm các số 0. Hình chữ nhật trống tối đa sao cho nó không thể được kéo dài theo một hướng mà không che (ít nhất) một hình 1.

Có thể tìm thấy bài báo trình bày thuật toán O (nxn) để tạo một danh sách như vậy tại www.ulg.ac.be/telecom/rectaries cũng như mã nguồn (không được tối ưu hóa). Không cần lưu trữ danh sách, chỉ cần gọi một hàm gọi lại mỗi khi thuật toán tìm thấy một hình chữ nhật và chỉ lưu trữ hình lớn nhất (hoặc chọn tiêu chí khác nếu bạn muốn).

Lưu ý rằng tồn tại một bằng chứng (xem bài báo) rằng số lượng hình chữ nhật trống lớn nhất bị giới hạn bởi số pixel của hình ảnh (trong trường hợp này là nxn).

Do đó, việc chọn hình chữ nhật tối ưu có thể được thực hiện trong O (nxn), và phương pháp tổng thể cũng là O (nxn).

Trên thực tế, phương pháp này rất nhanh và được sử dụng để phân tích luồng video theo thời gian thực.


0

Đây là một phiên bản của giải pháp jfs, cũng cung cấp vị trí của hình chữ nhật lớn nhất:

from collections import namedtuple
from operator import mul

Info = namedtuple('Info', 'start height')

def max_rect(mat, value=0):
    """returns (height, width, left_column, bottom_row) of the largest rectangle 
    containing all `value`'s.

    Example:
    [[0, 0, 0, 0, 0, 0, 0, 0, 3, 2],
     [0, 4, 0, 2, 4, 0, 0, 1, 0, 0],
     [1, 0, 1, 0, 0, 0, 3, 0, 0, 4],
     [0, 0, 0, 0, 4, 2, 0, 0, 0, 0],
     [0, 0, 0, 2, 0, 0, 0, 0, 0, 0],
     [4, 3, 0, 0, 1, 2, 0, 0, 0, 0],
     [3, 0, 0, 0, 2, 0, 0, 0, 0, 4],
     [0, 0, 0, 1, 0, 3, 2, 4, 3, 2],
     [0, 3, 0, 0, 0, 2, 0, 1, 0, 0]]
     gives: (3, 4, 6, 5)
    """
    it = iter(mat)
    hist = [(el==value) for el in next(it, [])]
    max_rect = max_rectangle_size(hist) + (0,)
    for irow,row in enumerate(it):
        hist = [(1+h) if el == value else 0 for h, el in zip(hist, row)]
        max_rect = max(max_rect, max_rectangle_size(hist) + (irow+1,), key=area)
        # irow+1, because we already used one row for initializing max_rect
    return max_rect

def max_rectangle_size(histogram):
    stack = []
    top = lambda: stack[-1]
    max_size = (0, 0, 0) # height, width and start position of the largest rectangle
    pos = 0 # current position in the histogram
    for pos, height in enumerate(histogram):
        start = pos # position where rectangle starts
        while True:
            if not stack or height > top().height:
                stack.append(Info(start, height)) # push
            elif stack and height < top().height:
                max_size = max(max_size, (top().height, (pos - top().start), top().start), key=area)
                start, _ = stack.pop()
                continue
            break # height == top().height goes here

    pos += 1
    for start, height in stack:
        max_size = max(max_size, (height, (pos - start), start), key=area)

    return max_size

def area(size):
    return size[0] * size[1]

0

Để hoàn tất, đây là phiên bản C # xuất ra tọa độ hình chữ nhật. Nó dựa trên câu trả lời của dmarra nhưng không có bất kỳ phụ thuộc nào khác. Chỉ có hàm bool GetPixel (int x, int y) , trả về true khi một pixel được đặt ở tọa độ x, y.

    public struct INTRECT
    {
        public int Left, Right, Top, Bottom;

        public INTRECT(int aLeft, int aTop, int aRight, int aBottom)
        {
            Left = aLeft;
            Top = aTop;
            Right = aRight;
            Bottom = aBottom;
        }

        public int Width { get { return (Right - Left + 1); } }

        public int Height { get { return (Bottom - Top + 1); } }

        public bool IsEmpty { get { return Left == 0 && Right == 0 && Top == 0 && Bottom == 0; } }

        public static bool operator ==(INTRECT lhs, INTRECT rhs)
        {
            return lhs.Left == rhs.Left && lhs.Top == rhs.Top && lhs.Right == rhs.Right && lhs.Bottom == rhs.Bottom;
        }

        public static bool operator !=(INTRECT lhs, INTRECT rhs)
        {
            return !(lhs == rhs);
        }

        public override bool Equals(Object obj)
        {
            return obj is INTRECT && this == (INTRECT)obj;
        }

        public bool Equals(INTRECT obj)
        {
            return this == obj;
        }

        public override int GetHashCode()
        {
            return Left.GetHashCode() ^ Right.GetHashCode() ^ Top.GetHashCode() ^ Bottom.GetHashCode();
        }
    }

    public INTRECT GetMaximumFreeRectangle()
    {
        int XEnd = 0;
        int YStart = 0;
        int MaxRectTop = 0;
        INTRECT MaxRect = new INTRECT();
        // STEP 1:
        // build a seed histogram using the first row of grid points
        // example: [true, true, false, true] = [1,1,0,1]
        int[] hist = new int[Height];
        for (int y = 0; y < Height; y++)
        {
            if (!GetPixel(0, y))
            {
                hist[y] = 1;
            }
        }

        // STEP 2:
        // get a starting max area from the seed histogram we created above.
        // using the example from above, this value would be [1, 1], as the only valid area is a single point.
        // another example for [0,0,0,1,0,0] would be [1, 3], because the largest area of contiguous free space is 3.
        // Note that at this step, the heigh fo the found rectangle will always be 1 because we are operating on
        // a single row of data.
        Tuple<int, int> maxSize = MaxRectSize(hist, out YStart);
        int maxArea = (int)(maxSize.Item1 * maxSize.Item2);
        MaxRectTop = YStart;
        // STEP 3:
        // build histograms for each additional row, re-testing for new possible max rectangluar areas
        for (int x = 1; x < Width; x++)
        {
            // build a new histogram for this row. the values of this row are
            // 0 if the current grid point is occupied; otherwise, it is 1 + the value
            // of the previously found historgram value for the previous position. 
            // What this does is effectly keep track of the height of continous avilable spaces.
            // EXAMPLE:
            //      Given the following grid data (where 1 means occupied, and 0 means free; for clairty):
            //          INPUT:        OUTPUT:
            //      1.) [0,0,1,0]   = [1,1,0,1]
            //      2.) [0,0,1,0]   = [2,2,0,2]
            //      3.) [1,1,0,1]   = [0,0,1,0]
            //
            //  As such, you'll notice position 1,0 (row 1, column 0) is 2, because this is the height of contiguous
            //  free space.
            for (int y = 0; y < Height; y++)
            {
                if (!GetPixel(x, y))
                {
                    hist[y]++;
                }
                else
                {
                    hist[y] = 0;
                }
            }

            // find the maximum size of the current histogram. If it happens to be larger
            // that the currently recorded max size, then it is the new max size.
            Tuple<int, int> maxSizeTemp = MaxRectSize(hist, out YStart);
            int tempArea = (int)(maxSizeTemp.Item1 * maxSizeTemp.Item2);
            if (tempArea > maxArea)
            {
                maxSize = maxSizeTemp;
                maxArea = tempArea;
                MaxRectTop = YStart;
                XEnd = x;
            }
        }
        MaxRect.Left = XEnd - maxSize.Item1 + 1;
        MaxRect.Top = MaxRectTop;
        MaxRect.Right = XEnd;
        MaxRect.Bottom = MaxRectTop + maxSize.Item2 - 1;

        // at this point, we know the max size
        return MaxRect;
    }

    private Tuple<int, int> MaxRectSize(int[] histogram, out int YStart)
    {
        Tuple<int, int> maxSize = new Tuple<int, int>(0, 0);
        int maxArea = 0;
        Stack<Tuple<int, int>> stack = new Stack<Tuple<int, int>>();
        int x = 0;
        YStart = 0;
        for (x = 0; x < histogram.Length; x++)
        {
            int start = x;
            int height = histogram[x];
            while (true)
            {
                if (stack.Count == 0 || height > stack.Peek().Item2)
                {
                    stack.Push(new Tuple<int, int>(start, height));
                }
                else if (height < stack.Peek().Item2)
                {
                    int tempArea = (int)(stack.Peek().Item2 * (x - stack.Peek().Item1));
                    if (tempArea > maxArea)
                    {
                        YStart = stack.Peek().Item1;
                        maxSize = new Tuple<int, int>(stack.Peek().Item2, (x - stack.Peek().Item1));
                        maxArea = tempArea;
                    }
                    Tuple<int, int> popped = stack.Pop();
                    start = (int)popped.Item1;
                    continue;
                }
                break;
            }
        }

        foreach (Tuple<int, int> data in stack)
        {
            int tempArea = (int)(data.Item2 * (x - data.Item1));
            if (tempArea > maxArea)
            {
                YStart = data.Item1;
                maxSize = new Tuple<int, int>(data.Item2, (x - data.Item1));
                maxArea = tempArea;
            }
        }

        return maxSize;
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.