【小Y学算法】⚡️每日LeetCode打卡⚡️——6. Z 字形变换

简介: 📢前言🌲原题样例🌻C#方法:按行排序法🌻Java 方法:按行排序💬总结

📢前言

🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻

🌲 每天打卡一道算法题,既是一个学习过程,又是一个分享的过程😜

🌲 提示:本专栏解题 编程语言一律使用 C# 和 Java 两种进行解题

🌲 要保持一个每天都在学习的状态,让我们一起努力成为算法大神吧🧐!

🌲 今天是力扣算法题持续打卡第6天🎈!

🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻

🌲原题样例

将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。


比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:

P   A   H   N
A P L S I I G
Y   I   R

之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“PAHNAPLSIIGYIR”。请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);

示例 1:

输入:s = "PAYPALISHIRING", numRows = 3
输出:"PAHNAPLSIIGYIR"

示例 2:

输入:s = "PAYPALISHIRING", numRows = 4
输出:"PINALSIGYAHRPI"
解释:
P     I    N
A   L S  I G
Y A   H R
P     I

示例 3:

输入:s = "A", numRows = 1
输出:"A"

提示:


1 <= s.length <= 1000

s 由英文字母(小写和大写)、’,’ 和 ‘.’ 组成

1 <= numRows <= 1000

🌻C#方法:按行排序法

解题思路

找规律:

numRows>=3 时

第一行 和 最后一行 的 每个下标 差为 diff = 4 +(numRows -3)2;

每行行头下标为第r行

除第一行 和 最后一行外, 每一组 应为两个数

除第一行 和 最后一行外, 每个组的第一个数 是与第一行对齐的,下标差也是diff

而每组中第二个数与第一个数的下标差为 j = diff - 2r ,因为行数每增加一行, 每一个垂直列下方会增加一个数, 每一个斜向上会增加一个数

public class Solution {
    public string Convert(string s, int numRows) {
        if (string.IsNullOrEmpty(s))
                return "";
            if (s.Length == 1)
                return s[0].ToString();
            if (numRows == 1)
                return s;
            int index = 0;
            char[] result = new char[s.Length];
            if (numRows == 2)
            {
                int halfLen = s.Length % 2 ==0? s.Length / 2  :s.Length /2 +1;
                for (int i = 0, j = 1; i < s.Length;)
                {
                    if (i < s.Length){
                        result[index] = s[i];                        
                    }
                    if (j < s.Length&&index+halfLen<s.Length){
                        result[index+halfLen] = s[j];
                    }
                    index++;
                    i += 2;
                    j += 2;
                }
                return new string(result);
            }
            int diff = 4 + (numRows - 3) * 2;
            int r = 0; 
            while (r < numRows)
            {
                if (r == 0 || r == numRows - 1)
                {
                    for (int k = r; k < s.Length; k += diff)
                    {
                        result[index++] = s[k];
                    }
                }
                else
                {
                    int j = diff - 2 * r;
                    for (int k = r; k < s.Length; k += diff)
                    {
                        result[index++] = s[k];
                        if (k + j < s.Length)
                            result[index++] = s[k + j];
                    }
                }
                r++;
            }
            return new string(result);
    }
}
链接:https://leetcode-cn.com/problems/zigzag-conversion/solution/zxing-bian-huan-cjie-fa-80ms-shi-jian-10-ebr2/

执行结果

执行结果 通过,执行用时92ms,内存消耗 26.6MB


🌻Java 方法:按行排序

思路

通过从左向右迭代字符串,我们可以轻松地确定字符位于 Z 字形图案中的哪一行。


算法

我们可以使用 \text{min}( \text{numRows}, \text{len}(s))min(numRows,len(s)) 个列表来表示 Z 字形图案中的非空行。

从左到右迭代 ss,将每个字符添加到合适的行。可以使用当前行和当前方向这两个变量对合适的行进行跟踪。

只有当我们向上移动到最上面的行或向下移动到最下面的行时,当前方向才会发生改变。

class Solution {
    public String convert(String s, int numRows) {
        if (numRows == 1) return s;
        List<StringBuilder> rows = new ArrayList<>();
        for (int i = 0; i < Math.min(numRows, s.length()); i++)
            rows.add(new StringBuilder());
        int curRow = 0;
        boolean goingDown = false;
        for (char c : s.toCharArray()) {
            rows.get(curRow).append(c);
            if (curRow == 0 || curRow == numRows - 1) goingDown = !goingDown;
            curRow += goingDown ? 1 : -1;
        }
        StringBuilder ret = new StringBuilder();
        for (StringBuilder row : rows) ret.append(row);
        return ret.toString();
    }
}
链接:https://leetcode-cn.com/problems/zigzag-conversion/solution/z-zi-xing-bian-huan-by-leetcode/

执行结果

执行结果 通过,执行用时6ms,内存消耗 38.8MB


复杂度分析


时间复杂度:O(n)

空间复杂度:O(n)


💬总结

今天是力扣算法题打卡的第六天!今天的题有点难,借助力扣大神题解看了半天!

文章采用 C# 和 Java 两种编程语言进行解题

一些方法也是参考力扣大神写的,也是边学习边分享,再次感谢算法大佬们

那今天的算法题分享到此结束啦,明天再见!


相关文章
|
1月前
|
存储 人工智能 算法
从零掌握贪心算法Java版:LeetCode 10题实战解析(上)
在算法世界里,有一种思想如同生活中的"见好就收"——每次做出当前看来最优的选择,寄希望于通过局部最优达成全局最优。这种思想就是贪心算法,它以其简洁高效的特点,成为解决最优问题的利器。今天我们就来系统学习贪心算法的核心思想,并通过10道LeetCode经典题目实战演练,带你掌握这种"步步为营"的解题思维。
|
3月前
|
算法 芯片 Python
使用变动和观察(Perturb and Observe)最大功率点跟踪(MPPT)算法控制升压变换器的MOSFET/IGBT(开关),以从光伏阵列中提取最大功率(Simulink仿真实现)
使用变动和观察(Perturb and Observe)最大功率点跟踪(MPPT)算法控制升压变换器的MOSFET/IGBT(开关),以从光伏阵列中提取最大功率(Simulink仿真实现)
211 1
|
算法
Leetcode 初级算法 --- 数组篇
Leetcode 初级算法 --- 数组篇
139 0
|
8月前
|
算法 数据安全/隐私保护 计算机视觉
基于sift变换的农田杂草匹配定位算法matlab仿真
本项目基于SIFT算法实现农田杂草精准识别与定位,运行环境为Matlab2022a。完整程序无水印,提供详细中文注释及操作视频。核心步骤包括尺度空间极值检测、关键点定位、方向分配和特征描述符生成。该算法通过特征匹配实现杂草定位,适用于现代农业中的自动化防控。
|
9月前
|
编解码 算法 数据安全/隐私保护
一维信号的小波变换与重构算法matlab仿真
本程序使用MATLAB2022A实现一维信号的小波变换与重构,对正弦测试信号进行小波分解和重构,并计算重构信号与原信号的误差。核心步骤包括:绘制分解系数图像、上抽取与滤波重构、对比原始与重构信号及误差分析。小波变换通过多分辨率分析捕捉信号的局部特征,适用于非平稳信号处理,在信号去噪、压缩等领域有广泛应用。
|
存储 算法 Java
leetcode算法题-有效的括号(简单)
【11月更文挑战第5天】本文介绍了 LeetCode 上“有效的括号”这道题的解法。题目要求判断一个只包含括号字符的字符串是否有效。有效字符串需满足左括号必须用相同类型的右括号闭合,并且左括号必须以正确的顺序闭合。解题思路是使用栈数据结构,遍历字符串时将左括号压入栈中,遇到右括号时检查栈顶元素是否匹配。最后根据栈是否为空来判断字符串中的括号是否有效。示例代码包括 Python 和 Java 版本。
282 4
|
算法
每日一道算法题(Leetcode 20)
每日一道算法题(Leetcode 20)
165 2
|
算法
测试工程师的技能升级:LeetCode算法挑战与职业成长
这篇文章通过作者亲身体验LeetCode算法题的过程,探讨了测试工程师学习算法的重要性,并强调了算法技能对于测试职业成长的必要性。
238 1
测试工程师的技能升级:LeetCode算法挑战与职业成长
|
存储 算法 Java
LeetCode经典算法题:打家劫舍java详解
LeetCode经典算法题:打家劫舍java详解
194 2
|
人工智能 算法 Java
LeetCode经典算法题:井字游戏+优势洗牌+Dota2参议院java解法
LeetCode经典算法题:井字游戏+优势洗牌+Dota2参议院java解法
186 1