Leetcode 2946. Matrix Similarity After Cyclic Shifts
Given two matrices, matrixA
and matrixB
, return the minimum number of cyclic shifts needed to make matrixA
identical to matrixB
if possible. If it is not possible to make them identical with any number of cyclic shifts, return -1.
A cyclic shift is defined as shifting all elements of a row or a column to the left or up by one position in a circular manner (elements that move out from one end reappear on the opposite end).
Constraints:
matrixA
and matrixB
are of the same size (m x n).Row and Column Shifts: Determine the number of cyclic shifts required for each row and column separately to align matrixA
with matrixB
.
Check Feasibility: If aligning any row or column requires a different number of shifts than other rows or columns, return -1.
Shift Calculation: Calculate and track the shifts required and find the minimum number of shifts.
matrixA
, determine how many cyclic shifts would be required for it to match the corresponding row in matrixB
.#include <vector>
#include <algorithm>
using namespace std;
class Solution {
public:
int minimumShiftsToMakeIdentical(vector<vector<int>>& matrixA, vector<vector<int>>& matrixB) {
int m = matrixA.size();
int n = matrixA[0].size();
// Check if cyclic shifts are same for rows
for (int i = 0; i < m; i++) {
vector<int> shifts;
for (int shift = 0; shift < n; shift++) {
if (isRowEqual(matrixA[i], matrixB[i], shift)) {
shifts.push_back(shift);
}
}
if (shifts.empty()) return -1;
}
// Check if cyclic shifts are same for columns
for (int j = 0; j < n; j++) {
vector<int> shifts;
for (int shift = 0; shift < m; shift++) {
if (isColumnEqual(matrixA, matrixB, j, shift)) {
shifts.push_back(shift);
}
}
if (shifts.empty()) return -1;
}
// Calculate minimum shifts (minimal intersection for both row and column shifts)
int minShift = INT_MAX;
for (int rowShift = 0; rowShift < n; rowShift++) {
for (int colShift = 0; colShift < m; colShift++) {
if (isMatrixEqualAfterShift(matrixA, matrixB, rowShift, colShift)) {
minShift = min(minShift, rowShift + colShift);
}
}
}
return minShift == INT_MAX ? -1 : minShift;
}
private:
bool isRowEqual(const vector<int>& rowA, const vector<int>& rowB, int shift) {
int n = rowA.size();
for (int i = 0; i < n; i++) {
if (rowA[i] != rowB[(i + shift) % n]) {
return false;
}
}
return true;
}
bool isColumnEqual(const vector<vector<int>>& matrixA, const vector<vector<int>>& matrixB, int col, int shift) {
int m = matrixA.size();
for (int i = 0; i < m; i++) {
if (matrixA[i][col] != matrixB[(i + shift) % m][col]) {
return false;
}
}
return true;
}
bool isMatrixEqualAfterShift(const vector<vector<int>>& matrixA, const vector<vector<int>>& matrixB, int rowShift, int colShift) {
int m = matrixA.size();
int n = matrixA[0].size();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (matrixA[i][j] != matrixB[(i + rowShift) % m][(j + colShift) % n]) {
return false;
}
}
}
return true;
}
};
This ensures that we efficiently check possible shifts and determine the minimal necessary shifts or return -1
if it’s not feasible.
Got blindsided by a question you didn’t expect?
Spend too much time studying?
Or simply don’t have the time to go over all 3000 questions?