剑指offer每日一题【顺时针打印矩阵、螺旋矩阵、栈的压入,弹出序列、验证栈序列 、把字符串转换成整数】

本文介绍了如何使用迭代法实现顺时针打印矩阵,以及利用栈结构验证压入和弹出序列的正确性。涉及的算法包括螺旋矩阵遍历、栈的压入与弹出操作验证,以及字符串转换成整数的技巧。这些技术展示了在数据结构和算法中的基本应用。
摘要由CSDN通过智能技术生成

在这里插入图片描述

顺时针打印矩阵.


class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        vector<int> res;  //记录遍历
        if(matrix.empty()) return res;
        int n = matrix.size(), m = matrix[0].size();  //横纵坐标
        vector<vector<bool>> st(n, vector<bool>(m, false)); //记录是否遍历过
        //上、右、下、左四种走向
        int dx[] = {-1, 0, 1, 0}, dy[] = {0 , 1 , 0 , -1};
        //初始值从【0,0】开始走
        int x = 0, y = 0, d = 1;
        for(int i = 0;i < n * m; i++) //循环走n * m次表示走完了
        {
            res.push_back(matrix[x][y]);//记录
            st[x][y] = true;  //标记
            int a = x + dx[d], b = y + dy[d];
            //下次走
            if(a < 0 || a >= n || b < 0 || b >= m || st[a][b]) 
            //如果实际的坐标不合法或者已经走过,那么就需要重新调整走向并
            //确定新的位置
            {
                d = (d + 1) % 4;  //调整走向
                a = x + dx[d], b = y + dy[d];  //重新确定位置
            }
            x = a, y = b;
        }
        return res;

    }
};

在这里插入图片描述

螺旋矩阵

类似的一道题也可以使用这个解法去处理螺旋矩阵.

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        vector<int> res;
        if(!matrix.size()) return res;
        int n = matrix.size(), m = matrix[0].size();
        vector<vector<bool>> st(n, vector<bool>(m, false));
        //上右下左
        int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
        int x = 0, y = 0, d = 1;
        for(int i = 0;i < n * m; i++)
        {
            res.push_back(matrix[x][y]);//存放答案
            st[x][y] = true;//标记为走过
            int a = x + dx[d], b = y + dy[d];
            if(a < 0 || a >= n || b < 0 || b >= m || st[a][b]){
                d = (d + 1) % 4;  //重新调整走向
                a = dx[d] + x, b = dy[d] + y;//确定新的坐标
            } 
            x = a, y = b;
        }
        return res;
    }
};

在这里插入图片描述
在这里插入图片描述

栈的压入、弹出序列.

class Solution {
public:
    bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
        //长度不一样肯定不相等
        if(pushed.size() != popped.size()) return false;
        stack<int> st;
        int i = 0;
        for(const auto &ref : pushed)
        {
            st.push(ref);

            //如果栈顶元素跟popped容器中的某一元素相同那么就出栈
            while(i < popped.size() && st.size() && st.top() == popped[i])
            {
                st.pop();
                i++;
            }
        }
        return st.empty();
    }
};

在这里插入图片描述

验证栈序列.

此题与上面那道题也是一样的解法,这里不得不吐槽力扣的重复题真是多,读者了解即可

class Solution {
public:
    bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
        if(pushed.size() != popped.size()) return false;

        int i = 0;
        stack<int> st;
        for(auto &ref : pushed)
        {
            st.push(ref);

            while(i < popped.size() && st.size() && st.top() == popped[i]) st.pop(), i++;
        }
        return st.empty();
    }
};

在这里插入图片描述
在这里插入图片描述

核心思想为使用一个指针从前往后逐个检查字符串中的字符是否合法,如果合法,则指针后移,否则指针停止移动,显然如果字符串是合法的,这个指针应该移动到字符串的最末尾

同时在移动指针的过程中判断从字符串开始到当前位置的字符子串是否是合法的数值,并将它存储在isNum中,显然isNum记录了指针所指位置的字符子串是否能表示为数值的信息

class Solution {
public:
    /*
        解题思路:
        首先为了能够区分i指针遍历到字符串结尾位置时就表示字符串是合法的,可以追加一个‘\0’在字符串的结
        尾位置(表示遍历到该位置时字符串就是合法的),字符串的前面空格和末尾空格都要处理(跳过忽略),
        紧接着要把不包含e的所有数字字符串处理,那么剩余的情况就是包含数字和e的情况了分开处理

        总结:
        1、加法减法符号忽略,因为是合法的
        2、空格忽略,数字判断并不需要包含空格
        3、判断字符串合法的方式是看i指针知否走到‘\0’位置处
        4、字符串中数字字符包含e和不好含e要分情况看待
    */
    bool isNumber(string s) {
        bool isNum = false;  //默认为fasle
        //删除前后空格
        int i = 0, j = s.size() - 1;
        while(i < s.size() && s[i] == ' ') i++;
        while(j >= 0 && s[j] == ' ') j--;
        //为字符串末尾位置加上‘\0’,为字符串合法标记
        s[j + 1] = '\0';


        //将所有的加减法符号和数字小数点的情况包含进来比如: +1.34、+.12345
        if(s[i] == '+' || s[i] == '-') i++;
        //判断数字字符
        while(s[i] >= '0' && s[i] <= '9')
        {
            isNum = true;
            i++;
        }
        //处理小数点
        if(s[i] == '.') i++;

        //小数点后面为数字
        while(s[i] >= '0' && s[i] <= '9')
        {
            isNum = true;
            i++;
        }
        //以上已经把不包含e/E的情况给处理了,那么剩下的就是包含小数点和e(又或者e之后会有数字那么该字
        //符串一定是合法的)
        if(isNum && (s[i] == 'e' || s[i] == 'E'))
        {
            isNum = false; //字符串中出现e默认将isNum值设置为false,防止isNum后面没有数字
            i++;
            if(s[i] == '+' || s[i] == '-')  i++;//忽略加法减法符号,因为是合法的
            //判断e后面是否会出现数字字符,如果出现数字字符那么该字符串又是属于合法的了
            while(s[i] >= '0' && s[i] <= '9') 
            {
                isNum = true;
                i++;
            }
        }
        return (isNum && s[i] == '\0');
         //如果i指针遍历字符串的过程中没有出现意外的情况,那么i指针一定会走到字符串的结尾位置,并且isNum的值一定是true
    }
};

在这里插入图片描述
在这里插入图片描述

把字符串转换成整数.

class Solution {
public:
    int strToInt(string str) {
       
        int i = 0;
        while(i < str.size() && str[i] == ' ') ++i;//跳过所有的空格
        long ret = 0;
        bool isminus = false; //假设正数
        if(str[i] == '-' || str[i] == '+'){
            if(str[i] == '-') isminus = true; //如果出现-号就标记为负数
            ++i;
        } 
        long long res = 0;
        while(str[i] >= '0' && str[i] <= '9'){
            ret = ret * 10 + str[i] - '0';  //将剩余的数字字符转换为数字
            ++i;
            if(!isminus && ret > INT_MAX) return INT_MAX;
            if(isminus && ret- 1 > INT_MAX) return INT_MIN; 
        }
        return isminus ? -ret : ret;
    }
};
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱生活,爱代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值