给定一个矩阵mat[][]有 N 行和 M 列。任务是找到矩阵中所需的最小更改次数,使得从左上角到右下角的每条路径都是回文路径。在路径中,只允许从一个单元格到另一个单元格的向右和底部移动。
例子:
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) 等距的所有元素,然后以最少的更改次数使所有元素相等。维护一个计数变量以获取更改的总数。下面是该方法的说明:
- 从左上角和右下角可能的距离是 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
Javascript
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) 元素替换为频率最大的元素并存储结果+=(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)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。