1+ #include < algorithm>
2+ #include < climits>
3+ #include < cmath>
4+ #include < cstring>
5+ #include < functional>
6+ #include < iostream>
7+ #include < map>
8+ #include < numeric>
9+ #include < queue>
10+ #include < set>
11+ #include < stack>
12+ #include < string>
13+ #include < unordered_map>
14+ #include < unordered_set>
15+ #include < vector>
16+
17+ using namespace std ;
18+
19+ // prefix sum & heap
20+ // time : O(RC \* min(R, C))
21+ // space : O(RC)
22+ class Solution {
23+ public:
24+ vector<int > getBiggestThree (vector<vector<int >>& grid) {
25+ int rows = grid.size (), cols = grid[0 ].size ();
26+ vector<vector<int >> rightDp (rows + 1 , vector<int >(cols + 2 ));
27+ vector<vector<int >> leftDp (rows + 1 , vector<int >(cols + 2 ));
28+ for (int y = 1 ; y <= rows; y++) {
29+ for (int x = 1 ; x <= cols; x++) {
30+ rightDp[y][x] = rightDp[y - 1 ][x - 1 ] + grid[y - 1 ][x - 1 ];
31+ leftDp[y][x] = leftDp[y - 1 ][x + 1 ] + grid[y - 1 ][x - 1 ];
32+ }
33+ }
34+
35+ unordered_set<int > visited;
36+ priority_queue<int , vector<int >, greater<int >> pq;
37+
38+ function<void (int )> add = [&](int sum) {
39+ if (visited.count (sum) == 0 ) {
40+ visited.insert (sum);
41+ pq.push (sum);
42+ if (pq.size () > 3 ) {
43+ visited.erase (pq.top ());
44+ pq.pop ();
45+ }
46+ }
47+ };
48+
49+ for (int y = 0 ; y < rows; ++y) {
50+ for (int x = 0 ; x < cols; ++x) {
51+ add (grid[y][x]);
52+
53+ for (int yy = y + 2 ; yy < rows; yy += 2 ) {
54+ int uy = y, ux = x;
55+ int dy = yy, dx = x;
56+ int ly = (y + yy) / 2 , lx = x - (yy - y) / 2 ;
57+ int ry = (y + yy) / 2 , rx = x + (yy - y) / 2 ;
58+
59+ if (lx < 0 || rx >= cols) break ;
60+
61+ int topLeft = leftDp[ly + 1 ][lx + 1 ] - leftDp[uy][ux + 2 ];
62+ int topRight = rightDp[ry + 1 ][rx + 1 ] - rightDp[uy][ux];
63+ int bottomRight = rightDp[dy + 1 ][dx + 1 ] - rightDp[ly][lx];
64+ int bottomLeft = leftDp[dy + 1 ][dx + 1 ] - leftDp[ry][rx + 2 ];
65+
66+ int duplicated =
67+ grid[uy][ux] + grid[dy][dx] + grid[ly][lx] + grid[ry][rx];
68+
69+ int sum = topLeft + topRight + bottomRight + bottomLeft - duplicated;
70+
71+ add (sum);
72+ }
73+ }
74+ }
75+ vector<int > answer;
76+ while (!pq.empty ()) {
77+ answer.push_back (pq.top ());
78+ pq.pop ();
79+ }
80+ reverse (answer.begin (), answer.end ());
81+ return answer;
82+ }
83+ };
84+
85+ // prefix sum & heap
86+ // time : O(RC \* min(R, C))
87+ // space : O(RC \* min(R, C))
88+ class Solution {
89+ public:
90+ vector<int > getBiggestThree (vector<vector<int >>& grid) {
91+ int rows = grid.size (), cols = grid[0 ].size ();
92+
93+ vector<vector<vector<int >>> topDp (
94+ rows, vector<vector<int >>(cols, vector<int >(51 , INT_MIN)));
95+ vector<vector<vector<int >>> downDp (
96+ rows, vector<vector<int >>(cols, vector<int >(51 , INT_MIN)));
97+
98+ for (int y = 0 ; y < rows; y++) {
99+ for (int x = 0 ; x < cols; x++) {
100+ topDp[y][x][0 ] = 0 ;
101+ topDp[y][x][1 ] = grid[y][x];
102+ for (int l = 2 ; l <= 50 ; l++) {
103+ int diff = l - 1 ;
104+
105+ if (x - diff < 0 || x + diff >= cols) break ;
106+ if (y + diff >= rows) break ;
107+ topDp[y][x][l] = topDp[y][x][l - 1 ] + grid[y + diff][x + diff] +
108+ grid[y + diff][x - diff];
109+ }
110+
111+ downDp[y][x][0 ] = 0 ;
112+ downDp[y][x][1 ] = grid[y][x];
113+ for (int l = 2 ; l <= 50 ; l++) {
114+ int diff = l - 1 ;
115+
116+ if (x - diff < 0 || x + diff >= cols) break ;
117+ if (y - diff < 0 ) break ;
118+ downDp[y][x][l] = downDp[y][x][l - 1 ] + grid[y - diff][x + diff] +
119+ grid[y - diff][x - diff];
120+ }
121+ }
122+ }
123+
124+ priority_queue<int , vector<int >, greater<int >> pq;
125+ unordered_set<int > visited;
126+ function<void (int )> add = [&](int sum) {
127+ if (visited.count (sum) == 0 ) {
128+ visited.insert (sum);
129+ pq.push (sum);
130+ if (pq.size () > 3 ) {
131+ pq.pop ();
132+ }
133+ }
134+ };
135+ for (int y = 0 ; y < rows; y++) {
136+ for (int x = 0 ; x < cols; x++) {
137+ for (int l = 1 ; l <= 50 ; l++) {
138+ int diff = l - 1 ;
139+ if (y + 2 * diff >= rows) break ;
140+ if (topDp[y][x][l] == INT_MIN ||
141+ downDp[y + 2 * diff][x][l - 1 ] == INT_MIN)
142+ break ;
143+ int cur = topDp[y][x][l] + downDp[y + 2 * diff][x][l - 1 ];
144+
145+ add (cur);
146+ }
147+ }
148+ }
149+
150+ vector<int > answer;
151+ while (!pq.empty ()) {
152+ answer.push_back (pq.top ());
153+ pq.pop ();
154+ }
155+ reverse (answer.begin (), answer.end ());
156+ return answer;
157+ }
158+ };
0 commit comments