Javascript | Simple Solution w/ Explanation & Visuals | beats 100% / 100%
Idea:\n\nSince the elements in each column can\'t move, we can think of each consecutive group of 1s in each column as a solid pillar within that column.\n\nmat
***Idea:***\n\nSince the elements in each column can\'t move, we can think of each consecutive group of **1**s in each column as a solid pillar within that column.\n```\nmatrix:   [ [ 0, 1, 0, 1, 0 ],\n            [ 1, 1, 0, 1, 1 ],\n            [ 1, 1, 1, 0, 1 ],\n            [ 1, 0, 1, 1, 0 ],\n            [ 1, 1, 1, 1, 1 ],\n            [ 0, 1, 0, 1, 1 ] ]\n```\n![image](https://assets.leetcode.com/users/images/b7105965-b163-4946-b87a-30918d98c2ff_1610953636.4017441.png)\n\nWe can iterate through the matrix once and convert each cell into a running total of the number of consecutive **1**s that stretch up from each cell in the row. That number represents the height of the pillar that would exist upward from this row.\n```\nmatrix:  [ [ 0, 1, 0, 1, 0 ],\n           [ 1, 2, 0, 2, 1 ],\n           [ 2, 3, 1, 0, 2 ],\n           [ 3, 0, 2, 1, 0 ],\n           [ 4, 1, 3, 2, 1 ],\n           [ 0, 2, 0, 3, 2 ] ]\n```\nWe can then iterate down the rows and on each row sort the pillar heights together in order to evaluate the maximum value found ending on that row.\n```\nmatrix[4]: [ 4, 1, 3, 2, 1 ]\n           [ 4, 3, 2, 1, 1 ]   // The row after it\'s sorted in descending order\n```\n![image](https://assets.leetcode.com/users/images/3fc73fe8-e174-4068-8112-8844fa94e451_1610954233.7745287.png)\n```\n        col. 0:              cols. 0-1:             cols. 0-2:            cols. 0-3:             cols. 0-4:\n       4 * 1 = 4             3 * 2 = 6              2 * 3 = 6             1 * 4 = 4              1 * 5 = 5\n```\nAfter we iterate through, we can return the best result.\n\nThe best result for the code below is **144ms / 55.3MB**.\n\n` `\n***Implementation:***\n\nFirst, we need to iterate through the matrix **M** and update each cell\'s value. If the cell is a **1**, then replace it with the value from the cell above, incremented.\n\nSince each row will now "remember" the height above it, we\'re free to sort each row when we iterate through again. After sorting, run through the pillar height values and multiply them by the submatrix width and check if they\'re better than the current best answer. If so, update **ans**.\n\nThen just **return ans.**\n\n` `\n***Code:***\n```\nvar largestSubmatrix = function(M) {\n    let y = M.length, x = M[0].length, ans = 0\n    for (let i = 1; i < y; i++)\n        for (let j = 0; j < x; j++)\n            if (M[i][j]) M[i][j] += M[i-1][j]\n    for (let i = 0; i < y; i++) {\n        let row = M[i].sort((a,b) => b - a)\n        for (let j = 0; j < x; j++)\n            ans = Math.max(ans, (j + 1) * row[j])\n    }\n    return ans\n};\n```
['JavaScript']