算法训练-模拟
模拟leetcode415. 字符串相加法一模拟双指针leetcode796. 旋转字符串法一模拟法二搜索子字符串leetcode946. 验证栈序列法一模拟leetcode6. Z 字形变换法一巧设flagleetcode54. 螺旋矩阵法一按层模拟leetcode59. 螺旋矩阵 II法一按层模拟leetcode48. 旋转图像法一辅助数组法二原地旋转leetcode8. 字符串转换整数 (atoi)法一模拟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 flagtrue; for (int j 0; j goal.length(); j) { if(s.charAt(j)!goal.charAt((ij)%goal.length())){ flagfalse; break; } } if(flag){ return true; } } return false; } }法二搜索子字符串public class Method02 { // 方法检查字符串 s 是否可以通过旋转得到字符串 goal public boolean rotateString(String s, String goal) { // 判断 s 和 goal 是否长度相等以及 goal 是否是 ss 的子串 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) { StackInteger 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/法一巧设flagpublic class Method01 { public String convert(String s, int numRows) { // 处理边界条件当输入字符串为 null 或者行数小于 2 时直接返回原字符串 if (s null || numRows 2) return s; // 创建一个 ArrayList存储每一行的字符串内容 ListStringBuilder rows new ArrayListStringBuilder(); // 初始化每一行以 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 ListInteger spiralOrder(int[][] matrix) { // 创建一个列表来存储结果 ListInteger 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. 螺旋矩阵 II59. 螺旋矩阵 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; } }