给定具有N行M列的矩阵mat [] [] 。任务是找到矩阵中所需的最小变化数,以使从左上到右下的每条路径都是回文路径。在路径中,只允许从一个单元格到另一个单元格的右移和下移。
例子:
Input: mat[][] = {{1, 2}, {3, 1}}
Output: 0
Explanation:
Every path in the matrix from top left to bottom right is palindromic.
Paths => {1, 2, 1}, {1, 3, 1}
Input: mat[][] = {{1, 2}, {3, 5}}
Output: 1
Explanation:
Only one change is required for the every path to be palindromic.
That is => mat[1][1] = 1
Paths => {1, 2, 1}, {1, 3, 1}
简单方法:
该问题的主要观察结果是,距前端或后端相同距离的元素相等。因此,找到与(0,0)和(N-1,M-1)等距离的所有元素,然后以最小的更改次数使所有元素相等。维护一个count变量以获取更改的总数。下面是该方法的说明:
- 左上角和右下角可能的距离是0到N + M – 2。
- 保持两个指针在左上角,即距离为0,而另一个则为N + M – 2。
- 遍历矩阵,并在所有距离上保持当前距离处矩阵元素的哈希图。
- 用所需的最少更改次数更新矩阵元素。
- 最后,将左侧距离增加1,并将右侧距离减少1。
下面是上述方法的实现:
C++
// C++ implementation to find the
// minimum number of changes required
// such that every path from top left
// to the bottom right
// are palindromic paths
#include
using namespace std;
#define M 3
#define N 3
// Function to find the minimum number
// of the changes required for the
// every path to be palindromic
int minchanges(int mat[N][M])
{
// count variable for
// maintaining total changes.
int count = 0;
// left and right variables for
// keeping distance values
// from cell(0, 0) and
// (N-1, M-1) respectively.
int left = 0, right = N + M - 2;
while (left < right) {
unordered_map mp;
int totalsize = 0;
// Iterating over the matrix
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (i + j == left) {
mp[mat[i][j]]++;
totalsize++;
}
else if (i + j == right) {
mp[mat[i][j]]++;
totalsize++;
}
}
}
// Finding minimum number
// of changes required.
unordered_map::iterator itr = mp.begin();
int changes = 0;
for (; itr != mp.end(); itr++)
changes = max(changes, itr->second);
// Minimum no. of changes will
// be the the minimum no.
// of different values and
// we will assume to
// make them equals to value
// with maximum frequency element
count += totalsize - changes;
// Moving ahead with
// greater distance
left++;
right--;
}
return count;
}
// Drive Code
int main()
{
int mat[][M]
= { { 1, 4, 1 }, { 2, 5, 3 }, { 1, 3, 1 } };
// Function Call
cout << minchanges(mat);
return 0;
}
Java
// Java implementation to find the
// minimum number of changes required
// such that every path from top left
// to the bottom right are palindromic
// paths
import java.io.*;
import java.util.*;
class GFG {
static final int M = 3;
static final int N = 3;
// Function to find the minimum number
// of the changes required for the
// every path to be palindromic
static int minchanges(int[][] mat)
{
// count variable for
// maintaining total changes.
int count = 0;
// left and right variables for
// keeping distance values
// from cell(0, 0) and
// (N-1, M-1) respectively.
int left = 0, right = N + M - 2;
while (left < right) {
Map mp = new HashMap<>();
int totalsize = 0;
// Iterating over the matrix
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (i + j == left) {
mp.put(mat[i][j],
mp.getOrDefault(mat[i][j], 0)
+ 1);
totalsize++;
}
else if (i + j == right) {
mp.put(mat[i][j],
mp.getOrDefault(mat[i][j], 0)
+ 1);
totalsize++;
}
}
}
// Finding minimum number
// of changes required.
int changes = 0;
for (Map.Entry itr :
mp.entrySet())
changes = Math.max(changes, itr.getValue());
// Minimum no. of changes will
// be the the minimum no.
// of different values and
// we will assume to
// make them equals to value
// with maximum frequency element
count += totalsize - changes;
// Moving ahead with
// greater distance
left++;
right--;
}
return count;
}
// Driver Code
public static void main(String[] args)
{
int mat[][]
= { { 1, 4, 1 }, { 2, 5, 3 }, { 1, 3, 1 } };
// Function Call
System.out.println(minchanges(mat));
}
}
// This code is contributed by offbeat
Python3
# Python3 implementation to find the
# minimum number of changes required
# such that every path from top left
# to the bottom right
# are palindromic paths
M = 3
N = 3
# Function to find the minimum number
# of the changes required for the
# every path to be palindromic
def minchanges(mat):
# count variable for
# maintaining total changes.
count = 0
# left and right variables for
# keeping distance values
# from cell(0, 0) and
# (N-1, M-1) respectively.
left = 0
right = N + M - 2
while (left < right):
mp = {}
totalsize = 0
# Iterating over the matrix
for i in range(N):
for j in range(M):
if (i + j == left):
mp[mat[i][j]] =
mp.get(mat[i][j], 0) + 1
totalsize += 1
elif (i + j == right):
mp[mat[i][j]] =
mp.get(mat[i][j], 0) + 1
totalsize += 1
# Finding minimum number
# of changes required.
changes = 0
for itr in mp:
changes = max(changes, mp[itr])
# Minimum no. of changes will
# be the the minimum no.
# of different values and
# we will assume to
# make them equals to value
# with maximum frequency element
count += totalsize - changes
# Moving ahead with
# greater distance
left += 1
right -= 1
return count
# Driver Code
if __name__ == '__main__':
mat = [[1, 4, 1],
[2, 5, 3],
[1, 3, 1]]
# Function Call
print(minchanges(mat))
# This code is contributed by Mohit Kumar 29
C#
// C# implementation to find the
// minimum number of changes required
// such that every path from top left
// to the bottom right are palindromic
// paths
using System;
using System.Collections;
using System.Collections.Generic;
class GFG {
static int M = 3;
static int N = 3;
// Function to find the minimum number
// of the changes required for the
// every path to be palindromic
static int minchanges(int[, ] mat)
{
// count variable for
// maintaining total changes.
int count = 0;
// left and right variables for
// keeping distance values
// from cell(0, 0) and
// (N-1, M-1) respectively.
int left = 0, right = N + M - 2;
while (left < right) {
Dictionary mp
= new Dictionary();
int totalsize = 0;
// Iterating over the matrix
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (i + j == left) {
if (mp.ContainsKey(mat[i, j])) {
mp[mat[i, j]]++;
}
else {
mp[mat[i, j]] = 1;
}
totalsize++;
}
else if (i + j == right) {
if (mp.ContainsKey(mat[i, j])) {
mp[mat[i, j]]++;
}
else {
mp[mat[i, j]] = 1;
}
totalsize++;
}
}
}
// Finding minimum number
// of changes required.
int changes = 0;
foreach(KeyValuePair itr in mp)
{
changes = Math.Max(changes, itr.Value);
}
// Minimum no. of changes will
// be the the minimum no.
// of different values and
// we will assume to
// make them equals to value
// with maximum frequency element
count += totalsize - changes;
// Moving ahead with
// greater distance
left++;
right--;
}
return count;
}
// Driver Code
public static void Main(string[] args)
{
int[, ] mat
= { { 1, 4, 1 }, { 2, 5, 3 }, { 1, 3, 1 } };
// Function Call
Console.Write(minchanges(mat));
}
}
// This code is contributed by rutvik_56
C++
// C++ Program to count minimum change
// required to convert all the paths
// pallindromic from top left to
// right bottom cell.
#include
using namespace std;
// Function to find the minimum number
// of the changes required for the
// every path to be palindromic
int minchanges(vector >& a)
{
int res = 0; // use to store final result
// Row and column
int N = a.size(), M = a[0].size();
// mp_key -> (i+j) , mp_value -> nw_map
// nw_map_key -> elements_of_matrix
// nw_map_value -> frequency of elements
// 2-D map
map > mp;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
// calculating position
int ind = i + j;
// increase the frequency of a[i][j]
// at position ind
mp[ind][a[i][j]]++;
}
}
// Define left and right limit
int r = M + N - 2, l = 0;
while (l < r) {
// s-> count total number of elements
// at index l and r
// mx-> store maximum frequency of any element
int s = 0, mx = 0;
// store all elements frequency at index l
for (auto x : mp[r]) {
mp[l][x.first] += x.second;
}
// Count total elements and mx->max_frequency
for (auto x : mp[l]) {
s += x.second;
mx = max(x.second, mx);
}
// We will replace (s-mx) elements with
// the element whose frequency is mx
res += (s - mx);
l++;
r--;
}
// return res
return res;
}
// Driver Code
int main()
{
// Function Call
vector > mat
= { { 1, 4, 1 }, { 2, 5, 3 }, { 1, 3, 1 } };
cout << "Total number of changes requires "
<< minchanges(mat) << "\n";
// Function Call
vector > mat1
= { { 1, 4 }, { 2, 5 }, { 1, 3 }, { 2, 5 } };
cout << "Total number of changes requires "
<< minchanges(mat1) << "\n";
return 0;
}
// This code is contributed by ajaykr00kj
输出:
2
性能分析:
- 时间复杂度: O(N 3 )
- 辅助空间: O(N)
高效方法:
算法:
- 我们将使用一个哈希图来计算每个元素与顶部和底部的距离相同的频率。
- 为此,我们将使用2D映射,其中键将是索引,而值将是另一个将对频率进行计数的映射
- 计数频率后,我们将l = 0迭代到r = m + n-1,而l
- 我们将(sum-f)个元素替换为频率最大的元素,并存储result + =(sum-f)
- 打印结果
下面是上述方法的实现:
C++
// C++ Program to count minimum change
// required to convert all the paths
// pallindromic from top left to
// right bottom cell.
#include
using namespace std;
// Function to find the minimum number
// of the changes required for the
// every path to be palindromic
int minchanges(vector >& a)
{
int res = 0; // use to store final result
// Row and column
int N = a.size(), M = a[0].size();
// mp_key -> (i+j) , mp_value -> nw_map
// nw_map_key -> elements_of_matrix
// nw_map_value -> frequency of elements
// 2-D map
map > mp;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
// calculating position
int ind = i + j;
// increase the frequency of a[i][j]
// at position ind
mp[ind][a[i][j]]++;
}
}
// Define left and right limit
int r = M + N - 2, l = 0;
while (l < r) {
// s-> count total number of elements
// at index l and r
// mx-> store maximum frequency of any element
int s = 0, mx = 0;
// store all elements frequency at index l
for (auto x : mp[r]) {
mp[l][x.first] += x.second;
}
// Count total elements and mx->max_frequency
for (auto x : mp[l]) {
s += x.second;
mx = max(x.second, mx);
}
// We will replace (s-mx) elements with
// the element whose frequency is mx
res += (s - mx);
l++;
r--;
}
// return res
return res;
}
// Driver Code
int main()
{
// Function Call
vector > mat
= { { 1, 4, 1 }, { 2, 5, 3 }, { 1, 3, 1 } };
cout << "Total number of changes requires "
<< minchanges(mat) << "\n";
// Function Call
vector > mat1
= { { 1, 4 }, { 2, 5 }, { 1, 3 }, { 2, 5 } };
cout << "Total number of changes requires "
<< minchanges(mat1) << "\n";
return 0;
}
// This code is contributed by ajaykr00kj
输出
Total number of changes requires 2
Total number of changes requires 3
时间复杂度: O(m * n)
空间复杂度: O(m * n)