每日一题 力扣 2946. 循环移位后的矩阵相似检查 力扣 155. 最小栈 数学 数组 模拟 C++ 题解

文章目录

力扣 2946. 循环移位后的矩阵相似检查

题目描述

力扣 2946. 循环移位后的矩阵相似检查

示例 1:
输入:mat = \[1,2,1,2,5,5,5,5,6,3,6,3], k = 2

输出:true

解释:

初始矩阵如图一所示。

图二表示对奇数行右移一次且对偶数行左移一次后的矩阵状态。

图三是经过两次循环移位后的最终矩阵状态,与初始矩阵相同。

因此,返回 true 。
示例 2:

输入:mat = \[2,2,2,2], k = 3

输出:true

解释:由于矩阵中的所有值都相等,即使进行循环移位,矩阵仍然保持不变。因此,返回 true 。
示例 3:

输入:mat = \[1,2], k = 1

输出:false

解释:循环移位一次后,mat = \[2,1],与初始矩阵不相等。因此,返回 false 。
提示:

1 <= mat.length <= 25

1 <= mati.length <= 25

1 <= matij <= 25

1 <= k <= 50

思路简述

核心思路其实很简单:无论对一行进行左移 k 次还是右移 k 次,判断移位后矩阵能否复原的底层逻辑是完全一致的。

这就像我们玩三阶魔方时,把红色面正对自己,无论向左还是向右旋转某一层,都需要旋转 4 次才能让红色面完全回到正对自己的初始状态 ------ 循环移位的核心就是周期性。

对于矩阵中任意一个元素 matij,经过题目要求的循环移位后,它的目标位置可以直接通过公式推导得出,最终只需验证 matij 是否与 mati(j + k) % n 相等即可。这里对 n 取模,是为了处理 k 大于行长度 n 的情况,避免重复循环移位带来的索引越界问题,同时也能直接抵消掉完整周期的无效移位。

基于这个规律,我们完全不需要实际模拟每一次移位操作,只需遍历矩阵做一次等式校验,就能得出最终结果。

代码实现

cpp 复制代码
class Solution {
public:
    bool areSimilar(vector<vector<int>>& mat, int k) {
        int m = mat.size(), n = mat[0].size();

        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j < n; j++)
            {
                if(mat[i][j] != mat[i][(j + k) % n])
                    return false;
            }
        }
        return true;
    }
};

复杂度分析

  • 时间复杂度:O(mn),需遍历矩阵中所有元素。
  • 空间复杂度:O(1),仅使用常数额外空间。

力扣 155. 最小栈

题目描述

力扣 155. 最小栈

示例 1:

输入:

"MinStack","push","push","push","getMin","pop","top","getMin"

\[\],\[-2\],\[0\],\[-3\],\[\],\[\],\[\],\[\]

输出:

null,null,null,null,-3,null,0,-2

解释:

MinStack minStack = new MinStack();

minStack.push(-2);

minStack.push(0);

minStack.push(-3);

minStack.getMin(); --> 返回 -3.

minStack.pop();

minStack.top(); --> 返回 0.

minStack.getMin(); --> 返回 -2.
提示:

-231 <= val <= 231 - 1

pop、top 和 getMin 操作总是在 非空栈 上调用

push, pop, top, and getMin最多被调用 3 * 104

思路简述

最小栈的核心需求是在常数时间内获取最小值 。我们可以用双栈实现(用数组实现底层逻辑同理,核心思路完全一致):

  • 主栈 st1:作为标准栈,完整存储所有入栈的元素,支持常规的 push、pop、top 操作;
  • 辅助栈 st2:专门同步记录每一次入栈后,当前栈内的最小值。

具体操作逻辑:

  • push :将元素压入 st1,若当前元素小于 st2 的栈顶元素,则将其压入 st2,否则将 st2 的栈顶元素再次压入 st2("占位"操作,目的是简化 pop 逻辑)。
  • pop :同时弹出 st1st2 的栈顶元素。
  • getMinst2 的栈顶元素即为当前最小值。

代码实现

cpp 复制代码
class MinStack {
public:
    MinStack() {
        st2.push(INT_MAX);
    }
    
    void push(int x) 
    {
        st1.push(x);
        if(st2.top() > x)
            st2.push(x);
        else
            st2.push(st2.top());
    }
    
    void pop() {
        st1.pop();
        st2.pop();
    }
    
    int top() {
        return st1.top();
    }
    
    int getMin() {
        return st2.top();
    }

    stack<int> st1;
    stack<int> st2;
};

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack* obj = new MinStack();
 * obj->push(x);
 * obj->pop();
 * int param_3 = obj->top();
 * int param_4 = obj->getMin();
 */

复杂度分析

  • 时间复杂度:所有操作(push、pop、top、getMin)均为 O(1)。
  • 空间复杂度:O(n),需额外使用一个栈存储最小值。

踩坑记录

  1. 刚拿到「循环移位后的矩阵相似检查」这道题时,看到是简单题,第一反应是想硬凹纯数学规律的O(1)解法,结果越想越复杂,特殊情况层出不穷,最后才发现完全没必要。这里也引出一个纠结的问题:做算法题时,到底该直接模拟,还是该深挖数学规律?

  2. 最小栈这道题里,有个很容易忽略的细节:必须在构造函数中给辅助栈st2先压入一个INT_MAX完成初始化。如果不做这个操作,第一次调用push时访问st2.top()会直接触发空栈访问的报错,这个小细节很容易在写代码时漏掉。

这里给总结一个超好用的判断口诀,希望能够帮助大家,刷题时扫一眼就能快速做决策:

小数据,直接模拟。
大数据,必找规律。
步骤清,模拟稳。
结果能算,数学冲。

就像今天这道矩阵题,矩阵行列数最大才25,k最大也只有50,这种小数据范围,直接模拟或者用简化后的规律遍历,远比死磕O(1)数学解法划算得多,不仅写得快,还不容易出错。

今天的两道题都是校招、社招面试里的高频基础题,一道是数组矩阵的核心操作题,一道是栈结构的经典设计题,吃透了对打牢算法基础非常有帮助。

如果这篇题解对你有帮助,麻烦点个点赞 +收藏 ,也可以关注我,后续会持续更新力扣每日一题的详细题解,还有高频面试算法的保姆级讲解,陪你一起刷穿力扣!

相关推荐
周末也要写八哥6 分钟前
C++中单线程方式之无脑上锁
java·开发语言·c++
cany100016 分钟前
C++ -- 动态内存分配和释放(new/delete)
开发语言·c++
BD4SXV21 分钟前
线性二次调节器(Linear Quadratic Regulator,LQR)的无限时域最优控制求解与黎卡提方程
算法·自动化
ST——Jess30 分钟前
2026年度传统文化数字化与命理科技(Ethno-tech)行业趋势研究报告:专业级数智工作台的技术壁垒与评测标准
人工智能·科技·算法·架构
_Evan_Yao41 分钟前
线性代数 + 编程:用Python实现向量和矩阵运算
python·线性代数·矩阵
xcyxiner42 分钟前
ubuntu下 cmake初始化脚本 以及 qt依赖
c++·qt
周末也要写八哥42 分钟前
Visual C++6.0下载安装流程及PDF学习手册资源
c++·学习·pdf
Matrix_111 小时前
第13篇:非线性位移场——漩涡、鱼眼、水波纹与球面化
图像处理·算法
金牌归来发现妻女流落街头1 小时前
【LeetCode 第207题】
算法·leetcode·拓扑·领接表
熬夜敲代码的猫1 小时前
AVL树(C++详解版)
数据结构·c++·算法