给定一个矩阵mat[][]有N行和M列。任务是找到矩阵中所需的最小更改次数,使得从左上角到右下角的每条路径都是回文路径。在路径中,只允许从一个单元格到另一个单元格的向右和底部移动。
例子:
Input: M = 2, N = 2, mat[M][N] = {{0, 0}, {0, 1}}
Output: 1
Explanation:
Change matrix[0][0] from 0 to 1. The two paths from (0, 0) to (1, 1) become palindromic.
Input: M = 3, N = 7, mat[M][N] = {{1, 2, 3, 4, 5, 6, 7}, {2, 2, 3, 3, 4, 3, 2}, {1, 2, 3, 2, 5, 6, 4}}
Output: 10
Naive Approach:关于Naive Approach,请参考这篇文章。
时间复杂度: O(N^3)
辅助空间: O(N)
有效的方法:
必须进行以下观察:
- 每个值(i+j)都存在唯一的对角线,其中i是行索引, j是列索引。
- 任务简化为选择两条对角线,它们分别与单元格 (0, 0) 和单元格 (M – 1, N – 1) 的距离相同,并使它们的所有元素都等于一个数字,重复次数最多所选对角线上的时间。
- 如果单元格 (0, 0) 和 (M – 1, N – 1) 之间的元素数为奇数,则存在到两个单元格的公共对角线等距。该对角线的元素不需要修改,因为它们不会影响路径的回文排列。
- 如果 (0, 0) 和 (M – 1, N – 1) 之间的单元格数量是偶数,则不存在这样的公共对角线。
请按照以下步骤解决问题:
- 创建一个二维数组frequency_diagonal ,用于存储每个选定对角线上所有数字的频率。
- 每个对角线都可以唯一地表示为 (i, j) 的和。
- 初始化一个计数变量,该变量存储必须替换值的单元格总数的计数。
- 迭代mat[][]并增加当前元素在它所属的对角线((i + j) 值)中的频率。
- 将变量number_of_elements初始化为 1,它存储当前选择的每对对角线中的元素数。
- 初始化start = 0和end = M + N – 2并重复以下步骤直到start < end :
- 找出在与(0, 0)和(M-1, N-1)等距的两条选定对角线上出现次数最多的数字的频率。
- 令上述步骤中的频率为X 。添加值(两条对角线中的元素总数 – X)以计算更改的最小数量。
- 从1开始递增,以 1结尾递减,如果当前对角线上的元素数小于矩阵任何对角线上的最大可能元素,则将number_of_elements增加 1。
- 完成上述步骤后打印总计数的值。
下面是上述方法的实现:
C++
// C++ program of the above approach
#include
using namespace std;
// Function to calculate the minimum
// number of replacements
int MinReplacements(
int M, int N, int mat[][30])
{
// 2D array to store frequency
// of all the numners in
// each diaginal
int frequency_diagonal[100][10005];
// Initialise all the elements
// of 2D array with 0
memset(frequency_diagonal, 0,
sizeof(frequency_diagonal));
// Initialise answer as 0
int answer = 0;
// Iterate over the matrix
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
// Update the frequency of
// number mat[i][j]
// for the diagonal
// identified by (i+j)
frequency_diagonal[i + j]
[mat[i][j]]++;
}
}
// Initialize start as 0
// which indicates the
// first diagonal
int start = 0;
// Initialize end as
// M + N - 2 which indicates
// the last diagonal
int end = M + N - 2;
// Number of elements in
// the current diagonal
int no_of_elemnts = 1;
// Maximum possible number
// of elements in a diagonal
// can be minimum of (number of
// rows and number of columns)
int max_elements = min(M, N);
while (start < end) {
// The frequecny of number
// which occurs for the
// maximum number of times
// in the two selected
// diagonals
int X = INT_MIN;
for (int i = 0; i <= 10000; i++) {
X = max(
X,
frequency_diagonal[start][i]
+ frequency_diagonal[end][i]);
}
answer = answer + (2 * (no_of_elemnts)) - X;
// Increment start
start++;
// Decrement end
end--;
// Increment current number
// of elements until it reaches
// the maximum possible value
if (no_of_elemnts < max_elements)
no_of_elemnts++;
}
// return the final answer
return answer;
}
// Driver Code
int main()
{
// Number of rows
int M = 3;
// Number of columns
int N = 7;
int mat[30][30]
= { { 1, 2, 3, 4, 5, 6, 7 },
{ 2, 2, 3, 3, 4, 3, 2 },
{ 1, 2, 3, 2, 5, 6, 4 } };
cout << MinReplacements(M, N, mat)
<< endl;
}
Java
// Java program of the above approach
class GFG{
// Function to calculate the minimum
// number of replacements
static int MinReplacements(int M, int N,
int mat[][])
{
// 2D array to store frequency
// of all the numners in
// each diaginal
int [][]frequency_diagonal = new int[100][10005];
// Initialise answer as 0
int answer = 0;
// Iterate over the matrix
for(int i = 0; i < M; i++)
{
for(int j = 0; j < N; j++)
{
// Update the frequency of
// number mat[i][j]
// for the diagonal
// identified by (i+j)
frequency_diagonal[i + j][mat[i][j]]++;
}
}
// Initialize start as 0
// which indicates the
// first diagonal
int start = 0;
// Initialize end as
// M + N - 2 which indicates
// the last diagonal
int end = M + N - 2;
// Number of elements in
// the current diagonal
int no_of_elemnts = 1;
// Maximum possible number
// of elements in a diagonal
// can be minimum of (number of
// rows and number of columns)
int max_elements = Math.min(M, N);
while (start < end)
{
// The frequecny of number
// which occurs for the
// maximum number of times
// in the two selected
// diagonals
int X = Integer.MIN_VALUE;
for(int i = 0; i <= 10000; i++)
{
X = Math.max(X,
frequency_diagonal[start][i] +
frequency_diagonal[end][i]);
}
answer = answer + (2 * (no_of_elemnts)) - X;
// Increment start
start++;
// Decrement end
end--;
// Increment current number
// of elements until it reaches
// the maximum possible value
if (no_of_elemnts < max_elements)
no_of_elemnts++;
}
// return the final answer
return answer;
}
// Driver Code
public static void main(String[] args)
{
// Number of rows
int M = 3;
// Number of columns
int N = 7;
int mat[][] = { { 1, 2, 3, 4, 5, 6, 7 },
{ 2, 2, 3, 3, 4, 3, 2 },
{ 1, 2, 3, 2, 5, 6, 4 } };
System.out.print(MinReplacements(M, N, mat) + "\n");
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 program of the above approach
import sys
# Function to calculate the minimum
# number of replacements
def MinReplacements(M, N, mat):
# 2D array to store frequency
# of all the numners in
# each diaginal
frequency_diagonal = [[0 for x in range(10005)]
for y in range (100)];
# Initialise answer as 0
answer = 0
# Iterate over the matrix
for i in range(M):
for j in range(N):
# Update the frequency of
# number mat[i][j]
# for the diagonal
# identified by (i+j)
frequency_diagonal[i + j][mat[i][j]] += 1
# Initialize start as 0
# which indicates the
# first diagonal
start = 0
# Initialize end as
# M + N - 2 which indicates
# the last diagonal
end = M + N - 2
# Number of elements in
# the current diagonal
no_of_elemnts = 1
# Maximum possible number
# of elements in a diagonal
# can be minimum of (number of
# rows and number of columns)
max_elements = min(M, N)
while (start < end):
# The frequecny of number
# which occurs for the
# maximum number of times
# in the two selected
# diagonals
X = -sys.maxsize - 1
for i in range(10001):
X = max(X,
frequency_diagonal[start][i] +
frequency_diagonal[end][i])
answer = answer + (2 * (no_of_elemnts)) - X
# Increment start
start += 1
# Decrement end
end -= 1
# Increment current number
# of elements until it reaches
# the maximum possible value
if (no_of_elemnts < max_elements):
no_of_elemnts += 1
# Return the final answer
return answer
# Driver Code
# Number of rows
M = 3
# Number of columns
N = 7
mat = [ [ 1, 2, 3, 4, 5, 6, 7 ],
[ 2, 2, 3, 3, 4, 3, 2 ],
[ 1, 2, 3, 2, 5, 6, 4 ] ]
print(MinReplacements(M, N, mat))
# This code is contributed by chitranayal
C#
// C# program of the above approach
using System;
class GFG{
// Function to calculate the minimum
// number of replacements
static int MinReplacements(int M, int N,
int [,]mat)
{
// 2D array to store frequency
// of all the numners in
// each diaginal
int [,]frequency_diagonal = new int[100, 10005];
// Initialise answer as 0
int answer = 0;
// Iterate over the matrix
for(int i = 0; i < M; i++)
{
for(int j = 0; j < N; j++)
{
// Update the frequency of
// number mat[i,j]
// for the diagonal
// identified by (i+j)
frequency_diagonal[i + j, mat[i, j]]++;
}
}
// Initialize start as 0
// which indicates the
// first diagonal
int start = 0;
// Initialize end as
// M + N - 2 which indicates
// the last diagonal
int end = M + N - 2;
// Number of elements in
// the current diagonal
int no_of_elemnts = 1;
// Maximum possible number
// of elements in a diagonal
// can be minimum of (number of
// rows and number of columns)
int max_elements = Math.Min(M, N);
while (start < end)
{
// The frequecny of number
// which occurs for the
// maximum number of times
// in the two selected
// diagonals
int X = int.MinValue;
for(int i = 0; i <= 10000; i++)
{
X = Math.Max(X,
frequency_diagonal[start, i] +
frequency_diagonal[end, i]);
}
answer = answer + (2 * (no_of_elemnts)) - X;
// Increment start
start++;
// Decrement end
end--;
// Increment current number
// of elements until it reaches
// the maximum possible value
if (no_of_elemnts < max_elements)
no_of_elemnts++;
}
// Return the readonly answer
return answer;
}
// Driver Code
public static void Main(String[] args)
{
// Number of rows
int M = 3;
// Number of columns
int N = 7;
int [,]mat = { { 1, 2, 3, 4, 5, 6, 7 },
{ 2, 2, 3, 3, 4, 3, 2 },
{ 1, 2, 3, 2, 5, 6, 4 } };
Console.Write(MinReplacements(M, N, mat) + "\n");
}
}
// This code is contributed by amal kumar choubey
输出:
10
时间复杂度: O(M * N)
辅助空间: O(M * N)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live