模拟
leetcode415. 字符串相加
415. 字符串相加https://leetcode.cn/problems/add-strings/
法一:模拟+双指针
public class Method01 {
// 方法:将两个字符串表示的非负整数相加
public String addStrings(String num1, String num2) {
StringBuilder sb = new StringBuilder(); // 创建一个 StringBuilder 用于存储结果
int i = num1.length() - 1, j = num2.length() - 1; // 初始化指针 i 和 j 分别指向两个字符串的末尾
int jinwei = 0; // 初始化进位
int sum = 0; // 初始化和
// 当 i 或 j 还在范围内时循环
while (i >= 0 || j >= 0) {
// 计算当前位的和,包括进位和当前位的数字
sum = jinwei + (i >= 0 ? num1.charAt(i) - '0' : 0) + (j >= 0 ? num2.charAt(j) - '0' : 0);
jinwei = sum / 10; // 更新进位
sb.append(sum % 10); // 将当前位结果添加到 StringBuilder 中
i--; // 指向 num1 的前一位
j--; // 指向 num2 的前一位
}
// 如果最后还有进位,则在前面加上 '1',否则直接返回结果
return jinwei == 0 ? sb.reverse().toString() : ("1" + sb.reverse().toString());
}
}
leetcode796. 旋转字符串
796. 旋转字符串https://leetcode.cn/problems/rotate-string/
法一:模拟
public class Method01 {
public boolean rotateString(String s, String goal) {
if(s.length()!=goal.length()){
return false;
}
for (int i = 0; i < s.length(); i++) {
boolean flag=true;
for (int j = 0; j < goal.length(); j++) {
if(s.charAt(j)!=goal.charAt((i+j)%goal.length())){
flag=false;
break;
}
}
if(flag){
return true;
}
}
return false;
}
}
法二:搜索子字符串
public class Method02 {
// 方法:检查字符串 s 是否可以通过旋转得到字符串 goal
public boolean rotateString(String s, String goal) {
// 判断 s 和 goal 是否长度相等,以及 goal 是否是 s+s 的子串
return s.length() == goal.length() && (s + s).contains(goal);
}
}
leetcode946. 验证栈序列
946. 验证栈序列https://leetcode.cn/problems/validate-stack-sequences/
法一:模拟
public class Method01 {
// 方法:验证推入和弹出序列是否可以表示栈的合法操作
public boolean validateStackSequences(int[] pushed, int[] popped) {
Stack<Integer> stack = new Stack<>(); // 创建一个栈
int i = 0; // 初始化弹出序列的索引
// 遍历每一个推入的元素
for (int push : pushed) {
stack.push(push); // 将当前元素推入栈
// 当栈不为空,并且栈顶元素等于当前要弹出的元素时
while (!stack.isEmpty() && stack.peek() == popped[i]) {
stack.pop(); // 弹出栈顶元素
i++; // 移动到下一个要弹出的元素
}
}
// 返回栈是否为空,即所有元素是否都已按照顺序弹出
return stack.isEmpty();
}
}
leetcode6. Z 字形变换
6. Z 字形变换https://leetcode.cn/problems/zigzag-conversion/
法一:巧设flag
public class Method01 {
public String convert(String s, int numRows) {
// 处理边界条件:当输入字符串为 null 或者行数小于 2 时,直接返回原字符串
if (s == null || numRows < 2) return s;
// 创建一个 ArrayList,存储每一行的字符串内容
List<StringBuilder> rows = new ArrayList<StringBuilder>();
// 初始化每一行,以 StringBuilder 的形式存储
for (int i = 0; i < numRows; i++) {
rows.add(new StringBuilder());
}
// 初始化行索引 i 和方向标志 flag
int i = 0, flag = -1; // flag 用于控制行的移动方向
// 遍历输入字符串的每一个字符
for (char c : s.toCharArray()) {
// 将字符追加到当前行
rows.get(i).append(c);
// 当到达顶行或底行时,反转方向
if (i == 0 || i == numRows - 1) {
flag = -flag; // 反转方向
}
// 根据当前方向更新行索引 i
i += flag; // flag 为 -1 时,i 减 1;为 1 时,i 加 1
}
// 创建一个新的 StringBuilder,用于构建最终结果
StringBuilder res = new StringBuilder();
// 将每一行的 StringBuilder 内容添加到最终结果中
for (StringBuilder row : rows) {
res.append(row); // 拼接每一行的内容
}
// 返回最终结果的字符串形式
return res.toString();
}
}
leetcode54. 螺旋矩阵
54. 螺旋矩阵https://leetcode.cn/problems/spiral-matrix/
法一:按层模拟
public class Method01 {
public List<Integer> spiralOrder(int[][] matrix) {
// 创建一个列表来存储结果
List<Integer> res = new ArrayList<>();
// 定义四个边界,left、right、top、bottom分别表示左、右、上、下边界
int left = 0, right = matrix[0].length - 1, top = 0, bottom = matrix.length - 1;
// 不断螺旋遍历,直到所有元素都被访问
while (true) {
// 从左到右遍历当前的上边界
for (int i = left; i <= right; i++) {
res.add(matrix[top][i]);
}
// 更新上边界
if (++top > bottom) {
break; // 如果上边界超过下边界,结束循环
}
// 从上到下遍历当前的右边界
for (int i = top; i <= bottom; i++) {
res.add(matrix[i][right]);
}
// 更新右边界
if (--right < left) {
break; // 如果右边界小于左边界,结束循环
}
// 从右到左遍历当前的下边界
for (int i = right; i >= left; i--) {
res.add(matrix[bottom][i]);
}
// 更新下边界
if (--bottom < top) {
break; // 如果下边界小于上边界,结束循环
}
// 从下到上遍历当前的左边界
for (int i = bottom; i >= top; i--) {
res.add(matrix[i][left]);
}
// 更新左边界
if (++left > right) {
break; // 如果左边界超过右边界,结束循环
}
}
// 返回结果列表
return res;
}
}
leetcode59. 螺旋矩阵 II
59. 螺旋矩阵 IIhttps://leetcode.cn/problems/spiral-matrix-ii/
法一:按层模拟
public class Method01 {
public int[][] generateMatrix(int n) {
// 创建一个 n x n 的二维数组,用于存储结果
int[][] res = new int[n][n];
// 定义四个边界,left、right、top、bottom分别表示左、右、上、下边界
int left = 0, right = n - 1, top = 0, bottom = n - 1;
// 定义一个变量用于填充矩阵的数字,从 1 开始
int num = 1;
// 不断螺旋填充矩阵,直到所有位置都被填充
while (true) {
// 从左到右遍历当前的上边界并填充数字
for (int i = left; i <= right; i++) {
res[top][i] = num++;
}
// 更新上边界
if (++top > bottom) {
break; // 如果上边界超过下边界,结束循环
}
// 从上到下遍历当前的右边界并填充数字
for (int i = top; i <= bottom; i++) {
res[i][right] = num++;
}
// 更新右边界
if (--right < left) {
break; // 如果右边界小于左边界,结束循环
}
// 从右到左遍历当前的下边界并填充数字
for (int i = right; i >= left; i--) {
res[bottom][i] = num++;
}
// 更新下边界
if (--bottom < top) {
break; // 如果下边界小于上边界,结束循环
}
// 从下到上遍历当前的左边界并填充数字
for (int i = bottom; i >= top; i--) {
res[i][left] = num++;
}
// 更新左边界
if (++left > right) {
break; // 如果左边界超过右边界,结束循环
}
}
// 返回填充完成的矩阵
return res;
}
}
leetcode48. 旋转图像
48. 旋转图像https://leetcode.cn/problems/rotate-image/
法一:辅助数组
public class Method01 {
public void rotate(int[][] matrix) {
// 获取矩阵的大小 n
int n = matrix.length;
// 创建一个临时矩阵,用于存储旋转后的结果
int[][] temp = new int[n][n];
// 将原矩阵的元素按顺时针方向旋转 90 度填充到临时矩阵中
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
// 对于位置 (i, j),旋转后的位置是 (j, n-1-i)
temp[j][n - 1 - i] = matrix[i][j];
}
}
// 将临时矩阵的内容复制回原矩阵
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
matrix[i][j] = temp[i][j];
}
}
}
}
法二:原地旋转
public class Method02 {
public void rotate(int[][] matrix) {
// 获取矩阵的大小 n
int n = matrix.length;
// 对矩阵的层进行旋转,遍历前半部分的行数
for (int i = 0; i < n / 2; i++) {
// 遍历当前层的元素(为了完美旋转,每层需要处理的元素是当前行的一半)
for (int j = 0; j < (n + 1) / 2; j++) {
// 保存当前元素
int temp = matrix[i][j];
// 进行四个位置之间的元素交换
// 当前位置 (i, j) 变为 (n - 1 - j, i)
matrix[i][j] = matrix[n - 1 - j][i];
// (n - 1 - j, i) 变为 (n - 1 - i, n - 1 - j)
matrix[n - 1 - j][i] = matrix[n - 1 - i][n - 1 - j];
// (n - 1 - i, n - 1 - j) 变为 (j, n - 1 - i)
matrix[n - 1 - i][n - 1 - j] = matrix[j][n - 1 - i];
// (j, n - 1 - i) 变为原来的 (i, j)
matrix[j][n - 1 - i] = temp;
}
}
}
}
leetcode8. 字符串转换整数 (atoi)
8. 字符串转换整数 (atoi)https://leetcode.cn/problems/string-to-integer-atoi/
法一:模拟
public class Method01 {
public int myAtoi(String s) {
// 将输入字符串去除首尾空格,并转换为字符数组
char[] chars = s.trim().toCharArray();
// 如果字符数组为空,返回 0
if (chars.length == 0) {
return 0;
}
// 初始化符号(默认为正数)和结果变量
int sign = 1;
int result = 0;
int i = 0;
// 检查符号,并更新 sign 和 i
if (chars[i] == '+') {
i++; // 正号,继续处理
} else if (chars[i] == '-') {
sign = -1; // 负号,更新符号为 -1
i++; // 移动到下一个字符
}
// 遍历字符数组,构建数字
for (; i < chars.length; i++) {
// 如果当前字符不是数字,则停止解析
if (chars[i] < '0' || chars[i] > '9') {
break;
}
// 检查是否会出现整数溢出
if (result > Integer.MAX_VALUE / 10 ||
(result == Integer.MAX_VALUE / 10 && chars[i] > '7')) {
// 根据符号返回对应的最大或最小值
if (sign == 1) {
return Integer.MAX_VALUE; // 超出最大值,返回最大值
} else {
return Integer.MIN_VALUE; // 超出最小值,返回最小值
}
}
// 更新结果:将当前数字加入到结果中
result = result * 10 + (chars[i] - '0');
}
// 返回结果乘以符号
return sign * result;
}
}