给定一个二维数组,表示等长瓷砖的宽度和水平,每个水平的总宽度相同,任务是找到可以被穿过所有水平的剑的单次垂直打击切割的最小数量的瓷砖瓷砖。
例子:
Input: tilesStack[][] = { { 2, 3 }, { 3, 2 }, { 1, 1, 1, 2 }, { 1, 1, 1, 1, 1 } }
Output: 1
Explanation:
The minimum number of tiles that can be cut is equal to 1
Input: tilesStack[][] = { { 1, 1 }, { 1, 1 } }
Output: 0
方法:这个想法是找到最大数量的间隙,以便如果绘制的垂直线通过这些点,那么它将切割最少数量的瓷砖。请按照以下步骤解决问题:
- 遍历二维数组tilesStack[][]的每一行。对于每第i 行,Map 其前缀和,它表示从最左边的 tile 开始的间隙的距离,并使用 Map 存储每行的前缀和的频率。
- 找到前缀总和(间隙距离)的最大频率,比如X 。
- 最后,打印(length(tilesStack) – X) 的值,它表示通过绘制垂直线切割的最小瓷砖数量。
下面是这个方法的实现。
C++
// C++ program for the above approach
#include
using namespace std;
// Function to count the minimum number
// of tiles that gets cut by a single
// vertical strike of a sword
void cutTiles(vector> tilesStack)
{
// Map prefix sum of each row
// of tilesStack
map gaps;
// Traverse each row of the tiles
for(vector tiles:tilesStack)
{
// Stores distance of gap from
// left of each row
int totWidth = 0;
// Excluding the last gap as it will
// be the edge of the level
for(int i = 0; i < tiles.size() - 1; i++)
{
// Update totWidth
totWidth += tiles[i];
// If gap is already found at
// this points in previous levels
gaps[totWidth]++;
}
}
// Stores maximum number of
// gap from left
int X = 0;
for(auto x : gaps)
{
X = max(x.second, X);
}
cout << tilesStack.size() - X;
}
// Driver code
int main()
{
vector> tilesStack(4);
tilesStack[0].push_back(2);
tilesStack[0].push_back(3);
tilesStack[1].push_back(3);
tilesStack[1].push_back(2);
tilesStack[2].push_back(1);
tilesStack[2].push_back(1);
tilesStack[2].push_back(1);
tilesStack[2].push_back(2);
tilesStack[3].push_back(1);
tilesStack[3].push_back(1);
tilesStack[3].push_back(1);
tilesStack[3].push_back(1);
tilesStack[3].push_back(1);
// Function Call
cutTiles(tilesStack);
}
// This code is contributed by rutvik_56.
Java
// Java program for the above approach
import java.util.*;
public class GFG
{
// Function to count the minimum number
// of tiles that gets cut by a single
// vertical strike of a sword
static void cutTiles(Vector> tilesStack)
{
// Map prefix sum of each row
// of tilesStack
HashMap gaps = new HashMap<>();
// Traverse each row of the tiles
for(Vector tiles : tilesStack)
{
// Stores distance of gap from
// left of each row
int totWidth = 0;
// Excluding the last gap as it will
// be the edge of the level
for(int i = 0; i < tiles.size() - 1; i++)
{
// Update totWidth
totWidth += tiles.get(i);
// If gap is already found at
// this points in previous levels
if(gaps.containsKey(totWidth))
{
gaps.put(totWidth, gaps.get(totWidth) + 1);
}
else{
gaps.put(totWidth, 1);
}
}
}
// Stores maximum number of
// gap from left
int X = 0;
for (Map.Entry Key : gaps.entrySet())
{
X = Math.max((int)Key.getValue(),X);
}
System.out.print(tilesStack.size() - X);
}
// Driver code
public static void main(String[] args)
{
Vector> tilesStack = new Vector>();
tilesStack.add(new Vector());
tilesStack.get(0).add(2);
tilesStack.get(0).add(3);
tilesStack.add(new Vector());
tilesStack.get(1).add(3);
tilesStack.get(1).add(2);
tilesStack.add(new Vector());
tilesStack.get(2).add(1);
tilesStack.get(2).add(1);
tilesStack.get(2).add(1);
tilesStack.get(2).add(2);
tilesStack.add(new Vector());
tilesStack.get(3).add(1);
tilesStack.get(3).add(1);
tilesStack.get(3).add(1);
tilesStack.get(3).add(1);
tilesStack.get(3).add(1);
// Function Call
cutTiles(tilesStack);
}
}
// This code is contributed by divyeshrabadiya07.
Python
# Python3 program for the above approach
# Function to count the minimum number
# of tiles that gets cut by a single
# vertical strike of a sword
def cutTiles(tilesStack):
# Map prefix sum of each row
# of tilesStack
gaps = {}
# Handling the case when
# map will be empty
gaps[-1] = 0
# Traverse each row of the tiles
for tiles in tilesStack:
# Stores distance of gap from
# left of each row
totWidth = 0
# Excluding the last gap as it will
# be the edge of the level
for tile in tiles[:-1]:
# Update totWidth
totWidth += tile
# If gap is already found at
# this points in previous levels
if totWidth in gaps:
gaps[totWidth] += 1
else:
gaps[totWidth] = 1
# Stores maximum number of
# gap from left
X = max(list(gaps.values()))
print(len(tilesStack) - X)
# Driver Code
if __name__ == '__main__':
tilesStack = [[2, 3], [3, 2], [1, 1, 1, 2],
[1, 1, 1, 1, 1]]
# Function Call
cutTiles(tilesStack)
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG {
// Function to count the minimum number
// of tiles that gets cut by a single
// vertical strike of a sword
static void cutTiles(List> tilesStack)
{
// Map prefix sum of each row
// of tilesStack
Dictionary gaps = new Dictionary();
// Traverse each row of the tiles
foreach(List tiles in tilesStack)
{
// Stores distance of gap from
// left of each row
int totWidth = 0;
// Excluding the last gap as it will
// be the edge of the level
for(int i = 0; i < tiles.Count - 1; i++)
{
// Update totWidth
totWidth += tiles[i];
// If gap is already found at
// this points in previous levels
if(gaps.ContainsKey(totWidth))
{
gaps[totWidth] += 1;
}
else{
gaps[totWidth] = 1;
}
}
}
// Stores maximum number of
// gap from left
int X = 0;
foreach(KeyValuePair Key in gaps)
{
X = Math.Max(Key.Value,X);
}
Console.WriteLine(tilesStack.Count - X);
}
static void Main() {
List> tilesStack = new List>();
tilesStack.Add(new List());
tilesStack[0].Add(2);
tilesStack[0].Add(3);
tilesStack.Add(new List());
tilesStack[1].Add(3);
tilesStack[1].Add(2);
tilesStack.Add(new List());
tilesStack[2].Add(1);
tilesStack[2].Add(1);
tilesStack[2].Add(1);
tilesStack[2].Add(2);
tilesStack.Add(new List());
tilesStack[3].Add(1);
tilesStack[3].Add(1);
tilesStack[3].Add(1);
tilesStack[3].Add(1);
tilesStack[3].Add(1);
// Function Call
cutTiles(tilesStack);
}
}
// This code is contributed by divyeshrbadiya07.
输出:
1
时间复杂度: O(N * M),其中 N 是级别的总数,M 是每个级别的宽度
辅助空间: O(M)