leetcode

Leetcode Solutions (0x6A73)
git clone https://git.pngu.org/leetcode
Log | Files | Refs | Submodules | README

commit c2626ccd050dd852b59d63a97529978b1e4ade9a
parent 65d4c333e07eaa581033ab4295e79db2687235f5
Author: Jack Sangdahl <jack@pngu.org>
Date:   Wed, 25 Mar 2026 21:45:34 -0600

3548. equal sum grid partition 2

Diffstat:
Aequal_sum_grid_partition2.c | 157+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aequal_sum_grid_partition2.py | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 225 insertions(+), 0 deletions(-)

diff --git a/equal_sum_grid_partition2.c b/equal_sum_grid_partition2.c @@ -0,0 +1,157 @@ +// 3548. Equal Sum Grid Partition II +#include "leetcode.h" + +/* + * you are given an 'm x n' matrix 'grid' of positive integers. your task is to + * determine if it is possible to make either one horizontal or one vertical cut + * on the grid such that each of the two resulting sections formed by the cut is + * non-empty, the sum of the elements in both sections is equal or can be made + * equal by discounting at most one single cell in total, and if a cell is + * discounted, the rest of the section must remain connected. return 'true' if + * such a partition exists, otherwise return false. + */ + +struct hash_item { + long long key; + UT_hash_handle hh; +}; + +static inline struct hash_item *hash_find_item(struct hash_item **obj, + long long key) { + struct hash_item *p_entry = NULL; + HASH_FIND(hh, *obj, &key, sizeof(key), p_entry); + return p_entry; +} + +bool hash_add_item(struct hash_item **obj, long long key) { + if (hash_find_item(obj, key)) + return false; + struct hash_item *p_entry = + (struct hash_item *)malloc(sizeof(struct hash_item)); + p_entry->key = key; + HASH_ADD(hh, *obj, key, sizeof(key), p_entry); + return true; +} + +void hash_free(struct hash_item **obj) { + struct hash_item *curr, *tmp; + HASH_ITER(hh, *obj, curr, tmp) { + HASH_DEL(*obj, curr); + free(curr); + } + *obj = NULL; +} + +int **rotation(int **grid, int m, int n, int *new_m, int *new_n) { + *new_m = n; + *new_n = m; + int **res = (int **)malloc(n * sizeof(int *)); + int *data = (int *)malloc(n * m * sizeof(int)); + for (int i = 0; i < n; i++) + res[i] = data + i * m; + for (int i = 0; i < m; i++) + for (int j = 0; j < n; j++) + res[j][m - 1 - i] = grid[i][j]; + return res; +} + +void free_grid(int **grid, int n) { + if (grid && grid[0]) + free(grid[0]); + free(grid); +} + +static inline bool check(struct hash_item **exist, int **curr, int curr_m, + int **original) { + hash_free(exist); + if (curr != original) + free_grid(curr, curr_m); + return true; +} + +static inline void rotate_update(int ***curr_grid, int *curr_m, int *curr_n, + int **original) { + int new_m, new_n; + int **new_grid = rotation(*curr_grid, *curr_m, *curr_n, &new_m, &new_n); + if (*curr_grid != original) + free_grid(*curr_grid, *curr_m); + *curr_grid = new_grid; + *curr_m = new_m; + *curr_n = new_n; +} + +bool canPartitionGrid(int **grid, int gridSize, int *gridColSize) { + const int m = gridSize, n = gridColSize[0]; + long long total = 0; + for (int i = 0; i < m; i++) + for (int j = 0; j < n; j++) + total += grid[i][j]; + int curr_m = m, curr_n = n, **curr_grid = grid; + for (int k = 0; k < 4; k++) { + struct hash_item *exist = NULL; + hash_add_item(&exist, 0LL); + long long sum = 0; + if (curr_m < 2 || curr_n == 1) { + if (curr_n == 1 && curr_m >= 2) + for (int i = 0; i < curr_m - 1; i++) { + sum += curr_grid[i][0]; + long long tag = sum * 2 - total; + if (!tag || tag == curr_grid[0][0] || tag == curr_grid[i][0]) + return check(&exist, curr_grid, curr_m, grid); + } + rotate_update(&curr_grid, &curr_m, &curr_n, grid); + hash_free(&exist); + continue; + } + for (int i = 0; i < curr_m - 1; i++) { + for (int j = 0; j < curr_n; j++) { + hash_add_item(&exist, (long long)curr_grid[i][j]); + sum += curr_grid[i][j]; + } + long long tag = sum * 2 - total; + if (!i) { + if (!tag || tag == curr_grid[0][0] || tag == curr_grid[0][curr_n - 1]) + return check(&exist, curr_grid, curr_m, grid); + continue; + } + if (hash_find_item(&exist, tag)) + return check(&exist, curr_grid, curr_m, grid); + } + rotate_update(&curr_grid, &curr_m, &curr_n, grid); + hash_free(&exist); + } + if (curr_grid != grid) + free_grid(curr_grid, curr_m); + return false; +} + +int main() { + int g1i[2][2] = {{1, 4}, {2, 3}}; + int g2i[2][2] = {{1, 2}, {3, 4}}; + int g3i[2][3] = {{1, 2, 4}, {2, 3, 5}}; + int g4i[2][3] = {{4, 1, 8}, {3, 2, 6}}; + struct two_d_arr *g1 = + two_d_arr_init(ARRAY_SIZE(g1i), ARRAY_SIZE(g1i[0]), g1i); + struct two_d_arr *g2 = + two_d_arr_init(ARRAY_SIZE(g2i), ARRAY_SIZE(g2i[0]), g2i); + struct two_d_arr *g3 = + two_d_arr_init(ARRAY_SIZE(g3i), ARRAY_SIZE(g3i[0]), g3i); + struct two_d_arr *g4 = + two_d_arr_init(ARRAY_SIZE(g4i), ARRAY_SIZE(g4i[0]), g4i); + bool r1 = canPartitionGrid(g1->arr, g1->row_size, g1->col_size); + bool r2 = canPartitionGrid(g2->arr, g2->row_size, g2->col_size); + bool r3 = canPartitionGrid(g3->arr, g3->row_size, g3->col_size); + bool r4 = canPartitionGrid(g4->arr, g4->row_size, g4->col_size); + printf("%d\n", r1); + assert(r1 == true); + printf("%d\n", r2); + assert(r2 == true); + printf("%d\n", r3); + assert(r3 == false); + printf("%d\n", r4); + assert(r4 == false); + two_d_arr_free(g1); + two_d_arr_free(g2); + two_d_arr_free(g3); + two_d_arr_free(g4); +} diff --git a/equal_sum_grid_partition2.py b/equal_sum_grid_partition2.py @@ -0,0 +1,68 @@ +# 3548. Equal Sum Grid Partition II +from typing import List + +""" +you are given an 'm x n' matrix 'grid' of positive integers. your task is to +determine if it is possible to make either one horizontal or one vertical cut +on the grid such that each of the two resulting sections formed by the cut is +non-empty, the sum of the elements in both sections is equal or can be made +equal by discounting at most one single cell in total, and if a cell is +discounted, the rest of the section must remain connected. return 'true' if +such a partition exists, otherwise return false. +""" + + +class Solution: + def canPartitionGrid(self, grid: List[List[int]]) -> bool: + m, n = len(grid), len(grid[0]) + total = 0 + for i in range(m): + for j in range(n): + total += grid[i][j] + for _ in range(4): + exist = set() + exist.add(0) + sum_val = 0 + m = len(grid) + n = len(grid[0]) + if m < 2: + grid = self.rotation(grid) + continue + if n == 1: + for i in range(m - 1): + sum_val += grid[i][0] + tag = sum_val * 2 - total + if tag == 0 or tag == grid[0][0] or tag == grid[i][0]: + return True + grid = self.rotation(grid) + continue + for i in range(m - 1): + for j in range(n): + exist.add(grid[i][j]) + sum_val += grid[i][j] + tag = sum_val * 2 - total + if i == 0: + if tag == 0 or tag == grid[0][0] or tag == grid[0][n - 1]: + return True + continue + if tag in exist: + return True + grid = self.rotation(grid) + return False + + def rotation(self, grid: List[List[int]]) -> List[List[int]]: + m = len(grid) + n = len(grid[0]) + tmp = [[0] * m for _ in range(n)] + for i in range(m): + for j in range(n): + tmp[j][m - 1 - i] = grid[i][j] + return tmp + + +if __name__ == "__main__": + obj = Solution() + print(obj.canPartitionGrid(grid=[[1, 4], [2, 3]])) + print(obj.canPartitionGrid(grid=[[1, 2], [3, 4]])) + print(obj.canPartitionGrid(grid=[[1, 2, 4], [2, 3, 5]])) + print(obj.canPartitionGrid(grid=[[4, 1, 8], [3, 2, 6]]))