N字形变换
来源:力扣(LeetCode) 链接:leetcode.cn/problems/zi…
将一个给定字符串 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
代码
class Solution {
public String convert(String s, int numRows) {
if (numRows == 1 || numRows >= s.length()) {
return s;
}
StringBuilder[] rows = new StringBuilder[numRows];
for (int i = 0; i < numRows; i++) {
rows[i] = new StringBuilder();
}
int currRow = 0;
boolean goingDown = false;
for (char c : s.toCharArray()) {
rows[currRow].append(c);
if (currRow == 0 || currRow == numRows - 1) {
goingDown = !goingDown;
}
currRow += goingDown ? 1 : -1;
}
StringBuilder result = new StringBuilder();
for (StringBuilder row : rows) {
result.append(row);
}
return result.toString();
}
}
思路分析
- 首先处理特殊情况,如果行数为1或大于等于字符串长度,则直接返回原字符串。
- 创建一个StringBuilder数组
rows,数组的长度为行数,每个元素都是一个StringBuilder对象,用于存储每行的字符。 - 定义当前行号
currRow和一个标志变量goingDown,用于表示当前字符是向下移动还是向上移动。 - 遍历字符串的每个字符,将字符添加到对应的行中的StringBuilder对象中。
- 根据当前行号和行数进行判断,如果当前行号为第一行或最后一行,则改变
goingDown的值。 - 根据
goingDown的值更新当前行号,向下移动时行号加1,向上移动时行号减1。 - 遍历完成后,将每行的StringBuilder对象按顺序合并为一个新的StringBuilder对象
result。 - 将
result转换为字符串并返回。
字符串转换整数(atoi)
来源:力扣(LeetCode) 链接:leetcode.cn/problems/st…
请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。
函数 myAtoi(string s) 的算法如下:
- 读入字符串并丢弃无用的前导空格
- 检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
- 读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
- 将前面步骤读入的这些数字转换为整数(即,"123" -> 123, "0032" -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。
- 如果整数数超过 32 位有符号整数范围 [−231, 231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −231 ,大于 231 − 1 的整数应该被固定为 231 − 1 。
- 返回整数作为最终结果。
注意:
- 本题中的空白字符只包括空格字符 ' ' 。
- 除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符。
示例 1:
输入:s = "42"
输出:42
解释:加粗的字符串为已经读入的字符,插入符号是当前读取的字符。
第 1 步:"42"(当前没有读入字符,因为没有前导空格)
^
第 2 步:"42"(当前没有读入字符,因为这里不存在 '-' 或者 '+')
^
第 3 步:"42"(读入 "42")
^
解析得到整数 42 。
由于 "42" 在范围 [-231, 231 - 1] 内,最终结果为 42 。
示例 2:
输入:s = " -42"
输出:-42
解释:
第 1 步:" -42"(读入前导空格,但忽视掉)
^
第 2 步:" -42"(读入 '-' 字符,所以结果应该是负数)
^
第 3 步:" -42"(读入 "42")
^
解析得到整数 -42 。
由于 "-42" 在范围 [-231, 231 - 1] 内,最终结果为 -42 。
示例 3:
输入:s = "4193 with words"
输出:4193
解释:
第 1 步:"4193 with words"(当前没有读入字符,因为没有前导空格)
^
第 2 步:"4193 with words"(当前没有读入字符,因为这里不存在 '-' 或者 '+')
^
第 3 步:"4193 with words"(读入 "4193";由于下一个字符不是一个数字,所以读入停止)
^
解析得到整数 4193 。
由于 "4193" 在范围 [-231, 231 - 1] 内,最终结果为 4193 。
提示:
- 0 <= s.length <= 200
- s 由英文字母(大写和小写)、数字(0-9)、' '、'+'、'-' 和 '.' 组成
代码
class Solution {
public int myAtoi(String s) {
int index = 0;
int sign = 1;
int result = 0;
// 移除前导空格
while (index < s.length() && s.charAt(index) == ' ') {
index++;
}
// 处理正负号
if (index < s.length() && (s.charAt(index) == '+' || s.charAt(index) == '-')) {
sign = s.charAt(index) == '+' ? 1 : -1;
index++;
}
// 将数字字符转换为整数
while (index < s.length()) {
char c = s.charAt(index);
if (c < '0' || c > '9') {
break;
}
// 处理溢出情况
if (result > Integer.MAX_VALUE / 10 || (result == Integer.MAX_VALUE / 10 && (c - '0') > Integer.MAX_VALUE % 10)) {
return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
result = result * 10 + (c - '0');
index++;
}
return sign * result;
}
}
思路分析
- 定义一个指针
index,用于遍历字符串s的每个字符。 - 移除字符串开头的空格,即将指针
index向后移动到第一个非空格字符的位置。 - 处理正负号,如果指针
index指向正号或负号,则根据正负号确定变量sign的值,并将指针index向后移动。 - 遍历剩余的字符,将数字字符转换为整数。如果遇到非数字字符,则跳出循环。
- 在转换过程中,判断整数是否溢出。如果溢出,根据正负号返回最大或最小整数值。
- 将转换后的整数乘以正负号并返回。