3548. Equal Sum Grid Partition II
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<RootNamespace>_3548._Equal_Sum_Grid_Partition_II</RootNamespace>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
139
3548. Equal Sum Grid Partition II/Program.cs
Normal file
139
3548. Equal Sum Grid Partition II/Program.cs
Normal file
@@ -0,0 +1,139 @@
|
||||
var sol = new Solution();
|
||||
|
||||
var cases = new (int[][] grid, bool expected, string name)[]
|
||||
{
|
||||
(
|
||||
new[]
|
||||
{
|
||||
new[] { 1, 4 },
|
||||
new[] { 2, 3 }
|
||||
},
|
||||
true,
|
||||
"Example 1"
|
||||
),
|
||||
(
|
||||
new[]
|
||||
{
|
||||
new[] { 1, 2 },
|
||||
new[] { 3, 4 }
|
||||
},
|
||||
true,
|
||||
"Example 2"
|
||||
),
|
||||
(
|
||||
new[]
|
||||
{
|
||||
new[] { 1, 2, 4 },
|
||||
new[] { 2, 3, 5 }
|
||||
},
|
||||
false,
|
||||
"Example 3"
|
||||
),
|
||||
(
|
||||
new[]
|
||||
{
|
||||
new[] { 4, 1, 8 },
|
||||
new[] { 3, 2, 6 }
|
||||
},
|
||||
false,
|
||||
"Example 4"
|
||||
),
|
||||
(
|
||||
new[]
|
||||
{
|
||||
new[] { 5, 5, 6, 2, 2, 2 }
|
||||
},
|
||||
true,
|
||||
"Example 5"
|
||||
),
|
||||
(
|
||||
new[]
|
||||
{
|
||||
new[] { 100000 },
|
||||
new[] { 86218 },
|
||||
new[] { 100000 }
|
||||
},
|
||||
true,
|
||||
"Example 6"
|
||||
),
|
||||
(
|
||||
new[]
|
||||
{
|
||||
new[] { 1, 2, 4 },
|
||||
new[] { 1, 6, 6 },
|
||||
new[] { 5, 6, 7 }
|
||||
},
|
||||
true,
|
||||
"Example 7"
|
||||
),
|
||||
(
|
||||
new[]
|
||||
{
|
||||
new[] { 1, 2, 1, 1, 1 },
|
||||
new[] { 1, 1, 1, 2, 1 }
|
||||
},
|
||||
true,
|
||||
"Example 8"
|
||||
),
|
||||
(
|
||||
new[]
|
||||
{
|
||||
new[] { 1, 1 },
|
||||
new[] { 2, 1 },
|
||||
new[] { 1, 1 },
|
||||
new[] { 1, 2 },
|
||||
new[] { 1, 1 }
|
||||
},
|
||||
true,
|
||||
"Example 9"
|
||||
),
|
||||
(
|
||||
new[]
|
||||
{
|
||||
new[] { 10, 5, 4, 5 }
|
||||
},
|
||||
false,
|
||||
"Example 10"
|
||||
),
|
||||
(
|
||||
new[]
|
||||
{
|
||||
new[] { 1, 1 },
|
||||
new[] { 2, 1 },
|
||||
new[] { 4, 3 }
|
||||
},
|
||||
false,
|
||||
"Example 11"
|
||||
),
|
||||
(
|
||||
new[]
|
||||
{
|
||||
new[] { 4 },
|
||||
new[] { 3 },
|
||||
new[] { 4 },
|
||||
new[] { 4 },
|
||||
new[] { 4 }
|
||||
},
|
||||
false,
|
||||
"Example 12"
|
||||
),
|
||||
(
|
||||
new[]
|
||||
{
|
||||
new[] { 100000 },
|
||||
new[] { 100000 },
|
||||
new[] { 100000 },
|
||||
new[] { 100000 },
|
||||
new[] { 1 }
|
||||
},
|
||||
true,
|
||||
"Example 13"
|
||||
),
|
||||
|
||||
};
|
||||
|
||||
foreach (var (grid, expected, name) in cases)
|
||||
{
|
||||
var actual = sol.CanPartitionGrid(grid);
|
||||
Console.WriteLine($"{name}: {actual} (expected: {expected})");
|
||||
}
|
||||
130
3548. Equal Sum Grid Partition II/Solution.cs
Normal file
130
3548. Equal Sum Grid Partition II/Solution.cs
Normal file
@@ -0,0 +1,130 @@
|
||||
public class Solution
|
||||
{
|
||||
struct SumInfo
|
||||
{
|
||||
public long Left;
|
||||
public long Right;
|
||||
public long Value;
|
||||
// ключ - число, значение - индексы, где оно встречается
|
||||
public Dictionary<long, SortedSet<int>> Nums;
|
||||
}
|
||||
|
||||
public bool CanPartitionGrid(int[][] grid)
|
||||
{
|
||||
var height = grid.Length;
|
||||
var width = grid[0].Length;
|
||||
|
||||
var colSums = new SumInfo[width];
|
||||
var rowSums = new SumInfo[height];
|
||||
for (var i = 0; i < height; i++)
|
||||
{
|
||||
for (var j = 0; j < width; j++)
|
||||
{
|
||||
var num = grid[i][j];
|
||||
colSums[j].Value += num;
|
||||
rowSums[i].Value += num;
|
||||
rowSums[i].Nums ??= new Dictionary<long, SortedSet<int>>();
|
||||
colSums[j].Nums ??= new Dictionary<long, SortedSet<int>>();
|
||||
|
||||
rowSums[i].Nums.TryAdd(num, new SortedSet<int>());
|
||||
rowSums[i].Nums[num].Add(j);
|
||||
|
||||
colSums[j].Nums.TryAdd(num, new SortedSet<int>());
|
||||
colSums[j].Nums[num].Add(i);
|
||||
}
|
||||
rowSums[i].Left = rowSums[i].Value;
|
||||
if (i > 0)
|
||||
rowSums[i].Left += rowSums[i - 1].Left;
|
||||
}
|
||||
for (var i = height - 1; i >= 0; i--)
|
||||
{
|
||||
rowSums[i].Right = rowSums[i].Value;
|
||||
if (i < height - 1)
|
||||
rowSums[i].Right += rowSums[i + 1].Right;
|
||||
}
|
||||
for (var j = 0; j < width; j++)
|
||||
{
|
||||
colSums[j].Left = colSums[j].Value;
|
||||
if (j > 0)
|
||||
colSums[j].Left += colSums[j - 1].Left;
|
||||
}
|
||||
for (var j = width - 1; j >= 0; j--)
|
||||
{
|
||||
colSums[j].Right = colSums[j].Value;
|
||||
if (j < width - 1)
|
||||
colSums[j].Right += colSums[j + 1].Right;
|
||||
}
|
||||
var answer = false;
|
||||
for (var i = 0; i < rowSums.Length - 1 && !answer; i++)
|
||||
{
|
||||
var row = rowSums[i];
|
||||
var nextRow = rowSums[i + 1];
|
||||
var diff = Math.Abs(row.Left - nextRow.Right);
|
||||
|
||||
var edgesOnly = colSums.Length == 1;
|
||||
var colLen = height;
|
||||
if (diff == 0 ||
|
||||
(row.Left < nextRow.Right && CanDelete(diff, colSums, i, true, i + 1 == rowSums.Length - 1, edgesOnly, colLen)) ||
|
||||
(row.Left > nextRow.Right && CanDelete(diff, colSums, i, false, i == 0, edgesOnly, colLen)))
|
||||
answer |= true;
|
||||
}
|
||||
for (var j = 0; j < colSums.Length - 1 && !answer; j++)
|
||||
{
|
||||
var col = colSums[j];
|
||||
var nextCol = colSums[j + 1];
|
||||
var diff = Math.Abs(col.Left - nextCol.Right);
|
||||
// тут проход по колонкам, значит поиск элемента для удаления надо выполнять по строкам
|
||||
// если j == 0 и отрезаем в левой части, то надо смотреть только первую и последнюю строку
|
||||
// если j+1 == colSums.Len-1 и отрезаем в правой части, то надо смотреть только первую и последнюю строку
|
||||
var edgesOnly = rowSums.Length == 1;
|
||||
var rowLen = width;
|
||||
if (diff == 0 ||
|
||||
(col.Left < nextCol.Right && CanDelete(diff, rowSums, j, true, j + 1 == colSums.Length - 1, edgesOnly, rowLen)) ||
|
||||
(col.Left > nextCol.Right && CanDelete(diff, rowSums, j, false, j == 0, edgesOnly, rowLen)))
|
||||
answer |= true;
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="target">Целевое число для поиска</param>
|
||||
/// <param name="infos">Что перебирать</param>
|
||||
/// <param name="idx">Индекс отсечения (для удаления справа строго больше, для удаления слева включительно)</param>
|
||||
/// <param name="deleteAfterIdx">Удалять ли спарва от индекса</param>
|
||||
/// <param name="firstAndLastOnly">Посмотреть только первый и последний SumInfo</param>
|
||||
/// <param name="edgesOnly">В sumInfo брать только крайние элементы</param>
|
||||
/// <param name="len">Количество чисел в SumInfo</param>
|
||||
/// <returns></returns>
|
||||
private static bool CanDelete(long target, SumInfo[] infos, int idx, bool deleteAfterIdx, bool firstAndLastOnly, bool edgesOnly, int len)
|
||||
{
|
||||
for (var i = 0; i < infos.Length; i++)
|
||||
{
|
||||
var nums = infos[i].Nums;
|
||||
|
||||
if (nums.TryGetValue(target, out var indexes))
|
||||
{
|
||||
var before = false;
|
||||
var after = false;
|
||||
if (edgesOnly)
|
||||
{
|
||||
before = indexes.Contains(0) || indexes.Contains(idx);
|
||||
after = indexes.Contains(len - 1) || indexes.Contains(idx+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
before = indexes.GetViewBetween(int.MinValue, idx).Count > 0;
|
||||
after = indexes.GetViewBetween(idx + 1, int.MaxValue).Count > 0;
|
||||
}
|
||||
if ((before && !deleteAfterIdx) || (after && deleteAfterIdx))
|
||||
return true;
|
||||
}
|
||||
|
||||
// если только границы, перейти сразу к последнему элементу
|
||||
if (firstAndLastOnly && i == 0)
|
||||
i = Math.Max(i, infos.Length - 2);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
14
Leetcode.sln
14
Leetcode.sln
@@ -197,6 +197,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "114. Flatten Binary Tree to
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "30. Substring with Concatenation of All Words", "30. Substring with Concatenation of All Words\30. Substring with Concatenation of All Words.csproj", "{DC410457-B769-4597-857D-5AAD2BDBAAC3}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "3548. Equal Sum Grid Partition II", "3548. Equal Sum Grid Partition II\3548. Equal Sum Grid Partition II.csproj", "{D4C2B514-1A13-495A-8627-8B40AD8B2770}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -1371,6 +1373,18 @@ Global
|
||||
{DC410457-B769-4597-857D-5AAD2BDBAAC3}.Release|x64.Build.0 = Release|Any CPU
|
||||
{DC410457-B769-4597-857D-5AAD2BDBAAC3}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{DC410457-B769-4597-857D-5AAD2BDBAAC3}.Release|x86.Build.0 = Release|Any CPU
|
||||
{D4C2B514-1A13-495A-8627-8B40AD8B2770}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D4C2B514-1A13-495A-8627-8B40AD8B2770}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D4C2B514-1A13-495A-8627-8B40AD8B2770}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{D4C2B514-1A13-495A-8627-8B40AD8B2770}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{D4C2B514-1A13-495A-8627-8B40AD8B2770}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{D4C2B514-1A13-495A-8627-8B40AD8B2770}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{D4C2B514-1A13-495A-8627-8B40AD8B2770}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D4C2B514-1A13-495A-8627-8B40AD8B2770}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D4C2B514-1A13-495A-8627-8B40AD8B2770}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{D4C2B514-1A13-495A-8627-8B40AD8B2770}.Release|x64.Build.0 = Release|Any CPU
|
||||
{D4C2B514-1A13-495A-8627-8B40AD8B2770}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{D4C2B514-1A13-495A-8627-8B40AD8B2770}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
Reference in New Issue
Block a user