【Day19】LeetCode算法刷题(附带解题思路、代码注释详细) 【777. 在LR字符串中交换相邻字符】 【54. 螺旋矩阵】

简介: 学习了解附带解题思路、代码注释详细) 【777. 在LR字符串中交换相邻字符】 【54. 螺旋矩阵】。

刷题打卡,第 十九 天


题目一、777. 在LR字符串中交换相邻字符

题目二、54. 螺旋矩阵


题目一、777. 在LR字符串中交换相邻字符


原题链接:777. 在LR字符串中交换相邻字符


题目描述:


在一个由'L','R'和'X'三个字符组成的字符串(例如"RXXLRXRXL")中进行移动操作。一次移动操作指用一个"LX"替换一个"XL",或者用一个"XR"替换一个"RX"。现给定起始字符串start和结束字符串end,请编写代码,当且仅当存在一系列移动操作使得start可以转换成end时,

返回True。

/

示例 :

输入: start = “RXXLRXRXL”, end = “XRLXXRRLX”

输出: True

解释:

我们可以通过以下几步将start转换成end:

RXXLRXRXL ->

XRXLRXRXL ->

XRLXRXRXL ->

XRLXXRRXL ->

XRLXXRRLX

/

提示:

1 <= len(start) = len(end) <= 10000。

start和end中的字符串仅限于’L’, ‘R’和’X’。


解题思路:

为了确定start字符串是否可以通过交换相邻字符获得end字符串,我们可以同时遍历两个字符串,当遇到可以确定两者不能通过交换字符而相等的情况时,返回false即可,完全遍历完说明符合条件,返回true;


那么我们应该怎么判断情况呢?


通过题目我们可以知道,交换字符是通过:‘RX’ 替换成 ‘XR’ 或 ‘XL’ 替换成 ‘LX’ 实现的,如果两者符合条件可以交换相邻字符获取对方,当将字符串中所有字符‘L’删去,剩下的两个字符串是相同的。


①反过来想,我们便利时忽略掉字符‘L’,当遍历的两个字符不相等时,就能确定不符合条件,返回false了。


到这里还不能完全排除不符合条件的情况,另一个情况如下,那就是:


②根据规则:一个"LX"替换一个"XL",或者用一个"XR"替换一个"RX"。


当start字符串遍历到L或者R,都因该是XL或RX,而end字符串是LX或XR

所以当start遍历到L,下标i应该 大于等于 end字符串的下标j,因为start中XL的L在X之后

所以当start遍历到R,下标i应该 小于等于 end字符串的下标j,因为start中RX的R在X之前

如果遇到不符合上述描述的情况,搜可以返回false了

③我们按照上述的操作推演一下,就知道这最后一个元素会是’X’,否则返回false


当两个字符串都顺利遍历完,说明排除了所有无法交换获得的情况,可以返回true。


提交代码:

class Solution {
    public boolean canTransform(String start, String end) {
        int n = start.length();    //获取字符串长度,方便遍历
        int i = 0,j = 0;           //用i表示start字符串下标,用j表示end字符串下标
       while(i < n && j < n){     //同时遍历
            while(i < n && start.charAt(i) == 'X'){//跳过start字符串中的‘X’
                ++i;
            }
            while(j < n && end.charAt(j) == 'X'){  //跳过end字符串中的‘X’
                ++j;
            }
          if(i < n && j < n){
                //忽略掉‘X’字符发现剩下的字符不对应,说明无法通过交换相邻字符获得
                if(start.charAt(i) != end.charAt(j)){ 
                    return false;
          }
//当我们按照前面的步骤遍历,根据规则:一个"LX"替换一个"XL",或者用一个"XR"替换一个"RX"。
//当start字符串遍历到L或者R,都因该是XL或RX,而end字符串是LX或XR
//所以当start遍历到L,下标i应该 大于等于 end字符串的下标j,因为start中XL的`L`在`X`之后
//所以当start遍历到R,下标i应该 小于等于 end字符串的下标j,因为start中RX的`R`在`X`之前
//所以遇到不符合上述描述的情况,搜可以返回false了
                char ch = start.charAt(i);
                if(ch == 'L' && i < j || ch == 'R' && i > j){
                    return false;
                }
                ++i;++j;
            }
        }
        //当我们遍历到最后,一个字符串已经遍历完成,剩下一个字符串遍历到最后一个元素
        //我们按照上述的操作推演一下,就知道这最后一个元素会是'X',否则返回false
        while(i < n && i < j){
            if(start.charAt(i) != 'X')
            return false;
            ++i;
        }
        while(j < n && j < i){
            if(end.charAt(j) != 'X')
            return false;
            ++j;
        }
        //两个字符串遍历完无异常,就说明start可以通过交换相邻字符获得end,返回true
        return true;
    }
}

提交结果:

微信图片_20221030172912.png


题目二、54. 螺旋矩阵


原题链接:54. 螺旋矩阵


题目描述:


给你一个m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

/

示例 1:

微信图片_20221030172921.png

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]

输出:[1,2,3,6,9,8,7,4,5]

/

示例 2:

微信图片_20221030172927.png

输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]

输出:[1,2,3,4,8,12,11,10,9,5,6,7]


解题思路:

为了让矩阵能按照顺时针螺旋顺序遍历,我们可以先观察,总结这样遍历的特点,而且很轻易就能发现,螺旋矩阵的遍历总是先向左、向下、再向上,最后又向左的,那么我们就可以从这个规律着手。


为了按照旋转矩阵的规律遍历,我们可以设置一个用于翻转数组,改变遍历方向的数组move[][]内容如下:


{0,1}让矩阵向右遍历 行下标row + 0,列下标col + 1

{1,0}让矩阵向下遍历 行下标row + 1,列下标col + 0

{0,-1}让矩阵向左遍历 行下标row + 0,列下标col + -1

{-1,0}让矩阵向上遍历 行下标row + -1,列下标col + 0

我们一边遍历,一边将扫描过的元素存入集合,同时标记扫描过的位置。


当下一个位置没有越界 或 遍历过,就照常遍历,遇到越界 或 扫描过的位置,就利用数组move,改变遍历方向。


重复操作,知道遍历完成即可。


提交代码:

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> list = new ArrayList<>();       //创建集合,记录顺时针螺旋顺序
       //如果矩阵为空或不含元素,返回空集合
        if(matrix == null || matrix.length == 0 || matrix[0].length == 0) 
        return list;
    //获取矩阵的长度rows与高度cols
        int rows = matrix.length;
        int cols = matrix[0].length;
        //定义一个标记矩阵flag,与matrix大小一致,用于标记相同位置上被遍历过的元素
        boolean[][] flag = new boolean[rows][cols];
        //定义一个用于翻转矩阵的二维数组
        //第一行代表向右遍历
        //第二行代表向下遍历
        //第三行代表向左遍历
        //第四行代表向上遍历
        int[][] move = {{0,1},{1,0},{0,-1},{-1,0}};
        //记录当前行、当前列和遍历方向的下标index
        int row = 0,col = 0,index = 0;
        for(int i = 0;i < rows*cols;++i){
     //开始遍历,标记遍历过的位置
            list.add(matrix[row][col]);
            flag[row][col] = true;
            //记录下一位置的行下标和列下标
            int nextRow = row + move[index][0];
            int nextCol = col + move[index][1];
            //如果下一个位置越界或者被遍历过
            if(nextRow < 0 || nextRow >= rows ||
               nextCol < 0 || nextCol >= cols ||
               flag[nextRow][nextCol]){
                   //翻转矩阵进行螺旋遍历
                   index = (index+1)%4;
               }
            //向后一个位置挪动
            row += move[index][0];
      col += move[index][1];
        }
    return list; //返回按照顺时针螺旋顺序存放元素的集合
    }
}

提交结果:

微信图片_20221030172933.png

⚽求关注⚽ 作者🥇 .29. 🥇 的✔博客主页✔

⚽来刷题⚽ 记录每日LeetCode✔刷题专栏✔

您的点赞,收藏以及关注是对作者最大的鼓励喔 ~~

微信图片_20221029111446.jpg




目录
相关文章
|
Go 索引
【LeetCode 热题100】394:字符串解码(详细解析)(Go语言版)
本文详细解析了 LeetCode 热题 394:字符串解码。题目要求对编码字符串如 `k[encoded_string]` 进行解码,其中 `encoded_string` 需重复 `k` 次。文章提供了两种解法:使用栈模拟和递归 DFS,并附有 Go 语言实现代码。栈解法通过数字栈与字符串栈记录状态,适合迭代;递归解法则利用函数调用处理嵌套结构,代码更简洁。两者时间复杂度均为 O(n),但递归需注意栈深度问题。文章还总结了解题注意事项及适用场景,帮助读者更好地掌握字符串嵌套解析技巧。
522 6
|
存储 机器学习/深度学习 缓存
🚀 力扣热题 394:字符串解码(详细解析)(Go语言版)
文章提供了两种解法:栈结构和递归解法。栈解法通过维护数字栈与字符串栈,依次处理 `[` 和 `]`,构造解码结果;递归解法则利用函数调用逐层解析嵌套结构。两者时间复杂度均为 $O(n)$,空间复杂度也为 $O(n)$。栈解法直观易懂,适合初学者;递归解法优雅简洁,适合处理深度嵌套规则。掌握这两种方法,可灵活应对类似问题,提升解题能力。
626 11
|
人工智能 自然语言处理 程序员
通义灵码:融合创新玩法与探索,重塑LeetCode解题策略
欢迎来到工程师令狐小哥的频道。本文介绍如何利用AI工具高效刷LeetCode,通过通义灵码插件在IntelliJ IDEA中实现代码生成、优化、单元测试等功能,提升编程学习效率。
921 1
通义灵码:融合创新玩法与探索,重塑LeetCode解题策略
|
C++
Leetcode第43题(字符串相乘)
本篇介绍了一种用C++实现的字符串表示的非负整数相乘的方法,通过逆向编号字符串,将乘法运算转化为二维数组的累加过程,最后处理进位并转换为字符串结果,解决了两个大数相乘的问题。
259 9
|
JavaScript
力扣3333.找到初始输入字符串Ⅱ
【10月更文挑战第9天】力扣3333.找到初始输入字符串Ⅱ
291 1
|
算法 C++
Leetcode第八题(字符串转换整数(atoi))
这篇文章介绍了LeetCode上第8题“字符串转换整数(atoi)”的解题思路和C++的实现方法,包括处理前导空格、正负号、连续数字字符以及整数溢出的情况。
497 0
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
593 6
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
298 6
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
636 2
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
576 4
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口